1 package Catalyst::Controller;
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';
13 extends qw/Catalyst::Component/;
14 with qw/MooseX::MethodAttributes::Role::AttrContainer::Inheritable/;
17 use MooseX::MethodAttributes;
18 use Catalyst::Exception;
21 with 'Catalyst::Component::ApplicationAttribute';
27 predicate => 'has_path_prefix',
30 has action_namespace => (
33 init_arg => 'namespace',
34 predicate => 'has_action_namespace',
38 accessor => '_controller_actions',
43 has _action_role_args => (
44 traits => [qw(Array)],
45 isa => 'ArrayRef[Str]',
46 init_arg => 'action_roles',
47 default => sub { [] },
49 _action_role_args => 'elements',
53 has _action_roles => (
54 traits => [qw(Array)],
55 isa => 'ArrayRef[RoleName]',
58 builder => '_build__action_roles',
60 _action_roles => 'elements',
64 has action_args => (is => 'ro');
66 # ->config(actions => { '*' => ...
67 has _all_actions_attributes => (
72 builder => '_build__all_actions_attributes',
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);
82 # trigger lazy builder
83 $self->_all_actions_attributes;
87 sub _build__action_roles {
89 my @roles = $self->_expand_role_shortname($self->_action_role_args);
90 load_class($_) for @roles;
94 sub _build__all_actions_attributes {
96 delete $self->_controller_actions->{'*'} || {};
101 Catalyst::Controller - Catalyst Controller base class
105 package MyApp::Controller::Search
106 use base qw/Catalyst::Controller/;
109 my ($self,$c,@args) = @_;
111 } # Dispatches to /search/foo
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.
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/;
126 __PACKAGE__->_dispatch_steps( [qw/_BEGIN _AUTO _ACTION/] );
127 __PACKAGE__->_action_class('Catalyst::Action');
128 __PACKAGE__->_action_role_prefix([ 'Catalyst::ActionRole::' ]);
131 sub _DISPATCH : Private {
132 my ( $self, $c ) = @_;
134 foreach my $disp ( @{ $self->_dispatch_steps } ) {
135 last unless $c->forward($disp);
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 return !@{ $c->error };
149 sub _AUTO : Private {
150 my ( $self, $c ) = @_;
151 my @auto = $c->get_actions( 'auto', $c->namespace );
152 foreach my $auto (@auto) {
153 $auto->dispatch( $c );
154 return 0 unless $c->state;
159 sub _ACTION : Private {
160 my ( $self, $c ) = @_;
162 && $c->action->can('execute')
163 && defined $c->req->action )
165 $c->action->dispatch( $c );
167 return !@{ $c->error };
171 my ( $self, $c ) = @_;
172 my $end = ( $c->get_actions( 'end', $c->namespace ) )[-1];
173 return 1 unless $end;
174 $end->dispatch( $c );
175 return !@{ $c->error };
179 my ( $self, $name ) = @_;
180 my $app = ($self->isa('Catalyst') ? $self : $self->_application);
181 return $app->dispatcher->get_action($name, $self->action_namespace);
184 #my opinion is that this whole sub really should be a builder method, not
185 #something that happens on every call. Anyone else disagree?? -- groditi
186 ## -- apparently this is all just waiting for app/ctx split
187 around action_namespace => sub {
189 my ( $self, $c ) = @_;
191 my $class = ref($self) || $self;
192 my $appclass = ref($c) || $c;
194 return $self->$orig if $self->has_action_namespace;
196 return $class->config->{namespace} if exists $class->config->{namespace};
201 $case_s = $appclass->config->{case_sensitive};
203 if ($self->isa('Catalyst')) {
204 $case_s = $class->config->{case_sensitive};
207 $case_s = ref($self->_application)->config->{case_sensitive};
209 confess("Can't figure out case_sensitive setting");
214 my $namespace = Catalyst::Utils::class2prefix($self->catalyst_component_name, $case_s) || '';
215 $self->$orig($namespace) if ref($self);
219 #Once again, this is probably better written as a builder method
220 around path_prefix => sub {
224 return $self->$orig if $self->has_path_prefix;
226 return $self->config->{path} if exists $self->config->{path};
228 my $namespace = $self->action_namespace(@_);
229 $self->$orig($namespace) if ref($self);
233 sub get_action_methods {
235 my $meta = find_meta($self) || confess("No metaclass setup for $self");
237 sprintf "Metaclass %s for %s cannot support register_actions.",
238 ref $meta, $meta->name,
239 ) unless $meta->can('get_nearest_methods_with_attributes');
240 my @methods = $meta->get_nearest_methods_with_attributes;
242 # actions specified via config are also action_methods
246 $meta->find_method_by_name($_)
247 || confess( sprintf 'Action "%s" is not available from controller %s',
249 } keys %{ $self->_controller_actions }
251 return uniq @methods;
255 sub register_actions {
256 my ( $self, $c ) = @_;
257 $self->register_action_methods( $c, $self->get_action_methods );
260 sub register_action_methods {
261 my ( $self, $c, @methods ) = @_;
262 my $class = $self->catalyst_component_name;
263 #this is still not correct for some reason.
264 my $namespace = $self->action_namespace($c);
267 if (!blessed($self) && $self eq $c && scalar(@methods)) {
268 my @really_bad_methods = grep { ! /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/ } map { $_->name } @methods;
269 if (scalar(@really_bad_methods)) {
270 $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.");
274 foreach my $method (@methods) {
275 my $name = $method->name;
276 # Horrible hack! All method metaclasses should have an attributes
277 # method, core Moose bug - see r13354.
278 my $attributes = $method->can('attributes') ? $method->attributes : [];
279 my $attrs = $self->_parse_attrs( $c, $name, @{ $attributes } );
280 if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
281 $c->log->warn( 'Bad action definition "'
282 . join( ' ', @{ $attributes } )
283 . qq/" for "$class->$name"/ )
287 my $reverse = $namespace ? "${namespace}/${name}" : $name;
288 my $action = $self->create_action(
290 code => $method->body,
292 namespace => $namespace,
294 attributes => $attrs,
297 $c->dispatcher->register( $c, $action );
301 sub _apply_action_class_roles {
302 my ($self, $class, @roles) = @_;
304 load_class($_) for @roles;
305 my $meta = Moose::Meta::Class->initialize($class)->create_anon_class(
306 superclasses => [$class],
310 $meta->add_method(meta => sub { $meta });
319 my $class = (exists $args{attributes}{ActionClass}
320 ? $args{attributes}{ActionClass}[0]
321 : $self->_action_class);
331 my $class = $self->action_class(%args);
334 Moose->init_meta(for_class => $class)
335 unless Class::MOP::does_metaclass_exist($class);
337 unless ($args{name} =~ /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/) {
338 my @roles = $self->gather_action_roles(%args);
339 push @roles, $self->gather_default_action_roles(%args);
341 $class = $self->_apply_action_class_roles($class, @roles) if @roles;
347 : $self->config->{action_args}
351 %{ $action_args->{'*'} || {} },
352 %{ $action_args->{ $args{name} } || {} },
355 return $class->new({ %extra_args, %args });
358 sub gather_action_roles {
359 my ($self, %args) = @_;
361 (blessed $self ? $self->_action_roles : ()),
362 @{ $args{attributes}->{Does} || [] },
366 sub gather_default_action_roles {
367 my ($self, %args) = @_;
369 push @roles, 'Catalyst::ActionRole::HTTPMethods'
370 if $args{attributes}->{Method};
372 push @roles, 'Catalyst::ActionRole::ConsumesContent'
373 if $args{attributes}->{Consumes};
375 push @roles, 'Catalyst::ActionRole::Scheme'
376 if $args{attributes}->{Scheme};
378 push @roles, 'Catalyst::ActionRole::QueryMatching'
379 if $args{attributes}->{Query};
384 my ( $self, $c, $name, @attrs ) = @_;
388 foreach my $attr (@attrs) {
390 # Parse out :Foo(bar) into Foo => bar etc (and arrayify)
392 if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+?)\s*\))?$/ ) )
395 if ( defined $value ) {
396 ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
398 push( @{ $raw_attributes{$key} }, $value );
402 my ($actions_config, $all_actions_config);
404 $actions_config = $self->_controller_actions;
405 # No, you're not getting actions => { '*' => ... } with actions in MyApp.
406 $all_actions_config = $self->_all_actions_attributes;
408 my $cfg = $self->config;
409 $actions_config = $self->merge_config_hashes($cfg->{actions}, $cfg->{action});
410 $all_actions_config = {};
415 # Note we deep copy array refs here to stop crapping on config
416 # when attributes are parsed. RT#65463
417 exists $actions_config->{$name} ? map { ref($_) eq 'ARRAY' ? [ @$_ ] : $_ } %{ $actions_config->{$name } } : (),
420 # Private actions with additional attributes will raise a warning and then
421 # be ignored. Adding '*' arguments to the default _DISPATCH / etc. methods,
422 # which are Private, will prevent those from being registered. They should
423 # probably be turned into :Actions instead, or we might want to otherwise
424 # disambiguate between those built-in internal actions and user-level
426 %raw_attributes = (%{ $all_actions_config }, %raw_attributes)
427 unless $raw_attributes{Private};
429 my %final_attributes;
431 while (my ($key, $value) = each %raw_attributes){
432 my $new_attrs = $self->_parse_attr($c, $name, $key => $value );
433 push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
436 return \%final_attributes;
440 my ($self, $c, $name, $key, $values) = @_;
442 my %final_attributes;
443 foreach my $value (ref($values) eq 'ARRAY' ? @$values : $values) {
444 my $meth = "_parse_${key}_attr";
445 if ( my $code = $self->can($meth) ) {
446 my %new_attrs = $self->$code( $c, $name, $value );
447 while (my ($new_key, $value) = each %new_attrs){
448 my $new_attrs = $key eq $new_key ?
449 { $new_key => [$value] } :
450 $self->_parse_attr($c, $name, $new_key => $value );
451 push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
455 push( @{ $final_attributes{$key} }, $value );
459 return \%final_attributes;
462 sub _parse_Global_attr {
463 my ( $self, $c, $name, $value ) = @_;
464 # _parse_attr will call _parse_Path_attr for us
465 return Path => "/$name";
468 sub _parse_Absolute_attr { shift->_parse_Global_attr(@_); }
470 sub _parse_Local_attr {
471 my ( $self, $c, $name, $value ) = @_;
472 # _parse_attr will call _parse_Path_attr for us
473 return Path => $name;
476 sub _parse_Relative_attr { shift->_parse_Local_attr(@_); }
478 sub _parse_Path_attr {
479 my ( $self, $c, $name, $value ) = @_;
480 $value = '' if !defined $value;
481 if ( $value =~ m!^/! ) {
482 return ( 'Path', $value );
484 elsif ( length $value ) {
485 return ( 'Path', join( '/', $self->path_prefix($c), $value ) );
488 return ( 'Path', $self->path_prefix($c) );
492 sub _parse_Chained_attr {
493 my ($self, $c, $name, $value) = @_;
495 if (defined($value) && length($value)) {
497 $value = '/'.$self->action_namespace($c);
498 } elsif (my ($rel, $rest) = $value =~ /^((?:\.{2}\/)+)(.*)$/) {
499 my @parts = split '/', $self->action_namespace($c);
500 my @levels = split '/', $rel;
502 $value = '/'.join('/', @parts[0 .. $#parts - @levels], $rest);
503 } elsif ($value !~ m/^\//) {
504 my $action_ns = $self->action_namespace($c);
507 $value = '/'.join('/', $action_ns, $value);
509 $value = '/'.$value; # special case namespace '' (root)
516 return Chained => $value;
519 sub _parse_ChainedParent_attr {
520 my ($self, $c, $name, $value) = @_;
521 return $self->_parse_Chained_attr($c, $name, '../'.$name);
524 sub _parse_PathPrefix_attr {
525 my ( $self, $c ) = @_;
526 return PathPart => $self->path_prefix($c);
529 sub _parse_ActionClass_attr {
530 my ( $self, $c, $name, $value ) = @_;
531 my $appname = $self->_application;
532 $value = Catalyst::Utils::resolve_namespace($appname . '::Action', $self->_action_class, $value);
533 return ( 'ActionClass', $value );
536 sub _parse_MyAction_attr {
537 my ( $self, $c, $name, $value ) = @_;
539 my $appclass = Catalyst::Utils::class2appclass($self);
540 $value = "+${appclass}::Action::${value}";
542 return ( 'ActionClass', $value );
545 sub _parse_Does_attr {
546 my ($self, $app, $name, $value) = @_;
547 return Does => $self->_expand_role_shortname($value);
550 sub _parse_GET_attr { Method => 'GET' }
551 sub _parse_POST_attr { Method => 'POST' }
552 sub _parse_PUT_attr { Method => 'PUT' }
553 sub _parse_DELETE_attr { Method => 'DELETE' }
554 sub _parse_OPTIONS_attr { Method => 'OPTIONS' }
555 sub _parse_HEAD_attr { Method => 'HEAD' }
556 sub _parse_PATCH_attr { Method => 'PATCH' }
558 sub _expand_role_shortname {
559 my ($self, @shortnames) = @_;
560 my $app = $self->_application;
562 my $prefix = $self->can('_action_role_prefix') ? $self->_action_role_prefix : ['Catalyst::ActionRole::'];
563 my @prefixes = (qq{${app}::ActionRole::}, @$prefix);
565 return String::RewritePrefix->rewrite(
567 my $loaded = load_first_existing_class(
568 map { "$_$_[0]" } @prefixes
570 return first { $loaded =~ /^$_/ }
571 sort { length $b <=> length $a } @prefixes;
579 __PACKAGE__->meta->make_immutable;
587 Like any other L<Catalyst::Component>, controllers have a config hash,
588 accessible through $self->config from the controller actions. Some
589 settings are in use by the Catalyst framework:
593 This specifies the internal namespace the controller should be bound
594 to. By default the controller is bound to the URI version of the
595 controller name. For instance controller 'MyApp::Controller::Foo::Bar'
596 will be bound to 'foo/bar'. The default Root controller is an example
597 of setting namespace to '' (the null string).
601 Sets 'path_prefix', as described below.
605 Allows you to set the attributes that the dispatcher creates actions out of.
606 This allows you to do 'rails style routes', or override some of the
607 attribute definitions of actions composed from Roles.
608 You can set arguments globally (for all actions of the controller) and
609 specifically (for a single action).
613 '*' => { Chained => 'base', Args => 0 },
614 base => { Chained => '/', PathPart => '', CaptureArgs => 0 },
618 In the case above every sub in the package would be made into a Chain
619 endpoint with a URI the same as the sub name for each sub, chained
620 to the sub named C<base>. Ergo dispatch to C</example> would call the
621 C<base> method, then the C<example> method.
625 Allows you to set constructor arguments on your actions. You can set arguments
626 globally and specifically (as above).
627 This is particularly useful when using C<ActionRole>s
628 (L<Catalyst::Controller::ActionRole>) and custom C<ActionClass>es.
632 '*' => { globalarg1 => 'hello', globalarg2 => 'goodbye' },
633 'specific_action' => { customarg => 'arg1' },
637 In the case above the action class associated with C<specific_action> would get
638 passed the following arguments, in addition to the normal action constructor
639 arguments, when it is instantiated:
641 (globalarg1 => 'hello', globalarg2 => 'goodbye', customarg => 'arg1')
645 =head2 BUILDARGS ($app, @args)
647 From L<Catalyst::Component::ApplicationAttribute>, stashes the application
648 instance as $self->_application.
650 =head2 $self->action_for('name')
652 Returns the Catalyst::Action object (if any) for a given method name
655 =head2 $self->action_namespace($c)
657 Returns the private namespace for actions in this component. Defaults
658 to a value from the controller name (for
659 e.g. MyApp::Controller::Foo::Bar becomes "foo/bar") or can be
660 overridden from the "namespace" config key.
663 =head2 $self->path_prefix($c)
665 Returns the default path prefix for :PathPrefix, :Local and
666 relative :Path actions in this component. Defaults to the action_namespace or
667 can be overridden from the "path" config key.
669 =head2 $self->register_actions($c)
671 Finds all applicable actions for this component, creates
672 Catalyst::Action objects (using $self->create_action) for them and
673 registers them with $c->dispatcher.
675 =head2 $self->get_action_methods()
677 Returns a list of L<Moose::Meta::Method> objects, doing the
678 L<MooseX::MethodAttributes::Role::Meta::Method> role, which are the set of
679 action methods for this package.
681 =head2 $self->register_action_methods($c, @methods)
683 Creates action objects for a set of action methods using C< create_action >,
684 and registers them with the dispatcher.
686 =head2 $self->action_class(%args)
688 Used when a controller is creating an action to determine the correct base
691 =head2 $self->create_action(%args)
693 Called with a hash of data to be use for construction of a new
694 Catalyst::Action (or appropriate sub/alternative class) object.
696 =head2 $self->gather_action_roles(\%action_args)
698 Gathers the list of roles to apply to an action with the given %action_args.
700 =head2 $self->gather_default_action_roles(\%action_args)
702 returns a list of action roles to be applied based on core, builtin rules.
703 Currently only the L<Catalyst::ActionRole::HTTPMethods> role is applied
706 =head2 $self->_application
710 Returns the application instance stored by C<new()>
712 =head1 ACTION SUBROUTINE ATTRIBUTES
714 Please see L<Catalyst::Manual::Intro> for more details
716 Think of action attributes as a sort of way to record metadata about an action,
717 similar to how annotations work in other languages you might have heard of.
718 Generally L<Catalyst> uses these to influence how the dispatcher sees your
719 action and when it will run it in response to an incoming request. They can
720 also be used for other things. Here's a summary, but you should refer to the
721 linked manual page for additional help.
725 sub homepage :Global { ... }
727 A global action defined in any controller always runs relative to your root.
728 So the above is the same as:
730 sub myaction :Path("/homepage") { ... }
734 Status: Deprecated alias to L</Global>.
738 Alias to "Path("$action_name"). The following two actions are the same:
740 sub myaction :Local { ... }
741 sub myaction :Path('myaction') { ... }
745 Status: Deprecated alias to L</Local>
749 Handle various types of paths:
751 package MyApp::Controller::Baz {
755 sub myaction1 :Path { ... } # -> /baz
756 sub myaction2 :Path('foo') { ... } # -> /baz/foo
757 sub myaction2 :Path('/bar') { ... } # -> /bar
760 This is a general toolbox for attaching your action to a given path.
767 B<Status: Deprecated.> Use Chained methods or other techniques.
768 If you really depend on this, install the standalone
769 L<Catalyst::DispatchType::Regex> distribution.
771 A global way to match a give regular expression in the incoming request path.
777 B<Status: Deprecated.> Use Chained methods or other techniques.
778 If you really depend on this, install the standalone
779 L<Catalyst::DispatchType::Regex> distribution.
781 Like L</Regex> but scoped under the namespace of the containing controller
793 Allowed values for CaptureArgs is a single integer (CaptureArgs(2), meaning two
794 allowed) or you can declare a L<Moose>, L<MooseX::Types> or L<Type::Tiny>
795 named constraint such as CaptureArgs(Int,Str) would require two args with
796 the first being a Integer and the second a string. You may declare your own
797 custom type constraints and import them into the controller namespace:
799 package MyApp::Controller::Root;
802 use MooseX::MethodAttributes;
803 use MyApp::Types qw/Int/;
805 extends 'Catalyst::Controller';
807 sub chain_base :Chained(/) CaptureArgs(1) { }
809 sub any_priority_chain :Chained(chain_base) PathPart('') Args(1) { }
811 sub int_priority_chain :Chained(chain_base) PathPart('') Args(Int) { }
813 See L<Catalyst::RouteMatching> for more.
815 Please see L<Catalyst::DispatchType::Chained> for more.
819 Set the base class for the action, defaults to L</Catalyst::Action>. It is now
820 preferred to use L</Does>.
824 Set the ActionClass using a custom Action in your project namespace.
826 The following is exactly the same:
828 sub foo_action1 : Local ActionClass('+MyApp::Action::Bar') { ... }
829 sub foo_action2 : Local MyAction('Bar') { ... }
833 package MyApp::Controller::Zoo;
835 sub foo : Local Does('Moo') { ... } # Catalyst::ActionRole::
836 sub bar : Local Does('~Moo') { ... } # MyApp::ActionRole::Moo
837 sub baz : Local Does('+MyApp::ActionRole::Moo') { ... }
855 Sets the give action path to match the specified HTTP method, or via one of the
856 broadly accepted methods of overriding the 'true' method (see
857 L<Catalyst::ActionRole::HTTPMethods>).
861 When used with L</Path> indicates the number of arguments expected in
862 the path. However if no Args value is set, assumed to 'slurp' all
863 remaining path pars under this namespace.
865 Allowed values for Args is a single integer (Args(2), meaning two allowed) or you
866 can declare a L<Moose>, L<MooseX::Types> or L<Type::Tiny> named constraint such
867 as Args(Int,Str) would require two args with the first being a Integer and the
868 second a string. You may declare your own custom type constraints and import
869 them into the controller namespace:
871 package MyApp::Controller::Root;
874 use MooseX::MethodAttributes;
875 use MyApp::Types qw/Tuple Int Str StrMatch UserId/;
877 extends 'Catalyst::Controller';
879 sub user :Local Args(UserId) {
880 my ($self, $c, $int) = @_;
883 sub an_int :Local Args(Int) {
884 my ($self, $c, $int) = @_;
887 sub many_ints :Local Args(ArrayRef[Int]) {
888 my ($self, $c, @ints) = @_;
891 sub match :Local Args(StrMatch[qr{\d\d-\d\d-\d\d}]) {
892 my ($self, $c, $int) = @_;
895 If you choose not to use imported type constraints (like L<Type::Tiny>, or <MooseX::Types>
896 you may use L<Moose> 'stringy' types however just like when you use these types in your
897 declared attributes you must quote them:
899 sub my_moose_type :Local Args('Int') { ... }
901 If you use 'reference' type constraints (such as ArrayRef[Int]) that have an unknown
902 number of allowed matches, we set this the same way "Args" is. Please keep in mind
903 that actions with an undetermined number of args match at lower precidence than those
904 with a fixed number. You may use reference types such as Tuple from L<Types::Standard>
905 that allows you to fix the number of allowed args. For example Args(Tuple[Int,Int])
906 would be determined to be two args (or really the same as Args(Int,Int).) You may
907 find this useful for creating custom subtypes with complex matching rules that you
908 wish to reuse over many actions.
910 See L<Catalyst::RouteMatching> for more.
912 =head2 Consumes('...')
914 Matches the current action against the content-type of the request. Typically
915 this is used when the request is a POST or PUT and you want to restrict the
916 submitted content type. For example, you might have an HTML for that either
917 returns classic url encoded form data, or JSON when Javascript is enabled. In
918 this case you may wish to match either incoming type to one of two different
919 actions, for properly processing.
923 sub is_json : Chained('start') Consumes('application/json') { ... }
924 sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
925 sub is_multipart : Chained('start') Consumes('multipart/form-data') { ... }
927 To reduce boilerplate, we include the following content type shortcuts:
931 sub is_json : Chained('start') Consume(JSON) { ... }
932 sub is_urlencoded : Chained('start') Consumes(UrlEncoded) { ... }
933 sub is_multipart : Chained('start') Consumes(Multipart) { ... }
935 You may specify more than one match:
939 : Consumes('application/x-www-form-urlencoded')
940 : Consumes('multipart/form-data')
944 : Consumes(UrlEncoded)
945 : Consumes(Multipart)
947 Since it is a common case the shortcut C<HTMLForm> matches both
948 'application/x-www-form-urlencoded' and 'multipart/form-data'. Here's the full
949 list of available shortcuts:
951 JSON => 'application/json',
952 JS => 'application/javascript',
953 PERL => 'application/perl',
956 Plain => 'text/plain',
957 UrlEncoded => 'application/x-www-form-urlencoded',
958 Multipart => 'multipart/form-data',
959 HTMLForm => ['application/x-www-form-urlencoded','multipart/form-data'],
961 Please keep in mind that when dispatching, L<Catalyst> will match the first most
962 relevant case, so if you use the C<Consumes> attribute, you should place your
963 most accurate matches early in the Chain, and your 'catchall' actions last.
965 See L<Catalyst::ActionRole::ConsumesContent> for more.
969 Allows you to specify a URI scheme for the action or action chain. For example
970 you can required that a given path be C<https> or that it is a websocket endpoint
971 C<ws> or C<wss>. For an action chain you may currently only have one defined
974 package MyApp::Controller::Root;
976 use base 'Catalyst::Controller';
978 sub is_http :Path(scheme) Scheme(http) Args(0) {
980 $c->response->body("is_http");
983 sub is_https :Path(scheme) Scheme(https) Args(0) {
985 $c->response->body("is_https");
988 In the above example http://localhost/root/scheme would match the first
989 action (is_http) but https://localhost/root/scheme would match the second.
991 As an added benefit, if an action or action chain defines a Scheme, when using
992 $c->uri_for the scheme of the generated URL will use what you define in the action
993 or action chain (the current behavior is to set the scheme based on the current
994 incoming request). This makes it easier to use uri_for on websites where some
995 paths are secure and others are not. You may also use this to other schemes
998 See L<Catalyst::ActionRole::Scheme> for more.
1000 =head1 OPTIONAL METHODS
1002 =head2 _parse_[$name]_attr
1004 Allows you to customize parsing of subroutine attributes.
1006 sub myaction1 :Path TwoArgs { ... }
1008 sub _parse_TwoArgs_attr {
1009 my ( $self, $c, $name, $value ) = @_;
1010 # $self -> controller instance
1015 Please note that this feature does not let you actually assign new functions
1016 to actions via subroutine attributes, but is really more for creating useful
1017 aliases to existing core and extended attributes, and transforms based on
1018 existing information (like from configuration). Code for actually doing
1019 something meaningful with the subroutine attributes will be located in the
1020 L<Catalyst::Action> classes (or your subclasses), L<Catalyst::Dispatcher> and
1021 in subclasses of L<Catalyst::DispatchType>. Remember these methods only get
1022 called basically once when the application is starting, not per request!
1026 Catalyst Contributors, see Catalyst.pm
1030 This library is free software. You can redistribute it and/or modify
1031 it under the same terms as Perl itself.