[Catalyst] MyApp::C::PageHooks - thoughts ?
Matthew Pitts
mpitts at a3its.com
Mon Oct 29 20:24:10 GMT 2007
I wanted to get some thoughts on something a little different that I'm
doing...
What I want to to have is Controllers that are temporary (i.e. date
sensitive) that represent a particular "promotion" that's running on a
site. This promotion may need to affect different areas of the site, but
I don't want to have $c->forward calls like the following everywhere
that I need the Promo's code to inject stash data.
$c->forward('Controller::Promos::Foo', 'some_action')
So, I decided to do a form of "hooks" within my app so that any given
controller can affect the stash for a defined set of hooks.
Below is the first run of my code to implement this. Basically, I
override Controller->register_actions and run through all the
controllers looking for C->config->{pagehooks} and build a local hashref
containing the hook definitions.
Then, in all the places throughout the app that are defined as
"hookable" I just do a:
$c->forward('Controller::PageHooks', 'run_hook', 'hook_name', [ 'arg1',
'arg2' ]);
and it "just works".
The main advantage with is that I can remove the promo's controller and
don't need to change any other controllers. I can even get my design
guys to code their templates in such a way that when the promo expires,
every place on the site affected by the promo magically goes back to
pre-promo look-and-feel.
Any thoughts on my level of sanity here?
package MyApp::Controller::PageHooks;
use base 'Catalyst::Controller';
use strict;
use warnings;
my $HOOKS = {};
sub register_actions {
my $self = shift;
my ( $c ) = @_;
$self->register_hooks($c);
return $self->SUPER::register_actions(@_);
}
sub register_hooks {
my ( $self, $c ) = @_;
my @ctrls = $c->controllers;
foreach my $ctrl (@ctrls) {
my $ctrl_ref = $c->controller($ctrl);
if ( $ctrl_ref->config->{pagehooks} ) {
my $hook = $ctrl_ref->config->{pagehooks};
while ( my ($hook, $action) = each(%{$hook}) ) {
$HOOKS->{$hook} ||= ();
push @{$HOOKS->{$hook}}, [ $ctrl, $action ];
}
}
}
}
sub run_hook : Private {
my ( $self, $c, $hook, @args ) = @_;
if ( $hook && $HOOKS->{$hook} ) {
foreach my $action_ref (@{$HOOKS->{$hook}}) {
my $ctrl = $c->controller($action_ref->[0]);
my $act = $ctrl->action_for($action_ref->[1]);
if ( $ctrl && $act ) {
$c->forward($action_ref->[0], $action_ref->[1], \@args);
}
}
}
}
1;
--
Matthew W. Pitts
Software Engineer
mpitts at a3its.com
336.202.3913 (mobile)
A3 IT Solutions, LLC
www.a3its.com
More information about the Catalyst
mailing list