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