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/

Reply via email to