X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FDispatchType%2FChained.pm;h=b9d6d07a07a102d32b4e9c2a3585ab13948cdc47;hp=831f6e89b025ce672142f0bda1a91d33aaa8ce98;hb=130b45ec858db6863e3d6959f7a6e3b6908cd48e;hpb=77b90892c20eafb4f80910aab7b63f0cd5b43511 diff --git a/lib/Catalyst/DispatchType/Chained.pm b/lib/Catalyst/DispatchType/Chained.pm index 831f6e8..b9d6d07 100644 --- a/lib/Catalyst/DispatchType/Chained.pm +++ b/lib/Catalyst/DispatchType/Chained.pm @@ -98,7 +98,7 @@ sub list { @{ $self->_endpoints } ) { my $args = $endpoint->list_extra_info->{Args}; - my @parts = (defined($args) ? (("*") x $args) : '...'); + my @parts = (defined($endpoint->attributes->{Args}[0]) ? (("*") x $args) : '...'); my @parents = (); my $parent = "DUMMY"; my $extra = $self->_list_extra_http_methods($endpoint); @@ -130,7 +130,12 @@ sub list { $name = "${extra} ${name}"; } if (defined(my $cap = $p->list_extra_info->{CaptureArgs})) { - $name .= ' ('.$cap.')'; + if($p->has_captures_constraints) { + my $tc = join ',', @{$p->captures_constraints}; + $name .= " ($tc)"; + } else { + $name .= " ($cap)"; + } } if (defined(my $ct = $p->list_extra_info->{Consumes})) { $name .= ' :'.$ct; @@ -144,6 +149,13 @@ sub list { } push(@rows, [ '', $name ]); } + + if($endpoint->has_args_constraints) { + my $tc = join ',', @{$endpoint->args_constraints}; + $endpoint .= " ($tc)"; + } else { + $endpoint .= defined($endpoint->attributes->{Args}[0]) ? " ($args)" : " (...)"; + } push(@rows, [ '', (@rows ? "=> " : '').($extra ? "$extra " : ''). ($scheme ? "$scheme: ":'')."/${endpoint}". ($consumes ? " :$consumes":"" ) ]); my @display_parts = map { $_ =~s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; decode_utf8 $_ } @parts; $rows[0][0] = join('/', '', @display_parts) || '/'; @@ -236,7 +248,7 @@ sub recurse_match { my @try_actions = @{$children->{$try_part}}; TRY_ACTION: foreach my $action (@try_actions) { if (my $capture_attr = $action->attributes->{CaptureArgs}) { - my $capture_count = $capture_attr->[0] || 0; + my $capture_count = $action->number_of_captures|| 0; # Short-circuit if not enough remaining parts next TRY_ACTION unless @parts >= $capture_count; @@ -248,7 +260,7 @@ sub recurse_match { push(@captures, splice(@parts, 0, $capture_count)); # check if the action may fit, depending on a given test by the app - if ($action->can('match_captures')) { next TRY_ACTION unless $action->match_captures($c, \@captures) } + next TRY_ACTION unless $action->match_captures($c, \@captures); # try the remaining parts against children of this action my ($actions, $captures, $action_parts, $n_pathparts) = $self->recurse_match( @@ -325,32 +337,6 @@ Calls register_path for every Path attribute for the given $action. =cut -sub _check_args_attr { - my ( $self, $action, $name ) = @_; - - return unless exists $action->attributes->{$name}; - - if (@{$action->attributes->{$name}} > 1) { - Catalyst::Exception->throw( - "Multiple $name attributes not supported registering " . $action->reverse() - ); - } - my $args = $action->attributes->{$name}->[0]; - if (defined($args) and not ( - Scalar::Util::looks_like_number($args) and - int($args) == $args and $args >= 0 - )) { - require Data::Dumper; - local $Data::Dumper::Terse = 1; - local $Data::Dumper::Indent = 0; - $args = Data::Dumper::Dumper($args); - Catalyst::Exception->throw( - "Invalid $name($args) for action " . $action->reverse() . - " (use '$name' or '$name()')" - ); - } -} - sub register { my ( $self, $c, $action ) = @_; @@ -398,10 +384,6 @@ sub register { $self->_actions->{'/'.$action->reverse} = $action; - foreach my $name (qw(Args CaptureArgs)) { - $self->_check_args_attr($action, $name); - } - if (exists $action->attributes->{Args} and exists $action->attributes->{CaptureArgs}) { Catalyst::Exception->throw( "Combining Args and CaptureArgs attributes not supported registering " . @@ -433,11 +415,15 @@ sub uri_for_action { my @captures = @$captures; my $parent = "DUMMY"; my $curr = $action; + # If this is an action chain get the last action in the chain + if($curr->can('chain') ) { + $curr = ${$curr->chain}[-1]; + } while ($curr) { - if (my $cap = $curr->attributes->{CaptureArgs}) { - return undef unless @captures >= ($cap->[0]||0); # not enough captures - if ($cap->[0]) { - unshift(@parts, splice(@captures, -$cap->[0])); + if (my $cap = $curr->number_of_captures) { + return undef unless @captures >= $cap; # not enough captures + if ($cap) { + unshift(@parts, splice(@captures, -$cap)); } } if (my $pp = $curr->attributes->{PathPart}) { @@ -721,6 +707,28 @@ An action that is part of a chain (that is, one that has a C<:Chained> attribute) but has no C<:CaptureArgs> attribute is treated by Catalyst as a chain end. +Allowed values for CaptureArgs is a single integer (CaptureArgs(2), meaning two +allowed) or you can declare a L, L or L +named constraint such as CaptureArgs(Int,Str) would require two args with +the first being a Integer and the second a string. You may declare your own +custom type constraints and import them into the controller namespace: + + package MyApp::Controller::Root; + + use Moose; + use MooseX::MethodAttributes; + use MyApp::Types qw/Int/; + + extends 'Catalyst::Controller'; + + sub chain_base :Chained(/) CaptureArgs(1) { } + + sub any_priority_chain :Chained(chain_base) PathPart('') Args(1) { } + + sub int_priority_chain :Chained(chain_base) PathPart('') Args(Int) { } + +See L for more. + =item Args By default, endpoints receive the rest of the arguments in the path. You