[Catalyst] Dispatching based on path and host/domain

Matt S Trout dbix-class at trout.me.uk
Wed Apr 23 14:33:44 BST 2008


On Wed, Apr 23, 2008 at 12:22:36PM +0100, Curtis Fletcher wrote:
> > Write an Action Class.
> > 
> > You can put whatever you want in the match() method. In your case,
> > 
> > return 0 if grep { $c->req->host =~ /$_/ } 
> > @{$self->attributes->{Domain}||[]}
> 
> I gave this a go (in principle it looks ideal), but the documentation on
> Catalyst::Action is pretty sparse and only talks about replacing the
> "execute" method. I'm assuming that if ActionClass->match() returns
> false the dispatcher assumes the method doesn't match, I gave that a
> quick test:
> 
> package Catalyst::Action::Domain;
> use strict;
> use warnings;
> use base 'Catalyst::Action';
> sub match
> {
> 	my $self = shift;
> 	my ($c) = @_;
> 	return 0;
> };
> 
> package MyAPP::Controller::Admin::Website1::Abstract
> sub index :Local
> {
> }
> 
> sub edit :Local :ActionClass('Domain')
> {
> }
> 
> http://mydomain.com/admin/website1/abstract/edit bounced me right back
> to the default controller, I was kind of expecting it to behave like
> NEXT in that it would fail to match
> http://mydomain.com/admin/website1/abstract/edit but would then match
> http://mydomain.com/admin/website1/abstract setting the first arg to
> 'edit'. Ah this may be specific to "index" as a "not-really" action it
> doesn't accept parameters the way I thought it did 
> 
> E.G.
> http://mydomain.com/admin/website1/abstract/iamnotamethod
> 
> Does not dispatch to MyAPP::Controller::Admin::Website1::Abstract->index
> with ARGS being ('iamnotamethod') I think I answered my own question,
> but there's no harm in having the result in the archives no? (especially
> if I'm wrong)
> (Also, Did someone say that "index" was a hack? And that we should use
> "base" instead?)

index is basically a degenerate form of ":Path :Args(0)"

If you'd wanted abstract/edit to match, you want ":Path :Args(1)" or no
:Args restriction.
 
> Dumping out the Action Object I can see:
> 'attributes' =>
> {
> 	'ActionClass' =>
> 	[
> 		'Catalyst::Action::Domain'
> 	],
> 	'Path' =>
> 	[
> 		'admin/website1/abstract/edit'
> 	]
> }
> 
> But I can't seem to find anywhere that this structure is set up, given
> the code in your Action example how would you go about setting the
> 'Domain' key in the attributes class from the Controller the Action is
> used in, apologies if this is a question with an obvious answer.

:Local is a shortcut for :Path($controller->path_prefix.'/'.$method_name)

Those values came straight off the attributes - you'd set the Domain key
just by using :Domain('foobar.com') exactly as you did in your original
example (which is where I got the key name from :)

> Finally isn't $c->req->host the hostname of the connecting client? I
> ended up mangling $c->req->base at the moment though I'm not sure that's
> the best way to go.

I meant $c->req->uri->host, sorry.

> Really finally, has anyone thought of putting together a flowchart of
> the Classes/methods involved in a Catalyst request response if it's been
> done I'd love to look at it and if not if might be a good exercise for
> me.

http://dev.catalyst.perl.org/wiki/FlowChart

shows the action dispatching order. Another one that maps out the
relationships of the classes would rock; feel free to barrage me with
questions (you get a free pass for stupid questions if you're writing docs
or equivalent material :)

-- 
      Matt S Trout       Need help with your Catalyst or DBIx::Class project?
   Technical Director                    http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/            http://www.shadowcat.co.uk/servers/



More information about the Catalyst mailing list