So, you want to write a generic base controller for some set of actions? Great! Want to use Chained actions for nicer looking URLs? Fantastic!
Let's presume you're writing a generic account admin controller. Your URL-space might look like:
/admin/account/
/admin/account/1/
/admin/account/1/update
Currently, you have a couple of options in order to make this a reality:
1) Action-specific configs
Catalyst's configurability is extremely granular -- you can set specific attributes as configuration parameters for any given action.
package MyApp::Controller::Admin::Account; use strict; use warnings; use base 'Catalyst::Controller'; __PACKAGE__->config( actions => { instance => { PathPart => 'admin/account' }, list => { PathPart => 'admin/account' } } ); sub list : Chained('/') Args(0) { die "index of accounts" } sub instance : Chained('/') CaptureArgs(1) { } # do something with $c->req->captures->[ 0 ] sub view : Chained('instance') PathPart('') Args(0) { die "view account" } sub update : Chained('instance') PathPart Args(0) { die "update account" } 1;
In the above example we're explicitly setting the PathPart
for the list and instance actions -- However, it's not quite fully generic.
2) Create our own attribute
We'll create an attribute that will expose a controller's path_prefix
to any action -- aptly named PathPrefix
.
package MyApp::Controller::Admin::Account; use strict; use warnings; use base 'Catalyst::Controller'; sub _parse_PathPrefix_attr { my ( $self, $c, $name, $value ) = @_; return PathPart => $self->path_prefix; } sub list : Chained('/') PathPrefix Args(0) { die "index of accounts" } sub instance : Chained('/') PathPrefix CaptureArgs(1) { } # do something with $c->req->captures->[ 0 ] sub view : Chained('instance') PathPart('') Args(0) { die "view account" } sub update : Chained('instance') PathPart Args(0) { die "update account" } 1;
Now that's better -- except for that pesky sub. Well, you're in luck -- PathPrefix
is now in the current Catalyst::Runtime branch. Our code is now even simpler:
package MyApp::Controller::Admin::Account; use strict; use warnings; use base 'Catalyst::Controller'; sub list : Chained('/') PathPrefix Args(0) { die "index of accounts" } sub instance : Chained('/') PathPrefix CaptureArgs(1) { } # do something with $c->req->captures->[ 0 ] sub view : Chained('instance') PathPart('') Args(0) { die "view account" } sub update : Chained('instance') PathPart Args(0) { die "update account" } 1;
As I've stated, Catalyst is extremely configurable. Let's say you don't like "admin/account
" as the path? No Problem!
package MyApp::Controller::Admin::Account; use strict; use warnings; use base 'Catalyst::Controller'; __PACKAGE__->config( path => 'foo/bar' ); sub list : Chained('/') PathPrefix Args(0) { die "index of accounts" } sub instance : Chained('/') PathPrefix CaptureArgs(1) { } # do something with $c->req->captures->[ 0 ] sub view : Chained('instance') PathPart('') Args(0) { die "view account" } sub update : Chained('instance') PathPart Args(0) { die "update account" } 1;
All of the actions will now start with "/foo/bar/
"!
Happy Hacking.
Special thanks to mst
for being my editor and sanity checker.