Fozzologs

RSS Feeds

About...

These posts are the creation of Doran L. Barton (AKA Fozziliny Moo). To learn more about Doran, check out his website at fozzilinymoo.org.

Right Side

This space reserved for future use.

Catalyst's 'begin' special action method

Posted: 26 May 2012 at 19:23:52

The [http://www.catalystframework.org/](Catalyst Framework) for Perl web development has some powerful special actions that frequently come in very handy when you're building an application, especially one that is heirarchical in nature as most are.

An application I am working on right now provides a list of hash references to the template view for presenting a dynamic crumb trail on the page. The crumb trail can be defined in the controller class like this:

$c->stash->{'crumbtrail'} = [
    {   href    =>  '/',
        label   =>  'Home',
    },
    {   href    =>  '/section1/'
        label   =>  'Section 1',
    },
    {   href    =>  '/subsection1/'
        label   =>  'Sub-Section 1',
    },
    {   label   =>  'Final Destination',
    },
];

In the interest of DRY, we certainly don't want to duplicate this code in each of our handler methods in the controller class. The special action method begin comes to the rescue.

The [https://metacpan.org/module/Catalyst::Manual::Intro](Catalyst::Manual::Intro POD) includes a brief section on these actions and describes the begin method as follows:

Called at the beginning of a request, once the controller that will run has been identified, but before any URL-matching actions are called. Catalyst will call the begin function in the controller which contains the action matching the URL.

If we have a controller class Foo that handles requests for /foo/ and any other path below it, we might have a begin action method defined in our Foo controller class that looks like this:

sub begin :Private {
    my ( $self, $c ) = @:

    $c->stash->{'crumbtrail'} = [
        {   href    =>  '/',
            label   =>  'Home',
        },
        {   href    =>  '/foo/'
            label   =>  'Foo',
        },
    ];
}

Then, in our index handler method, we simply remove the last href value:

sub index :Path Args(0) {
    my ( $self, $c ) = @_;

    ...
    $c->stash->{'crumbtrail'}->[-1]->{'href'} = undef;
}

In another Foo path handler, we would probably want to amend the crumb trail:

sub bar :Local {
    my ( $self, $c ) = @_;

    ...
    push @{$c->stash->{'crumbtrail'}}, {
        label   =>  'Bar',
    };
}

In summary, the begin special action method is a valuable way to save time and effort. Its cousins end and auto are also handy.