[Catalyst] stripping path parts and then redispatch?
Larry Leszczynski
larryl at emailplus.org
Tue Feb 24 01:44:31 GMT 2009
Just wanted to pass along some solutions...
To recap briefly:
URLs are prefixed with the page language, e.g "/en/foo/bar". The
language needs to be stripped off and stashed, and the remainder of the
request processed as if the language part had not been there, e.g.
"/foo/bar".
I was trying to use $c->go("/foo/bar"), which works if there is a
Foo::bar() action, but which breaks if the action is supposed to be
Foo::default() with the argument "bar" (or Foo::Bar::default() with no
arguments).
1) Bill Moseley suggested a different approach which is seeming to work
pretty well so far (thanks Bill), it involves subclassing
MyApp->prepare_path() to tweak the path at beginning of processing,
something like this:
sub prepare_path
{
my $c = shift;
$c->SUPER::prepare_path(@_);
my @path_chunks = split m[/], $c->request->path, -1;
return unless ( @path_chunks
&& $valid_languages{$path_chunks[0]});
# Pull off first path chunk:
my $language = shift @path_chunks;
$c->stash->{language} = $language;
# Create a request path from the remaining chunks:
my $path = join('/', @path_chunks) || '/';
# Stuff modified request path back into request:
$c->request->path($path);
# Update request base to include whatever
# was stripped from the request path:
my $base = $c->request->base;
$base->path($base->path . $language . '/');
}
A nice side effect is that tweaking $c->request->base to include the
language means the language is automatically included when you call
$c->uri_for().
2) In the process of trying to get $c->go() to work for an arbitrary
path, I found a way that seems to make it work consistently even if the
path is supposed to hit a default action:
# Create your request path to wherever:
my $path = "/foo/bar/baz";
# Stuff modified request path back into request:
$c->request->path($path);
# Create a new $c->action using $c->request->path.
# Updates $c->action and $c->request->args.
$c->dispatcher->prepare_action($c);
$c->go($c->action, $c->request->args);
This should work for any of $c->forward(), $c->detach(), $c->visit(),
$c->go().
Thanks for all the suggestions,
Larry
More information about the Catalyst
mailing list