File Coverage

blib/lib/Catalyst/Controller.pm
Criterion Covered Total %
statement 253 261 96.9
branch 90 100 90.0
condition 21 30 70.0
subroutine 53 62 85.4
pod 8 9 88.8
total 425 462 91.9


line stmt bran cond sub pod time code
1              
2             use Moose;
3 165     165   5830957 use Class::MOP;
  165         8465168  
  165         1143  
4 165     165   952249 use Class::Load ':all';
  165         448  
  165         4414  
5 165     165   894 use String::RewritePrefix;
  165         331  
  165         24785  
6 165     165   15019 use Moose::Util qw/find_meta/;
  165         29100  
  165         1619  
7 165     165   29011 use List::Util qw/first uniq/;
  165         390  
  165         1289  
8 165     165   33239 use namespace::clean -except => 'meta';
  165         393  
  165         11372  
9 165     165   10729  
  165         133059  
  165         2906  
10             BEGIN {
11             extends qw/Catalyst::Component/;
12 165     165   65073 with qw/MooseX::MethodAttributes::Role::AttrContainer::Inheritable/;
13 165         160853 }
14              
15             use MooseX::MethodAttributes;
16 165     165   7717511 use Catalyst::Exception;
  165         419  
  165         1010  
17 165     165   11080921 use Catalyst::Utils;
  165         446  
  165         4398  
18 165     165   966  
  165         380  
  165         73758  
19             with 'Catalyst::Component::ApplicationAttribute';
20              
21             has path_prefix => (
22             is => 'rw',
23             isa => 'Str',
24             init_arg => 'path',
25             predicate => 'has_path_prefix',
26             );
27              
28             has action_namespace => (
29             is => 'rw',
30             isa => 'Str',
31             init_arg => 'namespace',
32             predicate => 'has_action_namespace',
33             );
34              
35             has actions => (
36             accessor => '_controller_actions',
37             isa => 'HashRef',
38             init_arg => undef,
39             );
40              
41             has _action_role_args => (
42             traits => [qw(Array)],
43             isa => 'ArrayRef[Str]',
44             init_arg => 'action_roles',
45             default => sub { [] },
46             handles => {
47             _action_role_args => 'elements',
48             },
49             );
50              
51             has _action_roles => (
52             traits => [qw(Array)],
53             isa => 'ArrayRef[RoleName]',
54             init_arg => undef,
55             lazy => 1,
56             builder => '_build__action_roles',
57             handles => {
58             _action_roles => 'elements',
59             },
60             );
61              
62             has action_args => (is => 'ro');
63              
64             # ->config(actions => { '*' => ...
65             has _all_actions_attributes => (
66             is => 'ro',
67             isa => 'HashRef',
68             init_arg => undef,
69             lazy => 1,
70             builder => '_build__all_actions_attributes',
71             );
72              
73             my ($self, $args) = @_;
74             my $action = delete $args->{action} || {};
75 7075     7075 0 8804270 my $actions = delete $args->{actions} || {};
76 7075   100     29263 my $attr_value = $self->merge_config_hashes($actions, $action);
77 7075   100     20315 $self->_controller_actions($attr_value);
78 7075         19295  
79 7075         258342 # trigger lazy builder
80             $self->_all_actions_attributes;
81             $self->_action_roles;
82 7075         197100 }
83 7075         227594  
84             my $self = shift;
85             my @roles = $self->_expand_role_shortname($self->_action_role_args);
86             load_class($_) for @roles;
87 7075     7075   9579 return \@roles;
88 7075         236032 }
89 7075         329629  
90 7075         775409 my ($self) = @_;
91             delete $self->_controller_actions->{'*'} || {};
92             }
93              
94 7075     7075   11750 =head1 NAME
95 7075 100       187403  
96             Catalyst::Controller - Catalyst Controller base class
97              
98             =head1 SYNOPSIS
99              
100             package MyApp::Controller::Search
101             use base qw/Catalyst::Controller/;
102              
103             sub foo : Local {
104             my ($self,$c,@args) = @_;
105             ...
106             } # Dispatches to /search/foo
107              
108             =head1 DESCRIPTION
109              
110             Controllers are where the actions in the Catalyst framework
111             reside. Each action is represented by a function with an attribute to
112             identify what kind of action it is. See the L<Catalyst::Dispatcher>
113             for more info about how Catalyst dispatches to actions.
114              
115             =cut
116              
117             #I think both of these could be attributes. doesn't really seem like they need
118             #to be class data. i think that attributes +default would work just fine
119             __PACKAGE__->mk_classdata($_) for qw/_dispatch_steps _action_class _action_role_prefix/;
120              
121             __PACKAGE__->_dispatch_steps( [qw/_BEGIN _AUTO _ACTION/] );
122             __PACKAGE__->_action_class('Catalyst::Action');
123             __PACKAGE__->_action_role_prefix([ 'Catalyst::ActionRole::' ]);
124              
125              
126             my ( $self, $c ) = @_;
127              
128             foreach my $disp ( @{ $self->_dispatch_steps } ) {
129             last unless $c->forward($disp);
130             }
131 953     953   2265  
132             $c->forward('_END');
133 953         1496 }
  953         3787  
