Catalyst-Runtime

 view release on metacpan or  search on metacpan

lib/Catalyst/Controller.pm  view on Meta::CPAN

    my ($self, @shortnames) = @_;
    my $app = $self->_application;

    my $prefix = $self->can('_action_role_prefix') ? $self->_action_role_prefix : ['Catalyst::ActionRole::'];
    my @prefixes = (qq{${app}::ActionRole::}, @$prefix);

    return String::RewritePrefix->rewrite(
        { ''  => sub {
            my $loaded = load_first_existing_class(
                map { "$_$_[0]" } @prefixes
            );
            return first { $loaded =~ /^$_/ }
              sort { length $b <=> length $a } @prefixes;
          },
          '~' => $prefixes[0],
          '+' => '' },
        @shortnames,
    );
}

__PACKAGE__->meta->make_immutable;

1;

__END__

=head1 CONFIGURATION

Like any other L<Catalyst::Component>, controllers have a config hash,
accessible through $self->config from the controller actions.  Some
settings are in use by the Catalyst framework:

=head2 namespace

This specifies the internal namespace the controller should be bound
to. By default the controller is bound to the URI version of the
controller name. For instance controller 'MyApp::Controller::Foo::Bar'
will be bound to 'foo/bar'. The default Root controller is an example
of setting namespace to '' (the null string).

=head2 path

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 definitions 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. 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(
        action_args => {
            '*' => { 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:

  (globalarg1 => 'hello', globalarg2 => 'goodbye', customarg => 'arg1')

=head1 METHODS

=head2 BUILDARGS ($app, @args)

From L<Catalyst::Component::ApplicationAttribute>, stashes the application
instance as $self->_application.

=head2 $self->action_for($action_name)

Returns the Catalyst::Action object (if any) for a given action in this
controller or relative to it.  You may refer to actions in controllers
nested under the current controllers namespace, or in controllers 'up'
from the current controller namespace.  For example:

    package MyApp::Controller::One::Two;
    use base 'Catalyst::Controller';

    sub foo :Local {
      my ($self, $c) = @_;
      $self->action_for('foo'); # action 'foo' in Controller 'One::Two'
      $self->action_for('three/bar'); # action 'bar' in Controller 'One::Two::Three'
      $self->action_for('../boo'); # action 'boo' in Controller 'One'
    }

This returns 'undef' if there is no action matching the requested action
name (after any path normalization) so you should check for this as needed.

=head2 $self->action_namespace($c)

Returns the private namespace for actions in this component. Defaults
to a value from the controller name (for
e.g. MyApp::Controller::Foo::Bar becomes "foo/bar") or can be
overridden from the "namespace" config key.


=head2 $self->path_prefix($c)

lib/Catalyst/Controller.pm  view on Meta::CPAN

do more and better types of introspection driving tests and debugging.

=head2 Consumes('...')

Matches the current action against the content-type of the request.  Typically
this is used when the request is a POST or PUT and you want to restrict the
submitted content type.  For example, you might have an HTML for that either
returns classic url encoded form data, or JSON when Javascript is enabled.  In
this case you may wish to match either incoming type to one of two different
actions, for properly processing.

Examples:

    sub is_json       : Chained('start') Consumes('application/json') { ... }
    sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
    sub is_multipart  : Chained('start') Consumes('multipart/form-data') { ... }

To reduce boilerplate, we include the following content type shortcuts:

Examples

      sub is_json       : Chained('start') Consume(JSON) { ... }
      sub is_urlencoded : Chained('start') Consumes(UrlEncoded) { ... }
      sub is_multipart  : Chained('start') Consumes(Multipart) { ... }

You may specify more than one match:

      sub is_more_than_one
        : Chained('start')
        : Consumes('application/x-www-form-urlencoded')
        : Consumes('multipart/form-data')

      sub is_more_than_one
        : Chained('start')
        : Consumes(UrlEncoded)
        : Consumes(Multipart)

Since it is a common case the shortcut C<HTMLForm> matches both
'application/x-www-form-urlencoded' and 'multipart/form-data'.  Here's the full
list of available shortcuts:

    JSON => 'application/json',
    JS => 'application/javascript',
    PERL => 'application/perl',
    HTML => 'text/html',
    XML => 'text/XML',
    Plain => 'text/plain',
    UrlEncoded => 'application/x-www-form-urlencoded',
    Multipart => 'multipart/form-data',
    HTMLForm => ['application/x-www-form-urlencoded','multipart/form-data'],

Please keep in mind that when dispatching, L<Catalyst> will match the first most
relevant case, so if you use the C<Consumes> attribute, you should place your
most accurate matches early in the Chain, and your 'catchall' actions last.

See L<Catalyst::ActionRole::ConsumesContent> for more.

=head2 Scheme(...)

Allows you to specify a URI scheme for the action or action chain.  For example
you can required that a given path be C<https> or that it is a websocket endpoint
C<ws> or C<wss>.  For an action chain you may currently only have one defined
Scheme.

    package MyApp::Controller::Root;

    use base 'Catalyst::Controller';

    sub is_http :Path(scheme) Scheme(http) Args(0) {
      my ($self, $c) = @_;
      $c->response->body("is_http");
    }

    sub is_https :Path(scheme) Scheme(https) Args(0)  {
      my ($self, $c) = @_;
      $c->response->body("is_https");
    }

In the above example http://localhost/root/scheme would match the first
action (is_http) but https://localhost/root/scheme would match the second.

As an added benefit, if an action or action chain defines a Scheme, when using
$c->uri_for the scheme of the generated URL will use what you define in the action
or action chain (the current behavior is to set the scheme based on the current
incoming request).  This makes it easier to use uri_for on websites where some
paths are secure and others are not.  You may also use this to other schemes
like websockets.

See L<Catalyst::ActionRole::Scheme> for more.

=head1 OPTIONAL METHODS

=head2 _parse_[$name]_attr

Allows you to customize parsing of subroutine attributes.

    sub myaction1 :Path TwoArgs { ... }

    sub _parse_TwoArgs_attr {
      my ( $self, $c, $name, $value ) = @_;
      # $self -> controller instance
      #
      return(Args => 2);
    }

Please note that this feature does not let you actually assign new functions
to actions via subroutine attributes, but is really more for creating useful
aliases to existing core and extended attributes, and transforms based on
existing information (like from configuration).  Code for actually doing
something meaningful with the subroutine attributes will be located in the
L<Catalyst::Action> classes (or your subclasses), L<Catalyst::Dispatcher> and
in subclasses of L<Catalyst::DispatchType>.  Remember these methods only get
called basically once when the application is starting, not per request!

=head1 AUTHORS

Catalyst Contributors, see Catalyst.pm

=head1 COPYRIGHT

This library is free software. You can redistribute it and/or modify



( run in 0.698 second using v1.01-cache-2.11-cpan-39bf76dae61 )