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 166     166   6804263 use Class::MOP;
  166         10174532  
  166         1349  
4 166     166   1134882 use Class::Load ':all';
  166         432  
  166         5026  
5 166     166   1005 use String::RewritePrefix;
  166         416  
  166         28029  
6 166     166   17067 use Moose::Util qw/find_meta/;
  166         33466  
  166         1558  
7 166     166   33811 use List::Util qw/first uniq/;
  166         414  
  166         1484  
8 166     166   38371 use namespace::clean -except => 'meta';
  166         419  
  166         13263  
9 166     166   12768  
  166         155250  
  166         1761  
10             BEGIN {
11             extends qw/Catalyst::Component/;
12 166     166   78496 with qw/MooseX::MethodAttributes::Role::AttrContainer::Inheritable/;
13 166         195171 }
14              
15             use MooseX::MethodAttributes;
16 166     166   9247266 use Catalyst::Exception;
  166         517  
  166         1159  
17 166     166   13322191 use Catalyst::Utils;
  166         495  
  166         5009  
18 166     166   1106  
  166         407  
  166         85992  
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 7078     7078 0 10514258 my $actions = delete $args->{actions} || {};
76 7078   100     35441 my $attr_value = $self->merge_config_hashes($actions, $action);
77 7078   100     25908 $self->_controller_actions($attr_value);
78 7078         23258  
79 7078         307851 # trigger lazy builder
80             $self->_all_actions_attributes;
81             $self->_action_roles;
82 7078         235967 }
83 7078         273432  
84             my $self = shift;
85             my @roles = $self->_expand_role_shortname($self->_action_role_args);
86             load_class($_) for @roles;
87 7078     7078   11692 return \@roles;
88 7078         282987 }
89 7078         397580  
90 7078         905507 my ($self) = @_;
91             delete $self->_controller_actions->{'*'} || {};
92             }
93              
94 7078     7078   14814 =head1 NAME
95 7078 100       223224  
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 955     955   2756  
132             $c->forward('_END');
133 955         1936 }
  955         5014  
134 2859 100       9130  
135             my ( $self, $c ) = @_;
136             my $begin = ( $c->get_actions( 'begin', $c->namespace ) )[-1];
137 929         3635 return 1 unless $begin;
138 166     166   83565 $begin->dispatch( $c );
  166         179333  
  166         1185  
139             #If there is an error, all bets off
140             if( @{ $c->error }) {
141 955     955   3209 return !@{ $c->error };
142 955         23532 } else {
143 955 100       5235 return $c->state || 1;
144 300         1442 }
145             }
146 300 50       824  
  300         1605  
147 0         0 my ( $self, $c ) = @_;
  0         0  
148             my @auto = $c->get_actions( 'auto', $c->namespace );
149 300   100     7809 foreach my $auto (@auto) {
150             # We FORCE the auto action user to explicitly return
151 166     166   222814 # true. We need to do this since there's some auto
  166         449  
  166         780  
152             # users (Catalyst::Authentication::Credential::HTTP) that
153             # actually do a detach instead.
154 955     955   3162 $c->state(0);
155 955         23271 $auto->dispatch( $c );
156 955         3488 return 0 unless $c->state;
157             }
158             return $c->state || 1;
159             }
160              
161 40         968 my ( $self, $c ) = @_;
162 40         164 if ( ref $c->action
163 36 100       801 && $c->action->can('execute')
164             && defined $c->req->action )
165 949   100     22633 {
166 166     166   167960 $c->action->dispatch( $c );
  166         485  
  166         838  
167             }
168             #If there is an error, all bets off
169 949     949   3195 if( @{ $c->error }) {
170 949 50 33     22368 return !@{ $c->error };
      33        
171             } else {
172             return $c->state || 1;
173             }
174 949         21839 }
175              
176             my ( $self, $c ) = @_;
177 918 100       2629 my $end = ( $c->get_actions( 'end', $c->namespace ) )[-1];
  918         3430  
178 26         68 return 1 unless $end;
  26         107  
179             $end->dispatch( $c );
180 892   100     22231 return !@{ $c->error };
181             }
182 166     166   170097  
  166         521  
  166         943  