134 2853 100       7846  
135             my ( $self, $c ) = @_;
136             my $begin = ( $c->get_actions( 'begin', $c->namespace ) )[-1];
137 927         3442 return 1 unless $begin;
138 165     165   67418 $begin->dispatch( $c );
  165         154461  
  165         1061  
139             #If there is an error, all bets off
140             if( @{ $c->error }) {
141 953     953   2505 return !@{ $c->error };
142 953         19485 } else {
143 953 100       3988 return $c->state || 1;
144 300         1149 }
145             }
146 300 50       519  
  300         1171  
147 0         0 my ( $self, $c ) = @_;
  0         0  
148             my @auto = $c->get_actions( 'auto', $c->namespace );
149 300   100     6405 foreach my $auto (@auto) {
150             # We FORCE the auto action user to explicitly return
151 165     165   189118 # true. We need to do this since there's some auto
  165         471  
  165         706  
152             # users (Catalyst::Authentication::Credential::HTTP) that
153             # actually do a detach instead.
154 953     953   2552 $c->state(0);
155 953         19425 $auto->dispatch( $c );
156 953         2798 return 0 unless $c->state;
157             }
158             return $c->state || 1;
159             }
160              
161 40         793 my ( $self, $c ) = @_;
162 40         127 if ( ref $c->action
163 36 100       672 && $c->action->can('execute')
164             && defined $c->req->action )
165 947   100     19041 {
166 165     165   141706 $c->action->dispatch( $c );
  165         516  
  165         762  
167             }
168             #If there is an error, all bets off
169 947     947   2535 if( @{ $c->error }) {
170 947 50 33     18466 return !@{ $c->error };
      33        
171             } else {
172             return $c->state || 1;
173             }
174 947         18434 }
175              
176             my ( $self, $c ) = @_;
177 916 100       1975 my $end = ( $c->get_actions( 'end', $c->namespace ) )[-1];
  916         2821  
178 26         56 return 1 unless $end;
  26         72  
179             $end->dispatch( $c );
180 890   100     18316 return !@{ $c->error };
181             }
182 165     165   144965  
  165         515  
  165         806  
183             my ( $self, $name ) = @_;
184             my $app = ($self->isa('Catalyst') ? $self : $self->_application);
185 927     927   2638 return $app->dispatcher->get_action($name, $self->action_namespace);
186 927         18852 }
187 927 100       3771  
188 646         2248 #my opinion is that this whole sub really should be a builder method, not
189 645         1216 #something that happens on every call. Anyone else disagree?? -- groditi
  645         2047  
190 165     165   142352 ## -- apparently this is all just waiting for app/ctx split
  165         493  
  165         864  
191             around action_namespace => sub {
192             my $orig = shift;
193 65     65 1 1129 my ( $self, $c ) = @_;
194 65 100       2178  
195 65         228 my $class = ref($self) || $self;
196             my $appclass = ref($c) || $c;
197             if( ref($self) ){
198             return $self->$orig if $self->has_action_namespace;
199             } else {
200             return $class->config->{namespace} if exists $class->config->{namespace};
201             }
202              
203             my $case_s;
204             if( $c ){
205             $case_s = $appclass->config->{case_sensitive};
206             } else {
207             if ($self->isa('Catalyst')) {
208             $case_s = $class->config->{case_sensitive};
209             } else {
210             if (ref $self) {
211             $case_s = ref($self->_application)->config->{case_sensitive};
212             } else {
213             confess("Can't figure out case_sensitive setting");
214             }
215             }
216             }
217              
218             my $namespace = Catalyst::Utils::class2prefix($self->catalyst_component_name, $case_s) || '';
219             $self->$orig($namespace) if ref($self);
220             return $namespace;
221             };
222              
223             #Once again, this is probably better written as a builder method
224             around path_prefix => sub {
225             my $orig = shift;
226             my $self = shift;
227             if( ref($self) ){
228             return $self->$orig if $self->has_path_prefix;
229             } else {
230             return $self->config->{path} if exists $self->config->{path};
231             }
232             my $namespace = $self->action_namespace(@_);
233             $self->$orig($namespace) if ref($self);
234             return $namespace;
235             };
236              
237             my $self = shift;
238             my $meta = find_meta($self) || confess("No metaclass setup for $self");
239             confess(
240             sprintf "Metaclass %s for %s cannot support register_actions.",
241             ref $meta, $meta->name,
242             ) unless $meta->can('get_nearest_methods_with_attributes');
243             my @methods = $meta->get_nearest_methods_with_attributes;
244              
245             # actions specified via config are also action_methods
246             push(
247             @methods,
248 6515     6515 1 11808 map {
249 6515   33     16671 $meta->find_method_by_name($_)
250 6515 50       94209 || confess( sprintf 'Action "%s" is not available from controller %s',
251             $_, ref $self )
252             } keys %{ $self->_controller_actions }
253             ) if ( ref $self );
254 6515         17992 return uniq @methods;
255             }
256              
257              
258             my ( $self, $c ) = @_;
259             $self->register_action_methods( $c, $self->get_action_methods );
260 655 50       12950 }
261              
262             my ( $self, $c, @methods ) = @_;
263 6515 100       49905770 my $class = $self->catalyst_component_name;
  6367         176585  
