Merge branch 'master' into gsoc_breadboard
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Controller.pm
CommitLineData
5ee249f2 1package Catalyst::Controller;
2
ae29b412 3use Moose;
eff60019 4use Class::MOP;
c6392ad5 5use Class::Load ':all';
eff60019 6use String::RewritePrefix;
a58af53d 7use Moose::Util qw/find_meta/;
eff60019 8use List::Util qw/first/;
4f4ab5b4 9use List::MoreUtils qw/uniq/;
ae29b412 10use namespace::clean -except => 'meta';
11
ba545c13 12BEGIN { extends qw/Catalyst::Component MooseX::MethodAttributes::Inheritable/; }
234763d4 13
cf37d21a 14use MooseX::MethodAttributes;
234763d4 15use Catalyst::Exception;
16use Catalyst::Utils;
ae29b412 17
18with 'Catalyst::Component::ApplicationAttribute';
19
aea897b2 20has path_prefix => (
21 is => 'rw',
22 isa => 'Str',
23 init_arg => 'path',
24 predicate => 'has_path_prefix',
25);
ae29b412 26
aea897b2 27has action_namespace => (
28 is => 'rw',
29 isa => 'Str',
30 init_arg => 'namespace',
31 predicate => 'has_action_namespace',
32);
ae29b412 33
aea897b2 34has actions => (
35 accessor => '_controller_actions',
36 isa => 'HashRef',
37 init_arg => undef,
38);
ae29b412 39
eff60019 40has _action_role_args => (
41 traits => [qw(Array)],
42 isa => 'ArrayRef[Str]',
43 init_arg => 'action_roles',
44 default => sub { [] },
45 handles => {
46 _action_role_args => 'elements',
47 },
48);
49
50has _action_roles => (
51 traits => [qw(Array)],
52 isa => 'ArrayRef[RoleName]',
53 init_arg => undef,
54 lazy => 1,
55 builder => '_build__action_roles',
56 handles => {
57 _action_roles => 'elements',
58 },
59);
60
bf7c9c87 61has action_args => (is => 'ro');
ae29b412 62
bdd6684e 63# ->config(actions => { '*' => ...
64has _all_actions_attributes => (
65 is => 'ro',
66 isa => 'HashRef',
67 init_arg => undef,
68 lazy => 1,
69 builder => '_build__all_actions_attributes',
70);
71
7f22a5aa 72sub BUILD {
73 my ($self, $args) = @_;
ae29b412 74 my $action = delete $args->{action} || {};
75 my $actions = delete $args->{actions} || {};
7f22a5aa 76 my $attr_value = $self->merge_config_hashes($actions, $action);
77 $self->_controller_actions($attr_value);
5ee249f2 78
bdd6684e 79 # trigger lazy builder
80 $self->_all_actions_attributes;
eff60019 81 $self->_action_roles;
82}
83
84sub _build__action_roles {
85 my $self = shift;
86 my @roles = $self->_expand_role_shortname($self->_action_role_args);
c6392ad5 87 load_class($_) for @roles;
eff60019 88 return \@roles;
bdd6684e 89}
d0e5dfb5 90
bdd6684e 91sub _build__all_actions_attributes {
92 my ($self) = @_;
93 delete $self->_controller_actions->{'*'} || {};
94}
d0e5dfb5 95
5ee249f2 96=head1 NAME
97
98Catalyst::Controller - Catalyst Controller base class
99
100=head1 SYNOPSIS
101
234763d4 102 package MyApp::Controller::Search
a269e0c2 103 use base qw/Catalyst::Controller/;
234763d4 104
27ae4114 105 sub foo : Local {
85d9fce6 106 my ($self,$c,@args) = @_;
27ae4114 107 ...
234763d4 108 } # Dispatches to /search/foo
5ee249f2 109
110=head1 DESCRIPTION
111
a269e0c2 112Controllers are where the actions in the Catalyst framework
113reside. Each action is represented by a function with an attribute to
114identify what kind of action it is. See the L<Catalyst::Dispatcher>
115for more info about how Catalyst dispatches to actions.
234763d4 116
117=cut
118
ae29b412 119#I think both of these could be attributes. doesn't really seem like they need
120#to ble class data. i think that attributes +default would work just fine
eff60019 121__PACKAGE__->mk_classdata($_) for qw/_dispatch_steps _action_class _action_role_prefix/;
234763d4 122
123__PACKAGE__->_dispatch_steps( [qw/_BEGIN _AUTO _ACTION/] );
7b41db70 124__PACKAGE__->_action_class('Catalyst::Action');
eff60019 125__PACKAGE__->_action_role_prefix([ 'Catalyst::ActionRole::' ]);
234763d4 126
234763d4 127
128sub _DISPATCH : Private {
129 my ( $self, $c ) = @_;
130
131 foreach my $disp ( @{ $self->_dispatch_steps } ) {
132 last unless $c->forward($disp);
133 }
134
135 $c->forward('_END');
136}
137
138sub _BEGIN : Private {
139 my ( $self, $c ) = @_;
140 my $begin = ( $c->get_actions( 'begin', $c->namespace ) )[-1];
141 return 1 unless $begin;
142 $begin->dispatch( $c );
143 return !@{ $c->error };
144}
145
146sub _AUTO : Private {
147 my ( $self, $c ) = @_;
148 my @auto = $c->get_actions( 'auto', $c->namespace );
149 foreach my $auto (@auto) {
150 $auto->dispatch( $c );
151 return 0 unless $c->state;
152 }
153 return 1;
154}
155
156sub _ACTION : Private {
157 my ( $self, $c ) = @_;
158 if ( ref $c->action
159 && $c->action->can('execute')
53119b78 160 && defined $c->req->action )
234763d4 161 {
162 $c->action->dispatch( $c );
163 }
164 return !@{ $c->error };
165}
166
167sub _END : Private {
168 my ( $self, $c ) = @_;
169 my $end = ( $c->get_actions( 'end', $c->namespace ) )[-1];
170 return 1 unless $end;
171 $end->dispatch( $c );
172 return !@{ $c->error };
173}
174
234763d4 175sub action_for {
176 my ( $self, $name ) = @_;
177 my $app = ($self->isa('Catalyst') ? $self : $self->_application);
178 return $app->dispatcher->get_action($name, $self->action_namespace);
179}
180
27ae4114 181#my opinion is that this whole sub really should be a builder method, not
ae29b412 182#something that happens on every call. Anyone else disagree?? -- groditi
183## -- apparently this is all just waiting for app/ctx split
184around action_namespace => sub {
185 my $orig = shift;
234763d4 186 my ( $self, $c ) = @_;
ae29b412 187
df960201 188 my $class = ref($self) || $self;
189 my $appclass = ref($c) || $c;
b527cc7d 190
191 # FIXME - catalyst_component_name is no longer a class accessor, because
192 # 'MyApp as a controller' behavior is removed. But is this call to
193 # catalyst_component_name necessary, or is it always the same as $class?
194 my $component_name = ref($self) ? $self->catalyst_component_name : $self;
195
ae29b412 196 if( ref($self) ){
197 return $self->$orig if $self->has_action_namespace;
198 } else {
df960201 199 return $class->config->{namespace} if exists $class->config->{namespace};
234763d4 200 }
234763d4 201
ae29b412 202 my $case_s;
203 if( $c ){
df960201 204 $case_s = $appclass->config->{case_sensitive};
ae29b412 205 } else {
206 if ($self->isa('Catalyst')) {
df960201 207 $case_s = $class->config->{case_sensitive};
ae29b412 208 } else {
209 if (ref $self) {
df960201 210 $case_s = ref($self->_application)->config->{case_sensitive};
ae29b412 211 } else {
212 confess("Can't figure out case_sensitive setting");
213 }
214 }
234763d4 215 }
ae29b412 216
b527cc7d 217 my $namespace = Catalyst::Utils::class2prefix($component_name, $case_s) || '';
ae29b412 218 $self->$orig($namespace) if ref($self);
219 return $namespace;
220};
221
222#Once again, this is probably better written as a builder method
223around path_prefix => sub {
224 my $orig = shift;
225 my $self = shift;
226 if( ref($self) ){
227 return $self->$orig if $self->has_path_prefix;
228 } else {
229 return $self->config->{path} if exists $self->config->{path};
230 }
231 my $namespace = $self->action_namespace(@_);
232 $self->$orig($namespace) if ref($self);
233 return $namespace;
234};
234763d4 235
9ab7d83d 236sub get_action_methods {
237 my $self = shift;
2bf074ab 238 my $meta = find_meta($self) || confess("No metaclass setup for $self");
69048792 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');
cf37d21a 243 my @methods = $meta->get_nearest_methods_with_attributes;
fa649eb7 244
245 # actions specified via config are also action_methods
246 push(
247 @methods,
248 map {
d0e78355 249 $meta->find_method_by_name($_)
e87273a4 250 || confess( sprintf 'Action "%s" is not available from controller %s',
251 $_, ref $self )
bdd6684e 252 } keys %{ $self->_controller_actions }
fa649eb7 253 ) if ( ref $self );
4f4ab5b4 254 return uniq @methods;
9ab7d83d 255}
234763d4 256
fa649eb7 257
234763d4 258sub register_actions {
259 my ( $self, $c ) = @_;
9ab7d83d 260 $self->register_action_methods( $c, $self->get_action_methods );
261}
262
263sub register_action_methods {
264 my ( $self, $c, @methods ) = @_;
8f6cebb2 265 my $class = $self->catalyst_component_name;
ae29b412 266 #this is still not correct for some reason.
234763d4 267 my $namespace = $self->action_namespace($c);
234763d4 268
f3c5b1c9 269 # FIXME - fugly
a202886b 270 if (!blessed($self) && $self eq $c && scalar(@methods)) {
f3c5b1c9 271 my @really_bad_methods = grep { ! /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/ } map { $_->name } @methods;
272 if (scalar(@really_bad_methods)) {
273 $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 }
a202886b 275 }
d2598ac8 276
ba545c13 277 foreach my $method (@methods) {
278 my $name = $method->name;
d0f30dbc 279 # Horrible hack! All method metaclasses should have an attributes
280 # method, core Moose bug - see r13354.
10e970e4 281 my $attributes = $method->can('attributes') ? $method->attributes : [];
ba545c13 282 my $attrs = $self->_parse_attrs( $c, $name, @{ $attributes } );
234763d4 283 if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
284 $c->log->debug( 'Bad action definition "'
ba545c13 285 . join( ' ', @{ $attributes } )
286 . qq/" for "$class->$name"/ )
234763d4 287 if $c->debug;
288 next;
289 }
bc677969 290 my $reverse = $namespace ? "${namespace}/${name}" : $name;
234763d4 291 my $action = $self->create_action(
ba545c13 292 name => $name,
293 code => $method->body,
234763d4 294 reverse => $reverse,
295 namespace => $namespace,
296 class => $class,
297 attributes => $attrs,
298 );
299
300 $c->dispatcher->register( $c, $action );
301 }
302}
303
eff60019 304sub _apply_action_class_roles {
305 my ($self, $class, @roles) = @_;
306
c6392ad5 307 load_class($_) for @roles;
eff60019 308 my $meta = Moose::Meta::Class->initialize($class)->create_anon_class(
309 superclasses => [$class],
310 roles => \@roles,
311 cache => 1,
312 );
313 $meta->add_method(meta => sub { $meta });
314
315 return $meta->name;
316}
317
f0a9b791 318sub action_class {
7b41db70 319 my $self = shift;
320 my %args = @_;
234763d4 321
322 my $class = (exists $args{attributes}{ActionClass}
f0a9b791 323 ? $args{attributes}{ActionClass}[0]
324 : $self->_action_class);
325
ae29b412 326 Class::MOP::load_class($class);
f0a9b791 327 return $class;
328}
329
330sub create_action {
331 my $self = shift;
332 my %args = @_;
a7e955ae 333
f0a9b791 334 my $class = $self->action_class(%args);
eff60019 335
336 load_class($class);
337 Moose->init_meta(for_class => $class)
338 unless Class::MOP::does_metaclass_exist($class);
339
340 unless ($args{name} =~ /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/) {
341 my @roles = $self->gather_action_roles(%args);
342 $class = $self->_apply_action_class_roles($class, @roles) if @roles;
343 }
344
bf7c9c87 345 my $action_args = (
346 ref($self)
347 ? $self->action_args
348 : $self->config->{action_args}
349 );
f0a9b791 350
a7e955ae 351 my %extra_args = (
352 %{ $action_args->{'*'} || {} },
353 %{ $action_args->{ $args{name} } || {} },
354 );
355
356 return $class->new({ %extra_args, %args });
234763d4 357}
358
eff60019 359sub gather_action_roles {
360 my ($self, %args) = @_;
361
362 return (
363 (blessed $self ? $self->_action_roles : ()),
364 @{ $args{attributes}->{Does} || [] },
365 );
366}
367
234763d4 368sub _parse_attrs {
369 my ( $self, $c, $name, @attrs ) = @_;
370
371 my %raw_attributes;
372
373 foreach my $attr (@attrs) {
374
375 # Parse out :Foo(bar) into Foo => bar etc (and arrayify)
376
377 if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+?)\s*\))?$/ ) )
378 {
379
380 if ( defined $value ) {
381 ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
382 }
383 push( @{ $raw_attributes{$key} }, $value );
384 }
385 }
386
bdd6684e 387 my ($actions_config, $all_actions_config);
ae29b412 388 if( ref($self) ) {
bdd6684e 389 $actions_config = $self->_controller_actions;
390 # No, you're not getting actions => { '*' => ... } with actions in MyApp.
391 $all_actions_config = $self->_all_actions_attributes;
ae29b412 392 } else {
393 my $cfg = $self->config;
bdd6684e 394 $actions_config = $self->merge_config_hashes($cfg->{actions}, $cfg->{action});
395 $all_actions_config = {};
234763d4 396 }
397
ed9d06b6 398 %raw_attributes = (
399 %raw_attributes,
e95b2b49 400 # Note we deep copy array refs here to stop crapping on config
401 # when attributes are parsed. RT#65463
402 exists $actions_config->{$name} ? map { ref($_) eq 'ARRAY' ? [ @$_ ] : $_ } %{ $actions_config->{$name } } : (),
ed9d06b6 403 );
ae29b412 404
ed9d06b6 405 # Private actions with additional attributes will raise a warning and then
406 # be ignored. Adding '*' arguments to the default _DISPATCH / etc. methods,
407 # which are Private, will prevent those from being registered. They should
408 # probably be turned into :Actions instead, or we might want to otherwise
409 # disambiguate between those built-in internal actions and user-level
410 # Private ones.
bdd6684e 411 %raw_attributes = (%{ $all_actions_config }, %raw_attributes)
412 unless $raw_attributes{Private};
ae29b412 413
234763d4 414 my %final_attributes;
415
0b0aee67 416 while (my ($key, $value) = each %raw_attributes){
417 my $new_attrs = $self->_parse_attr($c, $name, $key => $value );
418 push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
419 }
234763d4 420
0b0aee67 421 return \%final_attributes;
422}
234763d4 423
0b0aee67 424sub _parse_attr {
425 my ($self, $c, $name, $key, $values) = @_;
234763d4 426
0b0aee67 427 my %final_attributes;
428 foreach my $value (ref($values) eq 'ARRAY' ? @$values : $values) {
429 my $meth = "_parse_${key}_attr";
430 if ( my $code = $self->can($meth) ) {
431 my %new_attrs = $self->$code( $c, $name, $value );
432 while (my ($new_key, $value) = each %new_attrs){
433 my $new_attrs = $key eq $new_key ?
434 { $new_key => [$value] } :
435 $self->_parse_attr($c, $name, $new_key => $value );
436 push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
234763d4 437 }
0b0aee67 438 }
439 else {
234763d4 440 push( @{ $final_attributes{$key} }, $value );
441 }
442 }
443
444 return \%final_attributes;
445}
446
447sub _parse_Global_attr {
448 my ( $self, $c, $name, $value ) = @_;
0b0aee67 449 # _parse_attr will call _parse_Path_attr for us
450 return Path => "/$name";
234763d4 451}
452
453sub _parse_Absolute_attr { shift->_parse_Global_attr(@_); }
454
455sub _parse_Local_attr {
456 my ( $self, $c, $name, $value ) = @_;
0b0aee67 457 # _parse_attr will call _parse_Path_attr for us
458 return Path => $name;
234763d4 459}
460
461sub _parse_Relative_attr { shift->_parse_Local_attr(@_); }
462
463sub _parse_Path_attr {
464 my ( $self, $c, $name, $value ) = @_;
53119b78 465 $value = '' if !defined $value;
234763d4 466 if ( $value =~ m!^/! ) {
467 return ( 'Path', $value );
468 }
469 elsif ( length $value ) {
470 return ( 'Path', join( '/', $self->path_prefix($c), $value ) );
471 }
472 else {
473 return ( 'Path', $self->path_prefix($c) );
474 }
475}
476
477sub _parse_Regex_attr {
478 my ( $self, $c, $name, $value ) = @_;
479 return ( 'Regex', $value );
480}
481
482sub _parse_Regexp_attr { shift->_parse_Regex_attr(@_); }
483
484sub _parse_LocalRegex_attr {
485 my ( $self, $c, $name, $value ) = @_;
486 unless ( $value =~ s/^\^// ) { $value = "(?:.*?)$value"; }
19c01ee1 487
488 my $prefix = $self->path_prefix( $c );
489 $prefix .= '/' if length( $prefix );
27ae4114 490
19c01ee1 491 return ( 'Regex', "^${prefix}${value}" );
234763d4 492}
493
494sub _parse_LocalRegexp_attr { shift->_parse_LocalRegex_attr(@_); }
495
f3107403 496sub _parse_Chained_attr {
497 my ($self, $c, $name, $value) = @_;
498
499 if (defined($value) && length($value)) {
500 if ($value eq '.') {
501 $value = '/'.$self->action_namespace($c);
fb56008f 502 } elsif (my ($rel, $rest) = $value =~ /^((?:\.{2}\/)+)(.*)$/) {
eb270c30 503 my @parts = split '/', $self->action_namespace($c);
fb56008f 504 my @levels = split '/', $rel;
505
506 $value = '/'.join('/', @parts[0 .. $#parts - @levels], $rest);
f3107403 507 } elsif ($value !~ m/^\//) {
508 my $action_ns = $self->action_namespace($c);
509
510 if ($action_ns) {
511 $value = '/'.join('/', $action_ns, $value);
512 } else {
513 $value = '/'.$value; # special case namespace '' (root)
514 }
515 }
516 } else {
517 $value = '/'
518 }
519
520 return Chained => $value;
521}
522
9356b981 523sub _parse_ChainedParent_attr {
524 my ($self, $c, $name, $value) = @_;
525 return $self->_parse_Chained_attr($c, $name, '../'.$name);
526}
527
e5d2cfdb 528sub _parse_PathPrefix_attr {
02825551 529 my ( $self, $c ) = @_;
530 return PathPart => $self->path_prefix($c);
e5d2cfdb 531}
532
234763d4 533sub _parse_ActionClass_attr {
534 my ( $self, $c, $name, $value ) = @_;
5d8129e9 535 my $appname = $self->_application;
536 $value = Catalyst::Utils::resolve_namespace($appname . '::Action', $self->_action_class, $value);
234763d4 537 return ( 'ActionClass', $value );
538}
539
9287719b 540sub _parse_MyAction_attr {
541 my ( $self, $c, $name, $value ) = @_;
542
543 my $appclass = Catalyst::Utils::class2appclass($self);
0b0aee67 544 $value = "+${appclass}::Action::${value}";
234763d4 545
9287719b 546 return ( 'ActionClass', $value );
547}
234763d4 548
eff60019 549sub _parse_Does_attr {
550 my ($self, $app, $name, $value) = @_;
551 return Does => $self->_expand_role_shortname($value);
552}
553
554sub _expand_role_shortname {
555 my ($self, @shortnames) = @_;
556 my $app = $self->_application;
557
558 my $prefix = $self->can('_action_role_prefix') ? $self->_action_role_prefix : ['Catalyst::ActionRole::'];
559 my @prefixes = (qq{${app}::ActionRole::}, @$prefix);
560
561 return String::RewritePrefix->rewrite(
562 { '' => sub {
c6392ad5 563 my $loaded = load_first_existing_class(
eff60019 564 map { "$_$_[0]" } @prefixes
565 );
566 return first { $loaded =~ /^$_/ }
567 sort { length $b <=> length $a } @prefixes;
568 },
569 '~' => $prefixes[0],
570 '+' => '' },
571 @shortnames,
572 );
573}
574
ae29b412 575__PACKAGE__->meta->make_immutable;
576
234763d4 5771;
578
579__END__
580
581=head1 CONFIGURATION
582
a269e0c2 583Like any other L<Catalyst::Component>, controllers have a config hash,
584accessible through $self->config from the controller actions. Some
585settings are in use by the Catalyst framework:
234763d4 586
587=head2 namespace
588
a269e0c2 589This specifies the internal namespace the controller should be bound
590to. By default the controller is bound to the URI version of the
591controller name. For instance controller 'MyApp::Controller::Foo::Bar'
592will be bound to 'foo/bar'. The default Root controller is an example
593of setting namespace to '' (the null string).
234763d4 594
27ae4114 595=head2 path
234763d4 596
597Sets 'path_prefix', as described below.
598
0a2577a8 599=head2 action
600
601Allows you to set the attributes that the dispatcher creates actions out of.
602This allows you to do 'rails style routes', or override some of the
f4dda4a8 603attribute definitions of actions composed from Roles.
0a2577a8 604You can set arguments globally (for all actions of the controller) and
605specifically (for a single action).
606
607 __PACKAGE__->config(
608 action => {
609 '*' => { Chained => 'base', Args => 0 },
610 base => { Chained => '/', PathPart => '', CaptureArgs => 0 },
611 },
612 );
613
614In the case above every sub in the package would be made into a Chain
615endpoint with a URI the same as the sub name for each sub, chained
616to the sub named C<base>. Ergo dispatch to C</example> would call the
617C<base> method, then the C<example> method.
618
c8136648 619=head2 action_args
620
4d4e5de8 621Allows you to set constructor arguments on your actions. You can set arguments
0a2577a8 622globally and specifically (as above).
623This is particularly useful when using C<ActionRole>s
b939ae6b 624(L<Catalyst::Controller::ActionRole>) and custom C<ActionClass>es.
c8136648 625
b939ae6b 626 __PACKAGE__->config(
c8136648 627 action_args => {
b939ae6b 628 '*' => { globalarg1 => 'hello', globalarg2 => 'goodbye' },
629 'specific_action' => { customarg => 'arg1' },
cea3f28a 630 },
b939ae6b 631 );
cea3f28a 632
b939ae6b 633In the case above the action class associated with C<specific_action> would get
634passed the following arguments, in addition to the normal action constructor
635arguments, when it is instantiated:
636
637 (globalarg1 => 'hello', globalarg2 => 'goodbye', customarg => 'arg1')
c8136648 638
234763d4 639=head1 METHODS
640
c4d02967 641=head2 BUILDARGS ($app, @args)
234763d4 642
c4d02967 643From L<Catalyst::Component::ApplicationAttribute>, stashes the application
644instance as $self->_application.
234763d4 645
646=head2 $self->action_for('name')
647
a269e0c2 648Returns the Catalyst::Action object (if any) for a given method name
649in this component.
234763d4 650
234763d4 651=head2 $self->action_namespace($c)
652
a269e0c2 653Returns the private namespace for actions in this component. Defaults
654to a value from the controller name (for
655e.g. MyApp::Controller::Foo::Bar becomes "foo/bar") or can be
656overridden from the "namespace" config key.
234763d4 657
658
659=head2 $self->path_prefix($c)
660
e5d2cfdb 661Returns the default path prefix for :PathPrefix, :Local, :LocalRegex and
662relative :Path actions in this component. Defaults to the action_namespace or
a269e0c2 663can be overridden from the "path" config key.
234763d4 664
c4d02967 665=head2 $self->register_actions($c)
666
667Finds all applicable actions for this component, creates
668Catalyst::Action objects (using $self->create_action) for them and
669registers them with $c->dispatcher.
670
671=head2 $self->get_action_methods()
672
673Returns a list of L<Moose::Meta::Method> objects, doing the
674L<MooseX::MethodAttributes::Role::Meta::Method> role, which are the set of
675action methods for this package.
676
677=head2 $self->register_action_methods($c, @methods)
678
679Creates action objects for a set of action methods using C< create_action >,
680and registers them with the dispatcher.
681
f0a9b791 682=head2 $self->action_class(%args)
683
684Used when a controller is creating an action to determine the correct base
24d2dfaf 685action class to use.
f0a9b791 686
234763d4 687=head2 $self->create_action(%args)
688
a269e0c2 689Called with a hash of data to be use for construction of a new
690Catalyst::Action (or appropriate sub/alternative class) object.
234763d4 691
eff60019 692=head2 $self->gather_action_roles(\%action_args)
693
694Gathers the list of roles to apply to an action with the given %action_args.
695
a269e0c2 696=head2 $self->_application
234763d4 697
698=head2 $self->_app
699
700Returns the application instance stored by C<new()>
5ee249f2 701
0bf7ab71 702=head1 AUTHORS
5ee249f2 703
0bf7ab71 704Catalyst Contributors, see Catalyst.pm
5ee249f2 705
706=head1 COPYRIGHT
707
536bee89 708This library is free software. You can redistribute it and/or modify
a269e0c2 709it under the same terms as Perl itself.
5ee249f2 710
711=cut