[Catalyst] Re: A point of confusion/frustration on chained actions

Aristotle Pagaltzis pagaltzis at gmx.de
Sun May 30 02:10:34 GMT 2010


* Ash Berlin <ash_cpan at firemirror.com> [2010-05-20 00:40]:
> sub tutorials : Chained('/') PathPart CaptureArgs(0) {
>  # stash tutorials rs
> }
> sub all_tutorials : Chained('tutorials') PathPart('') Args(0) {
>  # empty, or set stash for view
> }
>
> sub a_tutorial : Chained('tutorials') PathPart('') CaptureArgs(1) {
>  # stash tutorial
> }
> sub show_tutorial : Chained('a_tutorial') Args(0) PathPart('') {
> # setup view
> }
>
> sub comments : Chained('a_tutorial') CaptureArgs(0) PathPart {
>  # stash comments rs from stash->{tutorial}
> }
>
> # You get the idea hopefully....
> sub show_tutorial_comments : Chained('comments') Args(0) PathPart('') {}
> sub a_comment : Chained('comments') CaptureArgs(1) PathPart('') {}
>
> sub show_comment : Chained('a_comment') Args(0) PathPart('') { }
>
> sub replies : Chained('a_comment') PathPart CaptureArgs(0) {}
> sub show_replies : Chained('replies') Args(0) PathPart('') {}
> sub a_reply : Chained('replies') CaptureArgs(1) PathPart('') {}
> sub show_reply : Chained('a_reply') Args(0) PathPart('') {}

FWIW, I’d pull this out to several controllers and then use the
naming convention I’ve adopted for this sort of thing:

    package MyApp::Controller::Tutorials;
    sub base : Chained PathPart('tutorials') CaptureArgs(0) {
        # stash tutorials rs
    }
    sub list : Chained('base') PathPart('') Args(0) {
        # setup index view
    }
    sub item : Chained('base') PathPart('') CaptureArgs(1) {
        # stash one tutorial
    }
    sub view : Chained('item') PathPart('') Args(0) {
        # almost always empty
    }

    package MyApp::Controller::Comments;
    sub base : Chained('/tutorials/item') PathPart('comments') CaptureArgs(0) {
        # stash comments rs from stash->{tutorial}
    }
    sub list : Chained('base') PathPart('') Args(0) {}
    sub item : Chained('base') PathPart('') CaptureArgs(1) {}
    sub view : Chained('item') PathPart('') Args(0) {}


    package MyApp::Controller::Replies;
    sub base : Chained('/comments/item') PathPart('comments') CaptureArgs(0) {}
    sub list : Chained('base') PathPart('') Args(0) {}
    sub item : Chained('base') PathPart('') CaptureArgs(1) {}
    sub view : Chained('item') PathPart('') Args(0) {}

You get the idea.

This also makes it very nice to navigate the template structure
when using RenderView, as you can always relate everything to its
purpose at a glance without referring to the controllers once.

I kept the namespace structure flat here intentionally.
I recommend doing so even if your URIs are nested – unless there
are several different kinds of comments and replies in the
system. In that case I would nest the package names in order to
make it simpler to navigate the source. Chained dispatch makes it
easy to get just about any URI structure, regardless of how the
code is laid out; this is a feature, you should use it.

-- 
*AUTOLOAD=*_;sub _{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1}
&Just->another->Perl->hack;
#Aristotle Pagaltzis // <http://plasmasturm.org/>



More information about the Catalyst mailing list