264             #this is still not correct for some reason.
265 6515         51113 my $namespace = $self->action_namespace($c);
266              
267             # FIXME - fugly
268             if (!blessed($self) && $self eq $c && scalar(@methods)) {
269             my @really_bad_methods = grep { ! /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/ } map { $_->name } @methods;
270 6513     6513 1 14248 if (scalar(@really_bad_methods)) {
271 6513         31250 $c->log->warn("Action methods (" . join(', ', @really_bad_methods) . ") found defined in your application class, $self. This is deprecated, please move them into a Root controller.");
272             }
273             }
274              
275 6513     6513 1 357327 foreach my $method (@methods) {
276 6513         35800 my $name = $method->name;
277             # Horrible hack! All method metaclasses should have an attributes
278 6513         38894 # method, core Moose bug - see r13354.
279             my $attributes = $method->can('attributes') ? $method->attributes : [];
280             my $attrs = $self->_parse_attrs( $c, $name, @{ $attributes } );
281 6513 50 66     26754 if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
      100        
282 147         552 $c->log->warn( 'Bad action definition "'
  737         2603  
  737         2256  
283 147 100       744 . join( ' ', @{ $attributes } )
284 2         16 . qq/" for "$class->$name"/ )
285             if $c->debug;
286             next;
287             }
288 6513         14320 my $reverse = $namespace ? "${namespace}/${name}" : $name;
289 69164         227197 my $action = $self->create_action(
290             name => $name,
291             code => $method->body,
292 69164 100       1907642 reverse => $reverse,
293 69164         584574 namespace => $namespace,
  69164         215408  
294 69164 50 66     218918 class => $class,
295             attributes => $attrs,
296 0 0       0 );
  0         0  
297              
298             $c->dispatcher->register( $c, $action );
299 0         0 }
300             }
301 69164 100       174061  
302 69164         247389 my ($self, $class, @roles) = @_;
303              
304             load_class($_) for @roles;
305             my $meta = Moose::Meta::Class->initialize($class)->create_anon_class(
306             superclasses => [$class],
307             roles => \@roles,
308             cache => 1,
309             );
310             $meta->add_method(meta => sub { $meta });
311 69164         4653339  
312             return $meta->name;
313             }
314              
315             my $self = shift;
316 1818     1818   4143 my %args = @_;
317              
318 1818         5261 my $class = (exists $args{attributes}{ActionClass}
319 1818         510832 ? $args{attributes}{ActionClass}[0]
320             : $self->_action_class);
321              
322             load_class($class);
323             return $class;
324 1818     0   3510571 }
  0     0   0  
        0      
        0      
        0      
        0      
        0      
325              
326 1818         84572 my $self = shift;
327             my %args = @_;
328              
329             my $class = $self->action_class(%args);
330 69164     69164 1 86944  
331 69164         171439 load_class($class);
332             Moose->init_meta(for_class => $class)
333             unless Class::MOP::does_metaclass_exist($class);
334 69164 100       233710  
335             unless ($args{name} =~ /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/) {
336             my @roles = $self->gather_action_roles(%args);
337 69164         214531 push @roles, $self->gather_default_action_roles(%args);
338 69164         6443378  
339             $class = $self->_apply_action_class_roles($class, @roles) if @roles;
340             }
341              
342 69164     69164 1 93900 my $action_args = (
343 69164         264580 ref($self)
344             ? $self->action_args
345 69164         188905 : $self->config->{action_args}
346             );
347 69164         168118  
348 69164 100       1434171 my %extra_args = (
349             %{ $action_args->{'*'} || {} },
350             %{ $action_args->{ $args{name} } || {} },
351 69164 100       1486540 );
352 36599         117535  
353 36599         122768 return $class->new({ %extra_args, %args });
354             }
355 36599 100       79416  
356             my ($self, %args) = @_;
357             return (
358             (blessed $self ? $self->_action_roles : ()),
359             @{ $args{attributes}->{Does} || [] },
360             );
361             }
362 69164 100       1794050  
363             my ($self, %args) = @_;
364             my @roles = ();
365 69164 100       248849 push @roles, 'Catalyst::ActionRole::HTTPMethods'
366 69164 100       91654 if $args{attributes}->{Method};
  69164         235904  
367              
368             push @roles, 'Catalyst::ActionRole::ConsumesContent'
369 69164         1776632 if $args{attributes}->{Consumes};
370              
371             push @roles, 'Catalyst::ActionRole::Scheme'
372             if $args{attributes}->{Scheme};
373 36599     36599 1 114159  
374             push @roles, 'Catalyst::ActionRole::QueryMatching'
375             if $args{attributes}->{Query};
376 36599 100       1329461 return @roles;
  36599 100       177760  