183             my ( $self, $name ) = @_;
184             my $app = ($self->isa('Catalyst') ? $self : $self->_application);
185 929     929   3009 return $app->dispatcher->get_action($name, $self->action_namespace);
186 929         22921 }
187 929 100       4510  
188 646         2948 #my opinion is that this whole sub really should be a builder method, not
189 645         1612 #something that happens on every call. Anyone else disagree?? -- groditi
  645         2451  
190 166     166   166747 ## -- apparently this is all just waiting for app/ctx split
  166         505  
  166         922  
191             around action_namespace => sub {
192             my $orig = shift;
193 65     65 1 783 my ( $self, $c ) = @_;
194 65 100       2523  
195 65         250 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 6517     6517 1 15023 map {
249 6517   33     23905 $meta->find_method_by_name($_)
250 6517 50       113162 || confess( sprintf 'Action "%s" is not available from controller %s',
251             $_, ref $self )
252             } keys %{ $self->_controller_actions }
253             ) if ( ref $self );
254 6517         25897 return uniq @methods;
255             }
256              
257              
258             my ( $self, $c ) = @_;
259             $self->register_action_methods( $c, $self->get_action_methods );
260 655 50       15259 }
261              
262             my ( $self, $c, @methods ) = @_;
263 6517 100       60302515 my $class = $self->catalyst_component_name;
  6368         216356  
264             #this is still not correct for some reason.
265 6517         65394 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 6515     6515 1 19111 if (scalar(@really_bad_methods)) {
271 6515         40515 $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 6515     6515 1 439895 foreach my $method (@methods) {
276 6515         48336 my $name = $method->name;
277             # Horrible hack! All method metaclasses should have an attributes
278 6515         48587 # method, core Moose bug - see r13354.
279             my $attributes = $method->can('attributes') ? $method->attributes : [];
280             my $attrs = $self->_parse_attrs( $c, $name, @{ $attributes } );
281 6515 50 66     35926 if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
      100        
282 148         659 $c->log->warn( 'Bad action definition "'
  742         3266  
  742         2297  
283 148 100       1120 . join( ' ', @{ $attributes } )
284 2         27 . qq/" for "$class->$name"/ )
285             if $c->debug;
286             next;
287             }
288 6515         19389 my $reverse = $namespace ? "${namespace}/${name}" : $name;
289 69176         267515 my $action = $self->create_action(
290             name => $name,
291             code => $method->body,
292 69176 100       2310130 reverse => $reverse,
293 69176         702208 namespace => $namespace,
  69176         229477  
294 69176 50 66     263671 class => $class,
295             attributes => $attrs,
296 0 0       0 );
  0         0  
297              
298             $c->dispatcher->register( $c, $action );
299 0         0 }
300             }
301 69176 100       210323  
302 69176         296139 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 69176         5941794  
312             return $meta->name;
313             }
314              
315             my $self = shift;
316 1818     1818   4960 my %args = @_;
317              
318 1818         6484 my $class = (exists $args{attributes}{ActionClass}
319 1818         643259 ? $args{attributes}{ActionClass}[0]
320             : $self->_action_class);
321              
322             load_class($class);
323             return $class;
324 1818     0   4232254 }
  0     0   0  
        0      
        0      
        0      
        0      
        0      
325              
326 1818         100730 my $self = shift;
327             my %args = @_;
328              
329             my $class = $self->action_class(%args);
330 69176     69176 1 105443  
331 69176         204887 load_class($class);
332             Moose->init_meta(for_class => $class)
333             unless Class::MOP::does_metaclass_exist($class);
334 69176 100       283748  
335             unless ($args{name} =~ /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/) {
336             my @roles = $self->gather_action_roles(%args);
337 69176         257488 push @roles, $self->gather_default_action_roles(%args);
338 69176         7868819  
339             $class = $self->_apply_action_class_roles($class, @roles) if @roles;
340             }
341              
342 69176     69176 1 115215 my $action_args = (
343 69176         316238 ref($self)
344             ? $self->action_args
345 69176         226736 : $self->config->{action_args}
346             );
347 69176         202458  
348 69176 100       1718467 my %extra_args = (
349             %{ $action_args->{'*'} || {} },
350             %{ $action_args->{ $args{name} } || {} },
351 69176 100       1803259 );
352 36601         144920  
353 36601         151923 return $class->new({ %extra_args, %args });
354             }
355 36601 100       96395  
356             my ($self, %args) = @_;
357             return (
358             (blessed $self ? $self->_action_roles : ()),
359             @{ $args{attributes}->{Does} || [] },
360             );
361             }
362 69176 100       2160432  
363             my ($self, %args) = @_;
364             my @roles = ();
365 69176 100       302291 push @roles, 'Catalyst::ActionRole::HTTPMethods'
366 69176 100       110843 if $args{attributes}->{Method};
  69176         285148  
