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
_______________________________________________
List: [email protected]
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/