=head1 NAME

Squatting::Cookbook - Web Development Techniques for Squatting

=head1 INTRODUCTION

Squatting exists because I fell in love with Camping's API, and I couldn't
bear the thought of building another site using some other API.  When I decided
that the next site I want to build would be implemented in Perl, I had no choice
but to port Camping to Perl, and that's how Squatting was born.

My hope is that other Perl programmers will be able to appreciate how concise
this API is, and I hope they'll see just how far a little bit of code can go.

=head2 Anatomy of a Squatting Application

=head3 Pick a Name for Your App

  package App;
  use base 'Squatting';

=head3 Make a Package for Your Controllers

If your app is called C<App>, then:

=over 4

=item Your controllers must be defined in a package called C<App::Controllers>.

=item You must say C<use Squatting ':controllers'>.

=item You must put your controllers in a package variable named C<@C>.

=back

  package App::Controllers;
  use Squatting ':controllers';
  our @C = (
    C(
      Home => [ '/' ],
      get  => sub {
        my ($self) = @_;
        $self->render('home');
      }
    ),
    C(
      Profile => [ '/~(\w+)' ],
      get => sub {
        my ($self, $name) = @_;
        my $v = $self->v;
        $v->{name} = $name;
        $self->render('profile');
      }
    )
  );

=head4 Anatomy of a Controller

=head3 Make a Package for Your Views

If your app is called C<App>, then:

=over 4

=item Your views must be defined in a package called C<App::Views>.

=item You must say C<use Squatting ':views'>.

=item You must put your views in a package variable named C<@V>.

=back

  package App::Views;
  use Squatting ':views';
  our @V = (
    V(
      'html',
      layout => sub {
      },
      home => sub {
      },
      profile => sub {
      },
    )
  );

=head4 Anatomy of a View


=head2 Special Powers of Continuity


=head1 PROGRAMMING TECHNIQUES

=head2 COMET

=head3 Event Architecture

The L<Continuity> backend is the only one that will currently allow you to use
COMET-based techniques.

=head3 RESTless Controllers


=head2 How to Set Up Sessions

=head3 Continuity and Process Memory

Pure Continuity apps typically don't use persistent session storage, because
they can use lexically scoped variables instead.  However, Squatting apps are
RESTful and stateless by default, so you can't count on the lexical scope of a
controller to stick around between requests.  Luckily, package variables *will*
stick around, so that's what we'll use to implement persistent sessions.

  our %state;
  sub service {
    my ($app, $c, @args) = @_;
    my $cr  = $c->cr;
    my $sid = $cr->{session_id};
    if (defined $sid) {
      $c->state = $state{$sid} ||= {};
    } 
    $app->SUPER::service($c, @args);
  }

Here, we override service() in the main module of our app so that $c->state will
provide a hashref whose values will persist between requests.


=head3 Without Continuity

The challenge is to find a way to assign unique session ids to each visitor, and
use that session id as a key into a persistent store.


=head2 How to Use Various Templating Systems With Squatting

=head3 HTML::AsSubs

=head3 Tenjin

=head3 Template::Toolkit

=head3 HTML::Mason

=head3 HTML::Template


=head2 How to Internationalize and Localize Squatting Apps


=head2 How to Compose Multiple Squatting Apps Into One App

  App->mount('AnotherApp', '/prefix');


=head2 How to Embed a Squatting App Into Other Frameworks

In order to embed a Squatting app into an app written in another
framework, we need to be able to do the following things.

=over 4

=item get incoming CGI parameters

=item get incoming HTTP request headers

=item get incoming HTTP method

=item set outgoing HTTP status

=item set outgoing HTTP response headers

=item set outgoing content

=back

If we can do all these things, Squatting can make itself at home.
Here are some concrete examples to get you started.

=head3 Catalyst

To embed a Squatting app into a Catalyst app, you can add code like
this to your C<Root> controller.

  use App 'On::Catalyst';
  App->init;
  App->relocate('/somewhere');
  sub somewhere : Local { App->catalyze($_[1]) }

If you want the Squatting app to be completely in charge, you don't
even have to relocate() -- just redefine the default() method like
this:

  use App 'On::Catalyst';
  App->init;
  sub default : Private { App->catalyze($_[1]) }

=head3 HTML::Mason

=head3 Raw mod_perl1

=head3 Raw mod_perl2

=head3 CGI


=head1 DEPLOYMENT TECHNIQUES

=head2 Let Squatting+Continuity Own Port 80

This is the simplest thing you could possibly do, but it's also somewhat
limiting.

=head2 Reverse Proxying to Squatting+Continuity w/ Perlbal

=head2 Reverse Proxying to Squatting+Continuity w/ ngingx

=head2 Piggy-Backing on Top of Other Frameworks

If you've embedded a Squatting app into another application, the rules and
conventions governing the other application's framework take precedence.
Follow their deployment guidelines, and you should be fine.


=head1 SCALING TECHNIQUES

This section is for those who wish to scale Squatting apps that are using a
Continuity foundation.  If any part of your site is RESTless and stateful, and
you've suddenly got a lot of traffic to your site, this section is for you.

=head2 Session Affinity with Multiple Instances

TODO

=head2 Linux and OpenSSI

TODO

=head2 DragonFlyBSD Single Image Cluster

This is currently science fiction.


=cut
