use strict;
use warnings;
-use CatalystX::Routes::Role::Class;
-use CatalystX::Routes::Role::Controller;
use Moose::Util qw( apply_all_roles );
use Params::Util qw( _CODELIKE _REGEX _STRING );
use Scalar::Util qw( blessed );
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_class_name )],
- class_metaroles => {
- class => ['CatalystX::Routes::Role::Class'],
- },
+ with_meta => [qw( get get_html post put del chain_point )],
+ as_is => [qw( chained args capture_args path_part action_class_name )],
);
sub get {
$attrs->{Chained} = q{/};
}
+ my $name = $_[0];
+ $name =~ s{^/}{};
+
# 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];
+ $name = ( $attrs->{Chained} eq '/' ? q{} : $attrs->{Chained} ) . q{/}
+ . $name;
+
+ $name =~ s{/}{|}g;
my $meth_base = '__route__' . $name;
my ( $attrs, $sub ) = _process_args( $meta, @_ );
my $name = $_[0];
+ $name =~ s{/}{|}g;
- $meta->add_chain_point( $name => [ $attrs, $sub ] );
+ $meta->add_method( $name => $sub );
+
+ $meta->name()->config()->{actions}{$name} = $attrs;
}
sub _process_args {
unless ( $part =~ s{^/}{} ) {
$part = join q{/},
$meta->name()->action_namespace('FakeConfig'), $part;
+ $part =~ s{^/}{};
}
}
return if $meta->has_method($name);
- # This could be done by Moose::Exporter, but that would require that the
- # module has already inherited from Cat::Controller when it calls "use
- # CatalystX::Routes".
- unless ( $meta->does_role('CatalystX::Routes::Role::Controller') ) {
- apply_all_roles(
- $meta->name(),
- 'CatalystX::Routes::Role::Controller'
- );
- }
-
$meta->add_method( $name => sub { } );
- $meta->add_route( $name => [ $attrs, $meta->get_method($name) ] );
+ $meta->name()->config()->{actions}{$name} = $attrs;
return;
}
1;
-# ABSTRACT: Sugar for declaring RESTful chained action in Catalyst
+# ABSTRACT: Sugar for declaring RESTful chained actions in Catalyst
__END__
$c->stash()->{user} = ...;
};
- # GET /user/:user_Id
+ # GET /user/:user_id
get ''
=> chained('_set_user')
=> args 0
=> sub { ... };
# GET /user/foo
- get 'foo' => sub { ... }
+ get 'foo' => sub { ... };
sub _post { ... }
=head1 DESCRIPTION
+B<WARNING>: This module is still experimental. It works well, but the APIs may
+change without warning.
+
This module provides a sugar layer that allows controllers to declare chained
RESTful actions.
L<Catalyst::Action::REST::ForBrowsers> for end points. For other parts of a
chain, it simply won't be set.
-=head1 Path Generation
+=head1 PATH GENERATION
All of the end point function (C<get>, C<post>, etc.) take a path as the first
argument. By default, this will be used as the C<path_part> for the chain. You
Note that it is legitimate to pass the empty string as the name for a chain's
end point.
+If the end point's name does not start with a slash, it will be prefixed with
+the controller's namespace.
+
If you don't specify a C<chained> 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 CAVEATS
+
+When adding subroutines for end points to your controller, a name is generated
+for each subroutine based on the chained path to the subroutine. Some
+template-based views will automatically pick a template based on the
+subroutine's name if you don't specify one explicitly. This won't work very
+well with the bizarro names that this module generates, so you are strongly
+encouraged to specify a template name explicitly.
+
=head1 BUGS
Please report any bugs or feature requests to