377             }
378              
379             my ( $self, $c, $name, @attrs ) = @_;
380              
381 36599     36599 1 100863 my %raw_attributes;
382 36599         50776  
383             foreach my $attr (@attrs) {
384 36599 100       70936  
385             # Parse out :Foo(bar) into Foo => bar etc (and arrayify)
386              
387 36599 100       59296 if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+?)?\s*\))?$/ ) )
388             {
389              
390 36599 100       56900 if ( defined $value ) {
391             ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
392             }
393 36599 100       57523 push( @{ $raw_attributes{$key} }, $value );
394 36599         75313 }
395             }
396              
397             my ($actions_config, $all_actions_config);
398 69164     69164   187976 if( ref($self) ) {
399             $actions_config = $self->_controller_actions;
400 69164         89655 # No, you're not getting actions => { '*' => ... } with actions in MyApp.
401             $all_actions_config = $self->_all_actions_attributes;
402 69164         107447 } else {
403             my $cfg = $self->config;
404             $actions_config = $self->merge_config_hashes($cfg->{actions}, $cfg->{action});
405             $all_actions_config = {};
406 96081 50       534909 }
407              
408             %raw_attributes = (
409 96081 100       172591 %raw_attributes,
410 35945 100       115233 # Note we deep copy array refs here to stop crapping on config
411             # when attributes are parsed. RT#65463
412 96081         117060 exists $actions_config->{$name} ? map { ref($_) eq 'ARRAY' ? [ @$_ ] : $_ } %{ $actions_config->{$name } } : (),
  96081         281041  
413             );
414              
415             # Private actions with additional attributes will raise a warning and then
416 69164         97117 # be ignored. Adding '*' arguments to the default _DISPATCH / etc. methods,
417 69164 100       127470 # which are Private, will prevent those from being registered. They should
418 68427         1889773 # probably be turned into :Actions instead, or we might want to otherwise
419             # disambiguate between those built-in internal actions and user-level
420 68427         1623913 # Private ones.
421             %raw_attributes = (%{ $all_actions_config }, %raw_attributes)
422 737         2400 unless $raw_attributes{Private};
423 737         3814  
424 737         2107 my %final_attributes;
425              
426             while (my ($key, $value) = each %raw_attributes){
427             my $new_attrs = $self->_parse_attr($c, $name, $key => $value );
428             push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
429             }
430              
431 69164 100       251100 return \%final_attributes;
  1146 100       5048  
  654         3990  
432             }
433              
434             my ($self, $c, $name, $key, $values) = @_;
435              
436             my %final_attributes;
437             foreach my $value (ref($values) eq 'ARRAY' ? @$values : $values) {
438             my $meth = "_parse_${key}_attr";
439             if ( my $code = $self->can($meth) ) {
440 27592         69319 my %new_attrs = $self->$code( $c, $name, $value );
441 69164 100       142091 while (my ($new_key, $value) = each %new_attrs){
442             my $new_attrs = $key eq $new_key ?
443 69164         89447 { $new_key => [$value] } :
444             $self->_parse_attr($c, $name, $new_key => $value );
445 69164         167690 push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
446 97165         206313 }
447 97165         205438 }
  97408         165903  
  97408         375667  
448             else {
449             push( @{ $final_attributes{$key} }, $value );
450 69164         171180 }
451             }
452              
453             return \%final_attributes;
454 112582     112582   192612 }
455              
456 112582         127171 my ( $self, $c, $name, $value ) = @_;
457 112582 100       245042 # _parse_attr will call _parse_Path_attr for us
458 112746         197526 return Path => "/$name";
459 112746 100       358915 }
460 44321         87138  
461 44321         137412  
462 44564 100       119477 my ( $self, $c, $name, $value ) = @_;
463             # _parse_attr will call _parse_Path_attr for us
464             return Path => $name;
465 44564         100348 }
  44564         84059  
  44564         204872  
466              
467              
468             my ( $self, $c, $name, $value ) = @_;
469 68425         84260 $value = '' if !defined $value;
  68425         187305  
