NAME

Squatting - A Camping-inspired Web Microframework for Perl

SYNOPSIS

Running an App:

$ squatting App
Please contact me at: http://localhost:4234/

Check out our ASCII art logo:

$ squatting --logo

What a basic App looks like:

# STEP 1 => Subclass Squatting
{
  package App;
  use base 'Squatting';
  #use App::Controllers;
  #use App::Views;
}

# STEP 2 => Create a Controllers package
{
  package App::Controllers;
  use Squatting ':controllers';

  # Setup a list of controller objects using the C() function.
  our @C = (
    C(
      Home => [ '/' ],
      get  => sub {
        my ($self) = @_;
        my $v = $self->v;
        $v->{title} = 'Hello, World!';
        $self->render('home');
      },
      post => sub { }
    ),
  );
}

# STEP 3 => Create a Views package
{
  package App::Views;
  use Squatting ':views';

  # Setup a list of view objects using the V() function.
  our @V = (
    V(
      'html',
      layout  => sub {
        my ($self, $v, $content) = @_;
        "<html><body>$content</body></html>"
      },
      home    => sub {
        my ($self, $v) = @_;
        "<h1>$v->{title}</h1>"
      },
    ),
  );
}

# Models?  The whole world is your model.  ;-)
# - I've always been ambivalent about defining policy here.
# - Use whatever works for you.

DESCRIPTION

Squatting is a web microframework based on Camping that uses Continuity as its foundation.

What does this mean?

Concise API

_why did a really good job designing Camping's API, so I copied quite a bit of the feel of Camping for Squatting.

Tiny Codebase

Right now, it's around 6.6K of actual code (after minifying), but it can definitely get smaller. Also, the number of Perl module dependencies has been kept down to a minimum.

RESTful Controllers By Default

Controllers are objects (not classes) that are made to look like HTTP resources. Thus, they respond to methods like get(), post(), put(), and delete().

RESTless Controllers Are Possible (thanks to Continuity)

Stateful continuation-based code can be surprisingly useful (especially for COMET), so we try to make RESTless controllers easy to express as well.

Views Are ...Different

The View API feels like Camping, but Squatting allows multiple views to coexist (kinda like Catalyst (but not quite)).

Minimal Policy

You may use any templating system you want, and you may use any ORM(*) you want. We only have a few rules on how the controller code and the view code should be organized, but beyond that, you are free.

* Regarding ORMs, the nature of Continuity makes it somewhat DBI-unfriendly, so this may be a deal-breaker for many of you. However, I look at this as an opportunity to try novel storage systems like CouchDB, instead. With the high level of concurrency that Squatting can support (thanks to Continuity) we are probably better off this way.

API

Use as a Base Class for Squatting Applications

package App;
use base 'Squatting';
1;

App->service($controller, @args)

Every time an HTTP request comes in, this method is called with a controller object and a list of arguments. The controller will then be invoked with the HTTP method that was requested (like GET or POST), and it will return the content of the response as a string.

NOTE: If you want to do anything before, after, or around an HTTP request, this is the method you should override in your subclass.

App->init

This method takes no parameters and initializes some internal variables.

App->go(%options)

This method calls init and then starts a Continuity-based web server. The %options are passed straight through to Continuity.

Use as a Helper for Controllers

package App::Controllers;
use Squatting ':controllers';

C($name => \@urls, %methods)

This is a shortcut for:

Squatting::Controller->new(@_);

R($name, @args, [ \%params ])

R() is a URL generation function that takes a controller name and a list of arguments. You may also pass in a hashref representing CGI variables as the very last parameter to this function.

Example: Given the following controllers, R() would respond like this.

# Example Controllers
C(Home    => [ '/' ]);
C(Profile => [ '/~(\w+)', '/~(\w+)\.(\w+)' ]);

# Generated URLs
R('Home')                             # "/"
R('Home', { foo => 1, bar => 2})      # "/?foo=1&bar=2"
R('Profile', 'larry')                 # "/~larry"
R('Profile', 'larry', 'json')         # "/~larry.json"

Use as a Helper for Views

package App::Controllers;
use Squatting ':views';

V($name, %methods)

This is a shortcut for:

Squatting::View->new(@_);

R($name, @args, [ \%params ])

This is the same R() function that the controllers get access to.

SEE ALSO

Squatting::Controller, Squatting::View, Squatting::Mapper, Squatting::Q

Squatting Source Code

The source code is short and it has some useful comments in it, so this might be all you need to get going. There are also some examples in the eg/ directory.

http://github.com/beppu/squatting/tree/master

Bavl Source Code

We're going to throw Squatting into the metaphorical deep end by using it to implement the towr.of.bavl.org. If you're looking for an example of how to use Squatting for an ambitious project, look at the Bavl code.

http://github.com/beppu/bavl/tree/master

Continuity and Coro

When you want to start dabbling with RESTless controllers, it would serve you well to understand how Continuity and Coro work. I recommend reading the POD for the following Perl modules:

Continuity, Coro, Coro::Event, Event.

Also, check out the Continuity web site.

http://continuity.tlt42.org/

Camping

Squatting is the spiritual descendant of Camping, so studying the Camping API will indirectly teach you much of the Squatting API.

http://code.whytheluckystiff.net/camping/

Prototype-based OO

There were a lot of obscure Ruby idioms in Camping that were damn near impossible to directly translate into Perl. I got around this by resorting to techniques that are reminiscent of prototype-based OO. (That's why controllers and views are objects instead of classes.)

Prototypes == Grand Unified Theory of Objects

I've been coding a lot of JavaScript these days, and it has definitely influenced my programming style. I've come to love the simplicity of prototype-based OO, and I think it's a damned shame that they're introducing concepts like 'class' in the next version of JavaScript. It's like they missed the point of prototype-based OO.

If you're going to add anything to JavaScript, make the prototype side of it stronger. Look to languages like Io, and make it easier to clone objects and manipulate an object's prototype chain. The beauty of prototypes is that this one concept can be used to unify objects, classes, and namespaces. Look at Io if you don't believe me.

http://iolanguage.com/

AUTHOR

John BEPPU <beppu@cpan.org>

COPYRIGHT

Copyright (c) 2008 John BEPPU <beppu@cpan.org>.

The "MIT" License

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.