[Catalyst] URL mapping relative to Controller name space.

Bill Moseley moseley at hank.org
Sat Jul 30 06:07:48 CEST 2005


I'm trying to write controllers that don't need to know where they are
located.

I want a single controller to handle a number of tables (say, it's a
general CRUD handler for a collection of tables) with paths like:

    http://localhost:3000/admin/crud/<table>/list
    http://localhost:3000/admin/crud/<table>/edit/<id>
    http://localhost:3000/admin/crud/<table>/do_edit/<id>

I'd like the code in the controller to be relocatable -- that is, if I
move it to a new location in (in URL space) the code doesn't need to
be updated.  I like using "Local" actions in general, but seems that's
not a good choice in this case due to the <table> variable before the
action.


What I'm currently doing is something like:

    package MyApp::C::Admin::Crud;

    sub default : Private {
        my ( $self, $c, $admin, $crud, $table, $action, $id ) = @_;
        [...]
    }

where $admin and $lookup are there to eat up those path segments.  The
(minor) problem is that if I some day moved this controller to:

    package MyApp::C::Admin::Foo::Bar::Crud;

then I'd need to adjust the parameters passed to default().

What I'd like is a way to get the path segments relative to the
controller.  So my default() sub would look like


    sub default : Private {
        my ( $self, $c, $table, $action, $id ) = @_;
        [...]
        $c->forward( $action ) if $self->can($action);
    }

regardless of where it's located in URL space. $table, $action, $id
are the path segments after the name of the package.

Related, how do I generate self-referential hrefs in my templates?
>From my examples above, in the first case I'd want:

    $c->stash->{root} = '/admin/crud';

and when the controller is relocated it would instead be:

    $c->stash->{root} = '/admin/foo/bar/crud';

That is, every URL handled by the controller is relative to its
package name.


In some ways I wish I could do this at the top of my controller:

    package __right_here__;

and have the package set based on where it is in the path. ;)

Thanks,


-- 
Bill Moseley
moseley at hank.org




More information about the Catalyst mailing list