470             if ( $value =~ m!^/! ) {
471             return ( 'Path', $value );
472             }
473 112582         206930 elsif ( length $value ) {
474             return ( 'Path', join( '/', $self->path_prefix($c), $value ) );
475             }
476             else {
477 1728     1728   3894 return ( 'Path', $self->path_prefix($c) );
478             }
479 1728         5821 }
480              
481             my ($self, $c, $name, $value) = @_;
482 81     81   635  
483             if (defined($value) && length($value)) {
484             if ($value eq '.') {
485 11480     11480   22430 $value = '/'.$self->action_namespace($c);
486             } elsif (my ($rel, $rest) = $value =~ /^((?:\.{2}\/)+)(.*)$/) {
487 11480         28980 my @parts = split '/', $self->action_namespace($c);
488             my @levels = split '/', $rel;
489              
490 2025     2025   5928 $value = '/'.join('/', @parts[0 .. $#parts - @levels], $rest);
491             } elsif ($value !~ m/^\//) {
492             my $action_ns = $self->action_namespace($c);
493 15364     15364   26380  
494 15364 100       27249 if ($action_ns) {
495 15364 100       40245 $value = '/'.join('/', $action_ns, $value);
    100          
496 2140         5703 } else {
497             $value = '/'.$value; # special case namespace '' (root)
498             }
499 12631         43201 }
500             } else {
501             $value = '/'
502 593         3094 }
503              
504             return Chained => $value;
505             }
506              
507 12379     12379   24583 my ($self, $c, $name, $value) = @_;
508             return $self->_parse_Chained_attr($c, $name, '../'.$name);
509 12379 100 66     40064 }
510 11469 100       45837  
    100          
    100          
511 324         1401 my ( $self, $c ) = @_;
512             return PathPart => $self->path_prefix($c);
513 324         1245 }
514 324         930  
515             my ( $self, $c, $name, $value ) = @_;
516 324         1653 my $appname = $self->_application;
517             $value = Catalyst::Utils::resolve_namespace($appname . '::Action', $self->_action_class, $value);
518 6555         20600 return ( 'ActionClass', $value );
519             }
520 6555 100       13046  
521 6408         18729 my ( $self, $c, $name, $value ) = @_;
522              
523 147         581 my $appclass = Catalyst::Utils::class2appclass($self);
524             $value = "+${appclass}::Action::${value}";
525              
526             return ( 'ActionClass', $value );
527 910         1625 }
528              
529             my ($self, $app, $name, $value) = @_;
530 12379         32223 return Does => $self->_expand_role_shortname($value);
531             }
532              
533              
534 81     81   501 my ($self, @shortnames) = @_;
535 81         471 my $app = $self->_application;
536              
537             my $prefix = $self->can('_action_role_prefix') ? $self->_action_role_prefix : ['Catalyst::ActionRole::'];
538             my @prefixes = (qq{${app}::ActionRole::}, @$prefix);
539 331     331   1335  
540 331         2270 return String::RewritePrefix->rewrite(
541             { '' => sub {
542             my $loaded = load_first_existing_class(
543             map { "$_$_[0]" } @prefixes
544 918     918   2341 );
545 918         26934 return first { $loaded =~ /^$_/ }
546 918         3545 sort { length $b <=> length $a } @prefixes;
547 918         58169 },
548             '~' => $prefixes[0],
549             '+' => '' },
550             @shortnames,
551 84     84   394 );
552             }
553 84         495  
554 84         403 __PACKAGE__->meta->make_immutable;
555              
556 84         274 1;
557              
558              
559             =head1 CONFIGURATION
560 486     486   1104  
561 486         1293 Like any other L<Catalyst::Component>, controllers have a config hash,
562             accessible through $self->config from the controller actions. Some
563             settings are in use by the Catalyst framework:
564 330     330   971  
565 329     329   976 =head2 namespace
566 244     244   764  
567 243     243   738 This specifies the internal namespace the controller should be bound
568 81     81   711 to. By default the controller is bound to the URI version of the
569 0     0   0 controller name. For instance controller 'MyApp::Controller::Foo::Bar'
570 0     0   0 will be bound to 'foo/bar'. The default Root controller is an example
571             of setting namespace to '' (the null string).
572              
573 7561     7561   15428 =head2 path
574 7561         188981  
575             Sets 'path_prefix', as described below.
576 7561 50       42619  
577 7561         22497 =head2 action
578              
579             Allows you to set the attributes that the dispatcher creates actions out of.
580             This allows you to do 'rails style routes', or override some of the
581             attribute definitions of actions composed from Roles.
582 324     324   16071 You can set arguments globally (for all actions of the controller) and
  648         2482  
