[Catalyst] Programmatic way to determine the needed number of captures for an action?

John Napiorkowski jjn1056 at yahoo.com
Sat Nov 4 14:45:41 GMT 2006


--- Ash Berlin <ash at cpan.org> wrote:

> John Napiorkowski wrote:
> > Hi,
> > 
> > I have a question about $c->uri_for and chained
> > actions.
> > 
> > I've really enjoyed having this feature to
> > programmatically create urls for me in the code. 
  > It's
   > > one of the greatest things about Catalyst I
think.
> 
> > However one thing that is a bit tricky is that
> when
> > using $c->uri_for with chained actions you have to
> be
> > careful to supply the correct number of captures. 
> If
> > you give too few or too many then $c->uri_for will
> > return an undef.
> > 
> > So something I am trying to figure out is how to
> > determine in code (without knowing in advance) how
> > many captures a given chained action will expect
> so
> > that I can supply it correctly.
> > 
> > You can look at the Args and CaptureArgs attribute
> for
> > a single action, but if that action is an endpoint
> in
> > a chain, and actions earlier in the chain require
> > Args, I can't find a straightforward way to get
> the
> > total number of required Args for a given Chain
> > endpoint.
> > 
> > Here's an example of my issue:
> > 
> > Let's say I have a controller with two actions
> 'base'
> > and 'item'.  item is chained to base, with base as
> the
> > root and item requires an argument:
> > 
> > Controller One;
> > 
> > sub base Chained('/') CaptureArgs(0) {}
> > 
> > sub item (Chained('base') Args(1) {}
> > 
> > Now in my second controller I have:
> > 
> > Controller Two
> > 
> > sub base Chained('/') CaptureArgs(1) {}
> > 
> > sub item (Chained('base') Args(1) {}
> > 
> > For controller one I can get the URL with:
> > 
> >
> $c->uri_for($->controller(..)->action_for('base'));
> > 
> > But for the second controller I'd need:
> > 
> > $c->uri_for($->controller(..)->action_for('base'),
> > [$capture]);
> > 
> > What I am trying to do is to write some code that
> > looks at the number of arguments a given action
> needs
> > and automatically supplies that number off the
> current
> > captures list.
> > 
> > I can see that I could do this by adding some
> > additional metadata fields to my custom Action
> > Classes, but I was trying to see if there was a
> > canonically correct way to do this in Catalyst.
> > 
> > Anyone know?
> > 
> > Thanks!
> > 
> > John
> > 
> 
> This has been discussed before, tho a fully
> satisfactory solution never 
> appeared. Something that we touched upon that could
> work was to have a 
> stack of actions which been used/hit in the chain -
> though this wouldn't 
> help when going cross controller.
> 
> But yes, its something that has been niggling me as
> well.
> 
> Ash

I came up with this hack that worked for my client,
but it's dependent on the order of the captures unless
you are using some sort of named parameter system for
them:

my $uri = $c->uri_for(

   $c->controller->action_for('list'), 
   $c->request->query_parameters
);

my @captures = ();
	
foreach my $capture ( @{$c->request->captures} )
{
   last if $uri;
		
   push @captures, $capture;	

   $uri = $c->uri_for(

      $c->controller->action_for('list'), 
      [@captures], 
      $c->request->query_parameters
   );
}

As you can see it far from elegant.  Basically it
takes advantage of the fact that $c->uri_for will
always return false if it can't make a uri and just
walks through your current capture list.

I could probably rewrite this more cleanly, but it was
the best I could come up with on a friday late
afternoon :)

--john

> 
> _______________________________________________
> List: Catalyst at lists.rawmode.org
> Listinfo:
> http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive:
>
http://www.mail-archive.com/catalyst@lists.rawmode.org/
> Dev site: http://dev.catalyst.perl.org/
> 



 
__________________________________________________________________________________________
Check out the New Yahoo! Mail - Fire up a more powerful email and get things done faster. 
(http://advision.webevents.yahoo.com/mailbeta) 




More information about the Catalyst mailing list