Catalyst-ControllerRole-At
view release on metacpan or search on metacpan
README.mkdn view on Meta::CPAN
**NOTE** For the purposes of executing code, we treat 'At' and 'At()' as the same. However
We highly recommend At() as a best practice since it more clearly represents the idea
of 'no match template'.
## Chaining Actions across Controllers
The method attributes 'Via()' contains a pointer to the action being continued. In
standard practice this is almost always the name of an action in the same controller
as the one declaring it. This could be said to be a 'relative' (as in relative to
the current controller) action. However you don't have to use a relative name. You
can use any action's absolute private name, as long as it is an action that declares itself
to be a link in a chain.
However in practice it is not alway a good idea to spread your chained acions across
across controllers in a manner that is not easy to follow. We recommend you try
to limit youself to chains that follow the controller hierarchy, which should be
easier for your code maintainers.
For this common, best practice case when you are continuing your chained actions across
controllers, following a controller hierarchy, we provide some template expansions you can
use in the 'Via' attribute. These are useful to enforce this best practice as well as
promote reusability by decoupling hard coded private action namespaces from your controller.
$up: The controller whose namespace contains the current controller
$subname The name of the current actions subroutine
$parent: Expands to $up/$subname
For example:
package MyApp::Controller::ThingsTodo;
use Moose;
use MooseX::MethodAttributes;
extends 'Catalyst::Controller';
with 'Catalyst::ControllerRole::At';
sub init :At($controller/...) {
my ($self, $c) = @_;
}
sub list :Via(init) At($subname) {
my ($self, $c) = @_;
}
__PACKAGE__->meta->make_immutable;
package MyApp::Controller::ThingsTodo::Item;
use Moose;
use MooseX::MethodAttributes;
extends 'Catalyst::Controller';
with 'Catalyst::ControllerRole::At';
sub init :Via($parent) At({id:Int}/...) {
my ($self, $c) = @_;
}
sub show :Via(init) At($subname) { ... }
sub update :Via(init) At($subname) { ... }
sub delete :Via(init) At($subname) { ... }
__PACKAGE__->meta->make_immutable;
This creates four (4) URL templates:
https://localhost/thingstodo/list
https://localhost/thingstodo/:id/show
https://localhost/thingstodo/:id/update
https://localhost/thingstodo/:id/delete
With an action execution flow as follows:
https://localhost/thingstodo/list =>
/thingstodo/init
/thingstodo/list
https://localhost/thingstodo/:id/show
/thingstodo/init
/thingstodo/item/init
/thingstodo/item/show
https://localhost/thingstodo/:id/update
/thingstodo/init
/thingstodo/item/init
/thingstodo/item/update
https://localhost/thingstodo/:id/delete
/thingstodo/init
/thingstodo/item/init
/thingstodo/item/delete
# COOKBOOK
One thing I like to do is create a base controller for my project
so that I can make my controllers more concise:
package Myapp::Controller;
use Moose;
extends 'Catalyst::Controller';
with 'Catalyst::ControllerRole::At';
__PACKAGE__->meta->make_immutable;
You can of course doa lot more here if you want but I usually recommend
the lightest touch possible in your base controllers since the more you customize
the harder it might be for people new to the code to debug the system.
# TODO
- HTTP Methods
- Incoming Content type matching
- ??Content Negotiation??
# AUTHOR
John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)
# SEE ALSO
( run in 1.466 second using v1.01-cache-2.11-cpan-39bf76dae61 )