[Catalyst] how to get controller path

Matt S Trout dbix-class at trout.me.uk
Tue Nov 20 18:21:54 GMT 2007

On Tue, Nov 20, 2007 at 08:30:58AM -0600, Peter Karman wrote:
> On 11/20/2007 06:52 AM, Matt S Trout wrote:
> > On Tue, Nov 20, 2007 at 12:27:32PM +0530, Alok Sharma wrote:
> >> Hi,
> >> Need a bit of help.
> >> Given a path we have ways to get the uri using the method uri_for(path).
> >> Is there a  possible way to get the controller path given the uri so I am able 
> >> to do some thing like this
> >> 	$c->res->redirect(uri); $c->forward(controller_path(uri));
> > 
> > Why can't you start off with a controller action?
> > 
> > my $action = $c->controller('Foo')->action_for('bar'); # Controller::Foo->bar
> > 
> > $c->res->redirect($c->uri_for($action));
> > $c->forward($action->reverse);
> > 
> That assumes you know which Controller to start with.
> I've had this same issue recently. The problems IME are case and attributes.
> E.g., URIs are all lc() but the corresponding Controller/Action could be any case.
>  /foo/bar
> might correspond to:
>  MyApp::Controller::Foo::Bar->default()
> or
>  MyApp::Controller::FOO->bar()
> or
>  MyApp::Controller::foo->BAR()
> etc. You have no way of knowing from just a URI, and in my case, that was what
> I had to go on in my template.

I usually take that as "time to refactor the template".

obXThread: I try and avoid having URIs -anywhere- in my app code except in
the action attributes/config. It means I can rename stuff any time I need to
in terms of the external URI space and be certain of not needing to change
code or templates to handle it - effectively the path part names are just
another string dictionary to me.

> The Catalyst::Dispatcher seems to be the correct
> place to interrogate the action map for any given URL, maybe with
> get_action_by_path().

Nope, that's for forward() lookup.

Since actions can decide to match or not match the request based on pretty
much anything they like, the only way to determine what URI a particular
request would dispatch to with certainty is to mock up a request and context
and ask the dispatcher to set up $c->action the same way the prepare_action
phase of a real HTTP request dispatch would.

Any attempt to do otherwise runs really fast into me hiding under the desk
and yelling 'Halting Problem!' over and over until you go away.

Of course if you're willing to restrict what your code does and enforce that
via project policy or otherwise, the rules change - but there isn't really
a general solution here. Relying on action objects rather than URLs is the
best answer we have currently, which is why $c->uri_for($action, ...) got
implemented in the first place.

      Matt S Trout       Catalyst and DBIx::Class consulting and support -
   Technical Director      http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Christmas fun in collectable card game form -

More information about the Catalyst mailing list