I have an app "Foo" and would like to make a new application based on it
called "Bar".

Bar will get a new design and templates, and will have many of the same
controller actions. But, I expect over time the two apps will drift apart
in functionality. Different people will maintain Foo and Bar apps.

Is there a better approach than making a copy and s/Foo/Bar/g in most
directories (lib, t)?

I first thought I'd pull out the controllers from the original Foo and turn
them into roles, and then just use the roles in both applications, but I'm
not sure we want to share code like for the risk of a change in one role is
not wanted in the other (and is missed by testing).

The other option, of course, is to keep one app and have it run with
different configurations and different "root" directory (so separate css,
js, templates, etc). But, again, then have to think about how to manage
changes that only effect one app.


Bill Moseley
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20110610/79b07de9/attachment.htm

Search Discussions

  • Stephen Clouse at Jun 10, 2011 at 10:12 pm

    On Fri, Jun 10, 2011 at 4:21 PM, Bill Moseley wrote:

    I have an app "Foo" and would like to make a new application based on it
    called "Bar".

    Is there a better approach than making a copy and s/Foo/Bar/g in most
    directories (lib, t)?

    This is probably not a full solution, but may get you on the path to one.

    I had a similar problem at $work where we have a core Catalyst application,
    but also needed the ability to install customer-specific components (either
    completely new functionality, or overriding one of the core controllers),
    and didn't want this to turn into a management nightmare (like
    hand-replacing specific component files on certain customers' systems and
    praying we remembered when upgrading them later, which is what we
    unfortunately did with our ancient CGI-script-based "app").

    Our Catalyst implementation looks something like this:

    package My::App;

    use Moose;
    use Catalyst;

    customers => [qw/Initech/],
    setup_components => {
    except => qr/^My::App::(Controller|Model|View)::Customer::/,

    around locate_components => sub {
    my $orig = shift;
    my $class = shift;
    my @comps = $class->$orig(@_);
    foreach my $customer (@{$class->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;
    return @comps;

    The code above roughly does the following:

    - Find all components as Catalyst normally does
    - For each customer identifier, search a customer-specific component tree
    - For each component found there, append it to the list of components to
    - If the customer-specific component shares its class path with a core
    component, remove the core component from the load list (i.e.,
    ::Controller::Customer::Initech::Foo causes ::Controller::Foo to be skipped;
    the assumption is that the customer-specific module extends it or replaces
    it entirely)

    If I had to adapt your problem to my problem, the core application would be
    Foo, and our customer would be Bar.

    I hope this gives you some ideas.

    Stephen Clouse <stephenclouse@gmail.com>
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20110610/f90bbcc3/attachment.htm

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedJun 10, '11 at 9:21p
activeJun 10, '11 at 10:12p

2 users in discussion

Bill Moseley: 1 post Stephen Clouse: 1 post



site design / logo © 2022 Grokbase