[Catalyst] Mapping urls inside catalyst
Robert 'phaylon' Sedlacek
rs at 474.at
Sat May 19 21:18:11 GMT 2007
Mark Zealey wrote:
> Hi,
>
> I'm trying to work out the 'best way' of solving the following problem.
> Basically, I want to have several entries into my application. One is of the
> form /foo/<id> where id is an integer primary key. Another
> is /bar/<other_key> where other_key is some string key, and another is via a
> virtual host. I want them all to go into my MyApp::C::Foo:: namespace, but I
> have multiple classes under there eg MyApp::C::Foo::Fred. I thus want the
> following to be equivalent:
>
> mysite.com/foo/5/fred/list
> mysite.com/bar/myname/fred/list
> othersite.com/fred/list
Is fred an argument or is he a part of the application? :)
> I was thinking I colud do this using Chained actions; but I don't know much
> about them and the rest of the app is not using them - it's using :Local for
> the most part.
Assuming that fred is an argument, I would implement:
- a controller base class, that chains to a base action in the
subclass:
package MyApp::ControllerBase::Fred;
use strict;
use base 'Catalyst::Controller';
# this gets the fred, ties to the 'load' action in the subclass
sub load_fred: Chained('load') PathPart('') CaptureArgs(1) {
my ($self, $c, $fred) = @_;
$c->stash(fred => $fred);
}
sub list_fred: Chained('load_fred') PathPart('list') {
...
}
1;
- different controllers for every type of invocation. these are the
actions I would implement:
in MyApp::Controller::Foo (load gets the id):
sub base: Chained PathPart('foo') CaptureArgs(0) { ... }
sub load: Chained('base') PathPart('') CaptureArgs(1) { ... }
in MyApp::Controller::Bar (load gets the name):
sub base: Chained PathPart('bar') CaptureArgs(0) { ... }
sub load: Chained('base') PathPart('') CaptureArgs(1) { ... }
in MyApp::Controller::ViaHost (load uses host to find the item):
sub base: Chained PathPart('') CaptureArgs(0) { ... }
sub load: Chained('base') PathPart('') CaptureArgs(0) { ... }
In any case, you could omit the base actions and load directly. I just
like the convention of naming the chained base action in a controller
'base.' All need to have their base class set to the one above.
This is all untested of course. But you should get the chains
/foo/*/*/list - Foo::base, Foo::load, Fred::load_fred, Fred::list_fred
/bar/*/*/list - Bar::base, Bar::load, Fred::load_fred, Fred::list_fred
/*/*/list - ViaHost::base, ViaHost::load, Fred::load_fred,
Fred::list_fred
If 'fred' is an action, but not an argument, just change the 'load_fred'
action to a simple chained action that tales no args. Make it a base if
it's just a namespace element. Maybe you should also consider putting
the chain that goes via the domain under another namespace, if fred is
indeed an argument, to avoid collisions.
.phaylon
More information about the Catalyst
mailing list