Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of LTjake (4001)

Monday November 27, 2006
10:32 PM

Catalyst Tip: Generic Base Controllers

[ #31738 ]

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/
account list
/admin/account/1/
account view
/admin/account/1/update
account 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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.