On Mon, Jul 18, 2011 at 11:26 AM, Rodrigo <[email protected]> wrote:
> We're using 1) search_extra => [ 'MyAppX' ], as an add-on, non core
> namespace 2) {setup_components}->{except} 3) an around 'locate_components'
> to filter components in a special mode (which is used under a special flag
> which is not being really as far as I remember).
>
> if( $ENV{YELLOW_VERSION} ) {
> around 'locate_components' => sub {
> my $orig = shift;
> grep !/Blue/, $orig->( @_ );
> };
> }
>
>
>
This is pretty similar to how we were using it. In our case we have a core
application but need to be able to inject replacement components for
specific clients. Originally we just added the customer's namespace with
search_extra, but later realized that it didn't quite work as intended -- we
wanted to replace a component and that loaded both instead. Combining
search_extra and except worked but was spaghetti code because of the dynamic
nature. So we did an override of locate_components instead.
Suppose an app tree like so:
MyApp::Controller::Foo::Bar
MyApp::Controller::Customer::Initech::Foo::Bar
Our loading routine looks like this ($CONFIG here is a config file singleton
class that I hope goes away whenever Bread::Board makes it into Catalyst
core):
__PACKAGE__->config({
setup_components => {
except => qr/^MyApp::(?:Controller|Model|View)::Customer::/,
},
});
mangle_return locate_components => sub {
my($class,@comps) = @_;
foreach my $customer (@{$CONFIG->customers}) {
my @paths = qw( ::Controller ::Model ::View );
my $locator = Module::Pluggable::Object->new(
search_path => [ map {
s/^::(.*)/${class}::$1::Customer::${customer}/; $_; } @paths ],
);
foreach my $comp ($locator->plugins) {
my $replace_class = $comp;
$replace_class =~ s/::Customer::${customer}//;
@comps = grep {$_ ne $replace_class} @comps;
push @comps, $comp;
__PACKAGE__->config({
Catalyst::Utils::class2classsuffix($comp) => {
path => Catalyst::Utils::class2prefix($replace_class),
},
});
}
}
return @comps;
};
This does three things if we set customer=Initech:
1. Adds Controller::Customer::Initech::Foo::Bar to the load list
2. Removes Controller::Foo::Bar from the load list
3. Adjusts public path for Controller::Customer::Initech::Foo::Bar to
replace the original controller
--
Stephen Clouse <[email protected]>
_______________________________________________
List: [email protected]
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/