Agreed
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Controller.pm
index c738f9e..99c5f29 100644 (file)
@@ -225,7 +225,9 @@ sub register_action_methods {
 
     foreach my $method (@methods) {
         my $name = $method->name;
-        my $attributes = $method->attributes;
+        # Horrible hack! All method metaclasses should have an attributes
+        # method, core Moose bug - see r13354.
+        my $attributes = $method->can('attributes') ? $method->attributes : [];
         my $attrs = $self->_parse_attrs( $c, $name, @{ $attributes } );
         if ( $attrs->{Private} && ( keys %$attrs > 1 ) ) {
             $c->log->debug( 'Bad action definition "'
@@ -248,16 +250,25 @@ sub register_action_methods {
     }
 }
 
-sub create_action {
+sub action_class {
     my $self = shift;
     my %args = @_;
 
     my $class = (exists $args{attributes}{ActionClass}
-                    ? $args{attributes}{ActionClass}[0]
-                    : $self->_action_class);
+        ? $args{attributes}{ActionClass}[0]
+        : $self->_action_class);
+
     Class::MOP::load_class($class);
+    return $class;
+}
+
+sub create_action {
+    my $self = shift;
+    my %args = @_;
 
+    my $class = $self->action_class(%args);
     my $action_args = $self->config->{action_args};
+
     my %extra_args = (
         %{ $action_args->{'*'}           || {} },
         %{ $action_args->{ $args{name} } || {} },
@@ -285,11 +296,6 @@ sub _parse_attrs {
         }
     }
 
-    #I know that the original behavior was to ignore action if actions was set
-    # but i actually think this may be a little more sane? we can always remove
-    # the merge behavior quite easily and go back to having actions have
-    # presedence over action by modifying the keys. i honestly think this is
-    # superior while mantaining really high degree of compat
     my $actions;
     if( ref($self) ) {
         $actions = $self->_controller_actions;
@@ -446,22 +452,45 @@ of setting namespace to '' (the null string).
 
 Sets 'path_prefix', as described below.
 
+=head2 action
+
+Allows you to set the attributes that the dispatcher creates actions out of.
+This allows you to do 'rails style routes', or override some of the
+attribute defintions of actions composed from Roles.
+You can set arguments globally (for all actions of the controller) and
+specifically (for a single action).
+
+    __PACKAGE__->config(
+        action => {
+            '*' => { Chained => 'base', Args => 0  },
+            base => { Chained => '/', PathPart => '', CaptureArgs => 0 },
+        },
+     );
+
+In the case above every sub in the package would be made into a Chain
+endpoint with a URI the same as the sub name for each sub, chained
+to the sub named C<base>. Ergo dispatch to C</example> would call the
+C<base> method, then the C<example> method.
+
 =head2 action_args
 
-Allows you to set constructor arguments on your Actions or ActionRoles.  You can
-set args globally (all actions of the controller) and specifically (for a single
-action).
+Allows you to set constructor arguments on your actions. You can set arguments
+globally and specifically (as above).
+This is particularly useful when using C<ActionRole>s
+(L<Catalyst::Controller::ActionRole>) and custom C<ActionClass>es.
 
-    __PACKAGE__->config({
+    __PACKAGE__->config(
         action_args => {
-            '*' => {globalarg1=>'hello', globalarg2=>'goodbye'},
-            'specific_action' => {customarg=>'arg1'},
+            '*' => { globalarg1 => 'hello', globalarg2 => 'goodbye' },
+            'specific_action' => { customarg => 'arg1' },
         },
-     });
+     );
+
+In the case above the action class associated with C<specific_action> would get
+passed the following arguments, in addition to the normal action constructor
+arguments, when it is instantiated:
 
-In the case above the action class associated with 'specific_action' would get
-passed the following arguments when it is instantiated: (globalarg1=>'hello',
-globalarg2=>'goodbye', 'customarg=>'arg1').
+  (globalarg1 => 'hello', globalarg2 => 'goodbye', customarg => 'arg1')
 
 =head1 METHODS
 
@@ -506,6 +535,11 @@ action methods for this package.
 Creates action objects for a set of action methods using C< create_action >,
 and registers them with the dispatcher.
 
+=head2 $self->action_class(%args)
+
+Used when a controller is creating an action to determine the correct base
+action class to use.
+
 =head2 $self->create_action(%args)
 
 Called with a hash of data to be use for construction of a new