367              
368             push @roles, 'Catalyst::ActionRole::ConsumesContent'
369 69176         2136101 if $args{attributes}->{Consumes};
370              
371             push @roles, 'Catalyst::ActionRole::Scheme'
372             if $args{attributes}->{Scheme};
373 36601     36601 1 138921  
374             push @roles, 'Catalyst::ActionRole::QueryMatching'
375             if $args{attributes}->{Query};
376 36601 100       1596981 return @roles;
  36601 100       217559  
377             }
378              
379             my ( $self, $c, $name, @attrs ) = @_;
380              
381 36601     36601 1 126540 my %raw_attributes;
382 36601         62867  
383             foreach my $attr (@attrs) {
384 36601 100       87613  
385             # Parse out :Foo(bar) into Foo => bar etc (and arrayify)
386              
387 36601 100       76244 if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+?)?\s*\))?$/ ) )
388             {
389              
390 36601 100       72943 if ( defined $value ) {
391             ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
392             }
393 36601 100       71278 push( @{ $raw_attributes{$key} }, $value );
394 36601         90861 }
395             }
396              
397             my ($actions_config, $all_actions_config);
398 69176     69176   202777 if( ref($self) ) {
399             $actions_config = $self->_controller_actions;
400 69176         108258 # No, you're not getting actions => { '*' => ... } with actions in MyApp.
401             $all_actions_config = $self->_all_actions_attributes;
402 69176         127137 } else {
403             my $cfg = $self->config;
404             $actions_config = $self->merge_config_hashes($cfg->{actions}, $cfg->{action});
405             $all_actions_config = {};
406 96095 50       652099 }
407              
408             %raw_attributes = (
409 96095 100       210040 %raw_attributes,
410 35947 100       141878 # Note we deep copy array refs here to stop crapping on config
411             # when attributes are parsed. RT#65463
412 96095         138202 exists $actions_config->{$name} ? map { ref($_) eq 'ARRAY' ? [ @$_ ] : $_ } %{ $actions_config->{$name } } : (),
  96095         342934  
413             );
414              
415             # Private actions with additional attributes will raise a warning and then
416 69176         118104 # be ignored. Adding '*' arguments to the default _DISPATCH / etc. methods,
417 69176 100       154593 # which are Private, will prevent those from being registered. They should
418 68434         2286008 # probably be turned into :Actions instead, or we might want to otherwise
419             # disambiguate between those built-in internal actions and user-level
420 68434         1957873 # Private ones.
421             %raw_attributes = (%{ $all_actions_config }, %raw_attributes)
422 742         2720 unless $raw_attributes{Private};
423 742         4327  
424 742         2279 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 69176 100       305227 return \%final_attributes;
  1146 100       6172  
  654         3271  
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 27594         82463 my %new_attrs = $self->$code( $c, $name, $value );
441 69176 100       172686 while (my ($new_key, $value) = each %new_attrs){
442             my $new_attrs = $key eq $new_key ?
443 69176         109608 { $new_key => [$value] } :
444             $self->_parse_attr($c, $name, $new_key => $value );
445 69176         210172 push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
446 97179         252329 }
447 97179         253900 }
  97422         200120  
  97422         455426  
448             else {
449             push( @{ $final_attributes{$key} }, $value );
450 69176         209060 }
451             }
452              
453             return \%final_attributes;
454 112598     112598   236802 }
455              
456 112598         153125 my ( $self, $c, $name, $value ) = @_;
457 112598 100       296111 # _parse_attr will call _parse_Path_attr for us
458 112762         244135 return Path => "/$name";
459 112762 100       436933 }
460 44325         105103  
461 44325         170735  
462 44568 100       147993 my ( $self, $c, $name, $value ) = @_;
463             # _parse_attr will call _parse_Path_attr for us
464             return Path => $name;
465 44568         123800 }
  44568         101620  
  44568         249096  
