Catalyst-ControllerRole-At

 view release on metacpan or  search on metacpan

README.mkdn  view on Meta::CPAN

**NOTE** For the purposes of executing code, we treat 'At' and 'At()' as the same.  However
We highly recommend At() as a best practice since it more clearly represents the idea
of 'no match template'.

## Chaining Actions across Controllers

The method attributes 'Via()' contains a pointer to the action being continued.  In
standard practice this is almost always the name of an action in the same controller
as the one declaring it.  This could be said to be a 'relative' (as in relative to
the current controller) action.  However you don't have to use a relative name.  You
can use any action's absolute private name, as long as it is an action that declares itself
to be a link in a chain.

However in practice it is not alway a good idea to spread your chained acions across
across controllers in a manner that is not easy to follow.  We recommend you try
to limit youself to chains that follow the controller hierarchy, which should be
easier for your code maintainers.

For this common, best practice case when you are continuing your chained actions across
controllers, following a controller hierarchy, we provide some template expansions you can
use in the 'Via' attribute.  These are useful to enforce this best practice as well as
promote reusability by decoupling hard coded private action namespaces from your controller.

    $up: The controller whose namespace contains the current controller
    $subname The name of the current actions subroutine
    $parent: Expands to $up/$subname

For example:

    package MyApp::Controller::ThingsTodo;

    use Moose;
    use MooseX::MethodAttributes;

    extends 'Catalyst::Controller';
    with 'Catalyst::ControllerRole::At';

    sub init :At($controller/...) {
      my ($self, $c) = @_;
    }

      sub list :Via(init) At($subname) {
        my ($self, $c) = @_;
      }

    __PACKAGE__->meta->make_immutable;

    package MyApp::Controller::ThingsTodo::Item;

    use Moose;
    use MooseX::MethodAttributes;

    extends 'Catalyst::Controller';
    with 'Catalyst::ControllerRole::At';

    sub init :Via($parent) At({id:Int}/...) {
      my ($self, $c) = @_;
    }

      sub show    :Via(init) At($subname) { ... }
      sub update  :Via(init) At($subname) { ... }
      sub delete  :Via(init) At($subname) { ... }

    __PACKAGE__->meta->make_immutable;

This creates four (4) URL templates:

    https://localhost/thingstodo/list
    https://localhost/thingstodo/:id/show
    https://localhost/thingstodo/:id/update
    https://localhost/thingstodo/:id/delete

With an action execution flow as follows:

    https://localhost/thingstodo/list =>
      /thingstodo/init
      /thingstodo/list

    https://localhost/thingstodo/:id/show
      /thingstodo/init
        /thingstodo/item/init
        /thingstodo/item/show

    https://localhost/thingstodo/:id/update
      /thingstodo/init
        /thingstodo/item/init
        /thingstodo/item/update

    https://localhost/thingstodo/:id/delete
      /thingstodo/init
        /thingstodo/item/init
        /thingstodo/item/delete

# COOKBOOK

One thing I like to do is create a base controller for my project
so that I can make my controllers more concise:

    package Myapp::Controller;

    use Moose;
    extends 'Catalyst::Controller';
    with 'Catalyst::ControllerRole::At';
     
    __PACKAGE__->meta->make_immutable;

You can of course doa  lot more here if you want but I usually recommend
the lightest touch possible in your base controllers since the more you customize
the harder it might be for people new to the code to debug the system.

# TODO

    - HTTP Methods
    - Incoming Content type matching
    - ??Content Negotiation??

# AUTHOR

John Napiorkowski [email:jjnapiork@cpan.org](email:jjnapiork@cpan.org)

# SEE ALSO



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