From: Dave Rolsky Date: Sun, 23 Jan 2011 21:05:12 +0000 (-0600) Subject: Add docs and fix various bugs X-Git-Tag: 0.01~16 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=07583481bf6503d0edbb3f3cfa1b8513fb6731fd;hp=88adcbe098f41dafef6972d4f2b56338a1e1223b;p=catagits%2FCatalystX-Routes.git Add docs and fix various bugs Only default Chained parent for end points Use full path when generating sub names for end points Don't default Args to 0 --- diff --git a/lib/CatalystX/Routes.pm b/lib/CatalystX/Routes.pm index 1673f65..bd9a131 100644 --- a/lib/CatalystX/Routes.pm +++ b/lib/CatalystX/Routes.pm @@ -13,7 +13,7 @@ use Moose::Exporter; Moose::Exporter->setup_import_methods( with_meta => [qw( get get_html post put del chain_point )], - as_is => [qw( chained args capture_args path_part action )], + as_is => [qw( chained args capture_args path_part action_class_name )], class_metaroles => { class => ['CatalystX::Routes::Role::Class'], }, @@ -42,7 +42,16 @@ sub del { sub _add_route { my $rest = shift; my $meta = shift; - my ( $name, $attrs, $sub ) = _process_args( $meta, @_ ); + my ( $attrs, $sub ) = _process_args( $meta, @_ ); + + unless ( exists $attrs->{Chained} ) { + $attrs->{Chained} = q{/}; + } + + # We need to turn the full chain name into a path, since two end points + # from two different chains could have the same end point name. + ( my $name = ( $attrs->{Chained} eq '/' ? q{} : $attrs->{Chained} ) . q{/} + . $_[0] ) =~ s/(\W)/'X' . sprintf( '%x', ord($1) )/eg; my $meth_base = '__route__' . $name; @@ -63,7 +72,9 @@ sub chain_point { sub _add_chain_point { my $meta = shift; - my ( $name, $attrs, $sub ) = _process_args( $meta, @_ ); + my ( $attrs, $sub ) = _process_args( $meta, @_ ); + + ( my $name = $_[0] ) =~ s/(\W)/'X' . sprintf('%x', ord(1) )/eg; $meta->add_chain_point( $name => [ $attrs, $sub ] ); } @@ -101,17 +112,7 @@ sub _process_args { $p{PathPart} = [$part]; } - unless ( $p{CaptureArgs} || $p{Args} ) { - $p{Args} = [0]; - } - - unless ( exists $p{Chained} ) { - $p{Chained} = q{/}; - } - - ( my $name = $path ) =~ s/(\W)/'X' . sprintf( '%x', ord($1) )/eg; - - return $name, \%p, $sub; + return \%p, $sub; } sub _maybe_add_rest_route { @@ -154,7 +155,7 @@ sub path_part ($) { return ( PathPart => [ $_[0] ] ); } -sub action ($) { +sub action_class_name ($) { return ( ActionClass => [ $_[0] ] ); } @@ -180,3 +181,157 @@ sub _STRINGLIKE0 ($) { } 1; + +# ABSTRACT: Sugar for declaring RESTful chained action in Catalyst + +__END__ + +=head1 SYNOPSIS + + package MyApp::Controller::User; + + use Moose; + use CatalystX::Routes; + + BEGIN { extends 'Catalyst::Controller'; } + + # /user/:user_id + + chain_point '_set_user' + => chained '/' + => path_part 'user' + => capture_args 1 + => sub { + my $self = shift; + my $c = shift; + my $user_id = shift; + + $c->stash()->{user} = ...; + }; + + # GET /user/:user_Id + get '' + => chained('_set_user') + => args 0 + => sub { ... }; + + # GET /user/foo + get 'foo' => sub { ... } + + sub _post { ... } + + # POST /user/foo + post 'foo' => \&_post; + + # PUT /root + put '/root' => sub { ... }; + + # /user/plain_old_catalyst + sub plain_old_catalyst : Local { ... } + +=head1 DESCRIPTION + +This module provides a sugar layer that allows controllers to declare chained +RESTful actions. + +Under the hood, all the sugar declarations are turned into Chained subs. All +chain end points are declared using one of C, C, C, +C, or C. These will declare actions using the +L action class from the +L distribution. + +=head1 PUTTING IT ALL TOGETHER + +This module is merely sugar over Catalyst's built-in L and L. It +helps to know how those two things work. + +=head1 SUGAR FUNCTIONS + +All of these functions will be exported into your controller class when you +use C. + +=head2 get ... + +This declares a C handler. + +=head2 get_html + +This declares a C handler for browsers. Use this to generate a standard +HTML page for browsers while still being able to generate some sort of RESTful +data response for other clients. + +If a browser makes a C request and no C action has been +declared, a C action is used as a fallback. See +C for details on how +"browser-ness" is determined. + +=head2 post ... + +This declares a C handler. + +=head2 put + +This declares a C handler. + +=head2 del + +This declares a C handler. + +=head2 chain_point + +This declares an intermediate chain point that should not be exposed as a +public URI. + +=head2 chained $path + +This function takes a single argument, the previous chain point from which the +action is chained. + +=head2 args $number + +This declares the number of arguments that this action expects. This should +only be used for the end of a chain. + +=head2 capture_args $number + +The number of arguments to capture at this point in the chain. This should +only be used for the beginning or middle parts of a chain. + +=head2 path_part $path + +The path part for this part of the chain. If you are declaring a chain end +point with C, etc., then this isn't necessary. By default, the name +passed to the initial sugar function will be converted to a path part. See +below for details. + +=head2 action_class_name $class + +Use this to declare an action class. By default, this will be +L for end points. For other parts of a +chain, it simply won't be set. + +=head1 Path Generation + +All of the end point function (C, C, etc.) take a path as the first +argument. By default, this will be used as the C for the chain. You +can override this by explicitly calling C, in which case the name +is essentially ignored (but still required). + +Note that it is legitimate to pass the empty string as the name for a chain's +end point. + +If you don't specify a C value for an end point, then it will use the +root URI, C, as the root of the chain. + +By default, no arguments are specified for a chain's end point, meaning it +will accept any number of arguments. + +=head1 BUGS + +Please report any bugs or feature requests to +C, or through the web interface at +L. I will be notified, and then you'll automatically be +notified of progress on your bug as I make changes. + +=cut