466              
467              
468             my ( $self, $c, $name, $value ) = @_;
469 68437         100892 $value = '' if !defined $value;
  68437         228222  
470             if ( $value =~ m!^/! ) {
471             return ( 'Path', $value );
472             }
473 112598         248978 elsif ( length $value ) {
474             return ( 'Path', join( '/', $self->path_prefix($c), $value ) );
475             }
476             else {
477 1728     1728   4518 return ( 'Path', $self->path_prefix($c) );
478             }
479 1728         6956 }
480              
481             my ($self, $c, $name, $value) = @_;
482 81     81   621  
483             if (defined($value) && length($value)) {
484             if ($value eq '.') {
485 11482     11482   28635 $value = '/'.$self->action_namespace($c);
486             } elsif (my ($rel, $rest) = $value =~ /^((?:\.{2}\/)+)(.*)$/) {
487 11482         35853 my @parts = split '/', $self->action_namespace($c);
488             my @levels = split '/', $rel;
489              
490 2025     2025   7276 $value = '/'.join('/', @parts[0 .. $#parts - @levels], $rest);
491             } elsif ($value !~ m/^\//) {
492             my $action_ns = $self->action_namespace($c);
493 15366     15366   33671  
494 15366 100       34866 if ($action_ns) {
495 15366 100       49756 $value = '/'.join('/', $action_ns, $value);
    100          
496 2140         6725 } else {
497             $value = '/'.$value; # special case namespace '' (root)
498             }
499 12633         53478 }
500             } else {
501             $value = '/'
502 593         3646 }
503              
504             return Chained => $value;
505             }
506              
507 12379     12379   29329 my ($self, $c, $name, $value) = @_;
508             return $self->_parse_Chained_attr($c, $name, '../'.$name);
509 12379 100 66     48832 }
510 11469 100       55874  
    100          
    100          
511 324         1561 my ( $self, $c ) = @_;
512             return PathPart => $self->path_prefix($c);
513 324         1415 }
514 324         1031  
515             my ( $self, $c, $name, $value ) = @_;
516 324         2057 my $appname = $self->_application;
517             $value = Catalyst::Utils::resolve_namespace($appname . '::Action', $self->_action_class, $value);
518 6555         23479 return ( 'ActionClass', $value );
519             }
520 6555 100       15087  
521 6408         22254 my ( $self, $c, $name, $value ) = @_;
522              
523 147         577 my $appclass = Catalyst::Utils::class2appclass($self);
524             $value = "+${appclass}::Action::${value}";
525              
526             return ( 'ActionClass', $value );
527 910         1854 }
528              
529             my ($self, $app, $name, $value) = @_;
530 12379         38866 return Does => $self->_expand_role_shortname($value);
531             }
532              
533              
534 81     81   411 my ($self, @shortnames) = @_;
535 81         467 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   1303  
540 331         2471 return String::RewritePrefix->rewrite(
541             { '' => sub {
542             my $loaded = load_first_existing_class(
543             map { "$_$_[0]" } @prefixes
544 918     918   2686 );
545 918         32659 return first { $loaded =~ /^$_/ }
546 918         4231 sort { length $b <=> length $a } @prefixes;
547 918         71752 },
548             '~' => $prefixes[0],
549             '+' => '' },
550             @shortnames,
551 84     84   365 );
552             }
553 84         544  
554 84         423 __PACKAGE__->meta->make_immutable;
555              
556 84         333 1;
557              
558              
559             =head1 CONFIGURATION
560 486     486   1485  
561 486         1673 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   1166  
565 329     329   1119 =head2 namespace
566 244     244   804  
567 243     243   841 This specifies the internal namespace the controller should be bound
568 81     81   368 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 7564     7564   18208 =head2 path
574 7564         225640  
575             Sets 'path_prefix', as described below.
576 7564 50       51333  
577 7564         27679 =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   19814 You can set arguments globally (for all actions of the controller) and
  648         3074  
583             specifically (for a single action).
584 567         8849  
585 324         1693614 __PACKAGE__->config(
  324         2284  
586             action => {
587 7564         82323 '*' => { 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