583             specifically (for a single action).
584 567         7283  
585 324         1402058 __PACKAGE__->config(
  324         1775  
586             action => {
587 7561         66162 '*' => { Chained => 'base', Args => 0 },
588             base => { Chained => '/', PathPart => '', CaptureArgs => 0 },
589             },
590             );
591              
592             In the case above every sub in the package would be made into a Chain
593             endpoint with a URI the same as the sub name for each sub, chained
594             to the sub named C<base>. Ergo dispatch to C</example> would call the
595             C<base> method, then the C<example> method.
596              
597             =head2 action_args
598              
599             Allows you to set constructor arguments on your actions. You can set arguments
600             globally and specifically (as above).
601             This is particularly useful when using C<ActionRole>s
602             (L<Catalyst::Controller::ActionRole>) and custom C<ActionClass>es.
603              
604             __PACKAGE__->config(
605             action_args => {
606             '*' => { globalarg1 => 'hello', globalarg2 => 'goodbye' },
607             'specific_action' => { customarg => 'arg1' },
608             },
609             );
610              
611             In the case above the action class associated with C<specific_action> would get
612             passed the following arguments, in addition to the normal action constructor
613             arguments, when it is instantiated:
614              
615             (globalarg1 => 'hello', globalarg2 => 'goodbye', customarg => 'arg1')
616              
617             =head1 METHODS
618              
619             =head2 BUILDARGS ($app, @args)
620              
621             From L<Catalyst::Component::ApplicationAttribute>, stashes the application
622             instance as $self->_application.
623              
624             =head2 $self->action_for($action_name)
625              
626             Returns the Catalyst::Action object (if any) for a given action in this
627             controller or relative to it. You may refer to actions in controllers
628             nested under the current controllers namespace, or in controllers 'up'
629             from the current controller namespace. For example:
630              
631             package MyApp::Controller::One::Two;
632             use base 'Catalyst::Controller';
633              
634             sub foo :Local {
635             my ($self, $c) = @_;
636             $self->action_for('foo'); # action 'foo' in Controller 'One::Two'
637             $self->action_for('three/bar'); # action 'bar' in Controller 'One::Two::Three'
638             $self->action_for('../boo'); # action 'boo' in Controller 'One'
639             }
640              
641             This returns 'undef' if there is no action matching the requested action
642             name (after any path normalization) so you should check for this as needed.
643              
644             =head2 $self->action_namespace($c)
645              
646             Returns the private namespace for actions in this component. Defaults
647             to a value from the controller name (for
648             e.g. MyApp::Controller::Foo::Bar becomes "foo/bar") or can be
649             overridden from the "namespace" config key.
650              
651              
652             =head2 $self->path_prefix($c)
653              
654             Returns the default path prefix for :PathPrefix, :Local and
655             relative :Path actions in this component. Defaults to the action_namespace or
656             can be overridden from the "path" config key.
657              
658             =head2 $self->register_actions($c)
659              
660             Finds all applicable actions for this component, creates
661             Catalyst::Action objects (using $self->create_action) for them and
662             registers them with $c->dispatcher.
663              
664             =head2 $self->get_action_methods()
665              
666             Returns a list of L<Moose::Meta::Method> objects, doing the
667             L<MooseX::MethodAttributes::Role::Meta::Method> role, which are the set of
668             action methods for this package.
669              
670             =head2 $self->register_action_methods($c, @methods)
671              
672             Creates action objects for a set of action methods using C< create_action >,
673             and registers them with the dispatcher.
674              
675             =head2 $self->action_class(%args)
676              
677             Used when a controller is creating an action to determine the correct base
678             action class to use.
679              
680             =head2 $self->create_action(%args)
681              
682             Called with a hash of data to be use for construction of a new
683             Catalyst::Action (or appropriate sub/alternative class) object.
684              
685             =head2 $self->gather_action_roles(\%action_args)
686              
687             Gathers the list of roles to apply to an action with the given %action_args.
688              
689             =head2 $self->gather_default_action_roles(\%action_args)
690              
691             returns a list of action roles to be applied based on core, builtin rules.
692             Currently only the L<Catalyst::ActionRole::HTTPMethods> role is applied
693             this way.
694              
695             =head2 $self->_application
696              
697             =head2 $self->_app
698              
699             Returns the application instance stored by C<new()>
700              
701             =head1 ACTION SUBROUTINE ATTRIBUTES
702              
703             Please see L<Catalyst::Manual::Intro> for more details
704              
705             Think of action attributes as a sort of way to record metadata about an action,
706             similar to how annotations work in other languages you might have heard of.
707             Generally L<Catalyst> uses these to influence how the dispatcher sees your
708             action and when it will run it in response to an incoming request. They can
709             also be used for other things. Here's a summary, but you should refer to the
710             linked manual page for additional help.
711              
712             =head2 Global
713              
714             sub homepage :Global { ... }
715              
716             A global action defined in any controller always runs relative to your root.
717             So the above is the same as:
718              
719             sub myaction :Path("/homepage") { ... }
720              
721             =head2 Absolute
722              
723             Status: Deprecated alias to L</Global>.
724              
725             =head2 Local
726              
727             Alias to "Path("$action_name"). The following two actions are the same:
728              
729             sub myaction :Local { ... }
730             sub myaction :Path('myaction') { ... }
731              
732             =head2 Relative
733              
734             Status: Deprecated alias to L</Local>
735              
736             =head2 Path
737              
738             Handle various types of paths:
739              
740             package MyApp::Controller::Baz {
741              
742             ...
743              
744             sub myaction1 :Path { ... } # -> /baz
745             sub myaction2 :Path('foo') { ... } # -> /baz/foo
746             sub myaction2 :Path('/bar') { ... } # -> /bar
747             }
748              
749             This is a general toolbox for attaching your action to a given path.
750              
751              
752             =head2 Regex
753              
754             =head2 Regexp
755              
756             B<Status: Deprecated.> Use Chained methods or other techniques.
757             If you really depend on this, install the standalone
758             L<Catalyst::DispatchType::Regex> distribution.
759              
760             A global way to match a give regular expression in the incoming request path.
761              
762             =head2 LocalRegex
763              
764             =head2 LocalRegexp
765              
766             B<Status: Deprecated.> Use Chained methods or other techniques.
767             If you really depend on this, install the standalone
768             L<Catalyst::DispatchType::Regex> distribution.
769              
770             Like L</Regex> but scoped under the namespace of the containing controller
771              
772             =head2 Chained
773              
774             =head2 ChainedParent
775              
776             =head2 PathPrefix
777              
778             =head2 PathPart
779              
780             =head2 CaptureArgs
781              
782             Allowed values for CaptureArgs is a single integer (CaptureArgs(2), meaning two
783             allowed) or you can declare a L<Moose>, L<MooseX::Types> or L<Type::Tiny>
784             named constraint such as CaptureArgs(Int,Str) would require two args with
785             the first being a Integer and the second a string. You may declare your own
786             custom type constraints and import them into the controller namespace:
787              
788             package MyApp::Controller::Root;
789              
790             use Moose;
791             use MooseX::MethodAttributes;
792             use MyApp::Types qw/Int/;
793              
794             extends 'Catalyst::Controller';
795              
796             sub chain_base :Chained(/) CaptureArgs(1) { }
797              
798             sub any_priority_chain :Chained(chain_base) PathPart('') Args(1) { }
799              
800             sub int_priority_chain :Chained(chain_base) PathPart('') Args(Int) { }
801              
802             See L<Catalyst::RouteMatching> for more.
803              
804             Please see L<Catalyst::DispatchType::Chained> for more.
805              
806             =head2 ActionClass
807              
808             Set the base class for the action, defaults to L</Catalyst::Action>. It is now
809             preferred to use L</Does>.
810              
811             =head2 MyAction
812              
813             Set the ActionClass using a custom Action in your project namespace.
814              
815             The following is exactly the same:
816              
817             sub foo_action1 : Local ActionClass('+MyApp::Action::Bar') { ... }
818             sub foo_action2 : Local MyAction('Bar') { ... }
819              
820             =head2 Does
821              
822             package MyApp::Controller::Zoo;
823              
824             sub foo : Local Does('Buzz') { ... } # Catalyst::ActionRole::
825             sub bar : Local Does('~Buzz') { ... } # MyApp::ActionRole::Buzz
826             sub baz : Local Does('+MyApp::ActionRole::Buzz') { ... }
827              
828             =head2 GET
829              
830             =head2 POST
831              
832             =head2 PUT
833              
834             =head2 DELETE
835              
836             =head2 OPTION
837              
838             =head2 HEAD
839              
840             =head2 PATCH
841              
842             =head2 Method('...')
843              
844             Sets the give action path to match the specified HTTP method, or via one of the
845             broadly accepted methods of overriding the 'true' method (see
846             L<Catalyst::ActionRole::HTTPMethods>).
847              
848             =head2 Args
849              
850             When used with L</Path> indicates the number of arguments expected in
851             the path. However if no Args value is set, assumed to 'slurp' all
852             remaining path pars under this namespace.
853              
854             Allowed values for Args is a single integer (Args(2), meaning two allowed) or you
855             can declare a L<Moose>, L<MooseX::Types> or L<Type::Tiny> named constraint such
856             as Args(Int,Str) would require two args with the first being a Integer and the
857             second a string. You may declare your own custom type constraints and import
858             them into the controller namespace:
859              
860             package MyApp::Controller::Root;
861              
862             use Moose;
863             use MooseX::MethodAttributes;
864             use MyApp::Types qw/Tuple Int Str StrMatch UserId/;
865              
866             extends 'Catalyst::Controller';
867              
868             sub user :Local Args(UserId) {
869             my ($self, $c, $int) = @_;
870             }
871              
872             sub an_int :Local Args(Int) {
873             my ($self, $c, $int) = @_;
874             }
875              
876             sub many_ints :Local Args(ArrayRef[Int]) {
877             my ($self, $c, @ints) = @_;
878             }
879              
880             sub match :Local Args(StrMatch[qr{\d\d-\d\d-\d\d}]) {
881             my ($self, $c, $int) = @_;
882             }
883              
884             If you choose not to use imported type constraints (like L<Type::Tiny>, or <MooseX::Types>
885             you may use L<Moose> 'stringy' types however just like when you use these types in your
886             declared attributes you must quote them:
887              
888             sub my_moose_type :Local Args('Int') { ... }
889              
890             If you use 'reference' type constraints (such as ArrayRef[Int]) that have an unknown
891             number of allowed matches, we set this the same way "Args" is. Please keep in mind
892             that actions with an undetermined number of args match at lower precedence than those
893             with a fixed number. You may use reference types such as Tuple from L<Types::Standard>
894             that allows you to fix the number of allowed args. For example Args(Tuple[Int,Int])
895             would be determined to be two args (or really the same as Args(Int,Int).) You may
896             find this useful for creating custom subtypes with complex matching rules that you
897             wish to reuse over many actions.
898              
899             See L<Catalyst::RouteMatching> for more.
900              
901             B<Note>: It is highly recommended to use L<Type::Tiny> for your type constraints over
902             other options. L<Type::Tiny> exposed a better meta data interface which allows us to
903             do more and better types of introspection driving tests and debugging.
904              
905             =head2 Consumes('...')
906              
907             Matches the current action against the content-type of the request. Typically
908             this is used when the request is a POST or PUT and you want to restrict the
909             submitted content type. For example, you might have an HTML for that either
910             returns classic url encoded form data, or JSON when Javascript is enabled. In
911             this case you may wish to match either incoming type to one of two different
912             actions, for properly processing.
913              
914             Examples:
915              
916             sub is_json : Chained('start') Consumes('application/json') { ... }
917             sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
918             sub is_multipart : Chained('start') Consumes('multipart/form-data') { ... }
919              
920             To reduce boilerplate, we include the following content type shortcuts:
921              
922             Examples
923              
924             sub is_json : Chained('start') Consume(JSON) { ... }
925             sub is_urlencoded : Chained('start') Consumes(UrlEncoded) { ... }
926             sub is_multipart : Chained('start') Consumes(Multipart) { ... }
927              
928             You may specify more than one match:
929              
930             sub is_more_than_one
931             : Chained('start')
932             : Consumes('application/x-www-form-urlencoded')
933             : Consumes('multipart/form-data')
934              
935             sub is_more_than_one
936             : Chained('start')
937             : Consumes(UrlEncoded)
938             : Consumes(Multipart)
939              
940             Since it is a common case the shortcut C<HTMLForm> matches both
941             'application/x-www-form-urlencoded' and 'multipart/form-data'. Here's the full
942             list of available shortcuts:
943              
944             JSON => 'application/json',
945             JS => 'application/javascript',
946             PERL => 'application/perl',
947             HTML => 'text/html',
948             XML => 'text/XML',
949             Plain => 'text/plain',
950             UrlEncoded => 'application/x-www-form-urlencoded',
951             Multipart => 'multipart/form-data',
952             HTMLForm => ['application/x-www-form-urlencoded','multipart/form-data'],
953              
954             Please keep in mind that when dispatching, L<Catalyst> will match the first most
955             relevant case, so if you use the C<Consumes> attribute, you should place your
956             most accurate matches early in the Chain, and your 'catchall' actions last.
957              
958             See L<Catalyst::ActionRole::ConsumesContent> for more.
959              
960             =head2 Scheme(...)
961              
962             Allows you to specify a URI scheme for the action or action chain. For example
963             you can required that a given path be C<https> or that it is a websocket endpoint
964             C<ws> or C<wss>. For an action chain you may currently only have one defined
965             Scheme.
966              
967             package MyApp::Controller::Root;
968              
969             use base 'Catalyst::Controller';
970              
971             sub is_http :Path(scheme) Scheme(http) Args(0) {
972             my ($self, $c) = @_;
973             $c->response->body("is_http");
974             }
975              
976             sub is_https :Path(scheme) Scheme(https) Args(0) {
977             my ($self, $c) = @_;
978             $c->response->body("is_https");
979             }
980              
981             In the above example http://localhost/root/scheme would match the first
982             action (is_http) but https://localhost/root/scheme would match the second.
983              
984             As an added benefit, if an action or action chain defines a Scheme, when using
985             $c->uri_for the scheme of the generated URL will use what you define in the action
986             or action chain (the current behavior is to set the scheme based on the current
987             incoming request). This makes it easier to use uri_for on websites where some
988             paths are secure and others are not. You may also use this to other schemes
989             like websockets.
990              
991             See L<Catalyst::ActionRole::Scheme> for more.
992              
993             =head1 OPTIONAL METHODS
994              
995             =head2 _parse_[$name]_attr
996              
997             Allows you to customize parsing of subroutine attributes.
998              
999             sub myaction1 :Path TwoArgs { ... }
1000              
1001             sub _parse_TwoArgs_attr {
1002             my ( $self, $c, $name, $value ) = @_;
1003             # $self -> controller instance
1004             #
1005             return(Args => 2);
1006             }
1007              
1008             Please note that this feature does not let you actually assign new functions
1009             to actions via subroutine attributes, but is really more for creating useful
1010             aliases to existing core and extended attributes, and transforms based on
1011             existing information (like from configuration). Code for actually doing
1012             something meaningful with the subroutine attributes will be located in the
1013             L<Catalyst::Action> classes (or your subclasses), L<Catalyst::Dispatcher> and
1014             in subclasses of L<Catalyst::DispatchType>. Remember these methods only get
1015             called basically once when the application is starting, not per request!
1016              
1017             =head1 AUTHORS
1018              
1019             Catalyst Contributors, see Catalyst.pm
1020              
1021             =head1 COPYRIGHT
1022              
1023             This library is free software. You can redistribute it and/or modify
1024             it under the same terms as Perl itself.
1025              
1026             =cut