[Catalyst-dev] Developing action_uri() for Catalyst 5.80

Ash Berlin ash_cpan at firemirror.com
Thu May 29 10:04:15 GMT 2008


On 28 May 2008, at 20:50, Jason Gottshall wrote:

> After reviewing the list archives (both users and dev), it appears  
> that
> there is some interest in developing an action_uri() method that would
> Do The Right Thing given a private path and any necessary captures.  
> I've
> been given a tuit at $work to do some dev on this, so that I can  
> pass it
> along to my programmers as a "best practice", especially in template
> construction. This being my first attempt at a contrib to this  
> project,
> I'm gonna need a little help to get going, though.
>
> Background: I raised this question on the cat users list about a year
> and half ago, in the context of getting URIs for Chained actions:
>
> http://www.gossamer-threads.com/lists/catalyst/users/12260
>
> At that point, mst affirmed that it was a point of interest and  
> invited
> me onto the dev list (sorry it took me so long!) And interestingly, it
> looks like Ash had put out an RFC for the same thing a few months
> earlier on the dev list, but that thread seems to have been warnocked
> (or talked out on IRC?):

I forget what happened to the thread. I think Matt's response was die  
if something invalid is passed.

The reason i did an RFC is cos i have had an uri_for_action sitting in  
MyApp.pm for about 2 years now :)

Here is my code. It probably only works well for chained actions :) Oh  
and there aren't really any tests for it other than my app still works.

sub uri_for_action {
     my $c = shift;
     my $priv_path = shift;

     my $orig_path = $priv_path;

     my $action;
     # Action object
     if (blessed($priv_path) && $priv_path->isa('Catalyst::Action') ) {
       $action = $priv_path;
     }
     # Relative action paths
     elsif ($priv_path =~ s!^\./!!) {
       $action = $c->controller->action_for($priv_path);
     } else {
       $priv_path = $c->namespace . "/$priv_path" unless $priv_path =~  
m[^/];
       $action = $c->dispatcher->get_action_by_path($priv_path);
     }

     croak "Invalid action path $orig_path" unless $action;

     if ($action && (my ($chain) = @{$action->attributes->{Chained} ||  
[] }) ) {
         my @actions = ($action);

         my @captures;

         while ($chain ne '/') {
             my $action = $c->dispatcher->get_action_by_path($chain);
             die "Unable to find action in chain: $chain" unless  
$action;

             unshift @actions, $action;
             ($chain) = @{$action->attributes->{Chained}};
         }


         my @captures_in = splice @_;
         @captures_in = @{$captures_in[0]} if (ref  
$captures_in[0]||'') eq 'ARRAY';

         foreach my $action (@actions) {
             last unless exists $action->attributes->{CaptureArgs};
             my $cap_args = $action->attributes->{CaptureArgs}[0];
             carp("Not enough captures passed to uri_for_action")
               unless $cap_args <= scalar @captures_in;

             push @captures, splice(@captures_in, 0, $cap_args);
         }

         @_ =  \@captures;
         push @_, @captures_in if scalar @captures_in;

     }
     $c->uri_for($action, @_);
}

__END__

-ash





More information about the Catalyst-dev mailing list