The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CatalystX::VirtualComponents - Setup Virtual Catalyst Components Based On A Parent Application Class

SYNOPSIS

    # in your base app...
    package MyApp;
    use Catalyst;

    # in another app...
    package MyApp::Extended;
    use Moose;
    use Catalyst qw(+CatalystX::VirtualComponents);
    
    extends 'MyApp';

DESCRIPTION

WARNING: YMMV with this module.

This module provides a way to reuse controllers, models, and views from another Catalyst application.

HOW IT WORKS

Suppose you have a Catalyst application with the following components:

    # Application MyApp::Base
    MyApp::Base::Controller::Root
    MyApp::Base::Model::DBIC
    MyApp::Base::View::TT

And then in MyApp::Extended, you wanted to reuse these components -- except you want to customize the Root controller, and you want to add another model (say, Model::XML::Feed).

In your new app, you can skip creating MyApp::Extended::Model::DBIC and MyApp::Extended::View::TT -- CatalystX::VirtualComponents will take care of these.

Just provide the customized Root controller and the new model:

    package MyApp::Extended::Controller::Root;
    use Moose;

    BEGIN { extends 'MyApp::Base::Controller::Root' }

    sub new_action :Path('new_action') {
        ....
    }

(We will skip XML::Feed, as it's just a regular model)

Then, in MyApp::Extended

    packge MyApp::Extended;
    use Moose;
    use Catalyst;

    extends 'MyApp::Base';

Note that MyApp::Extended inherits from MyApp::Base. Naturally, if you are inheriting from an application, you'd probably want to inherit all of its controllers and such. To do this, specify CatalystX::VirtualComponents in the Catalyst plugin list for MyApp::Extended:

    __PACKAGE__->setup( qw(
        ... # your regular Catalyst plugins
        +CatalystX::VirtualComponent
    ) );

When setup() is run, CatalystX::VirtualComponent will intercept the component setup code and will automatically create virtual subclasses for components that exist in MyApp::Base, but not in MyApp::Extended. In the above case, MyApp::Extended::View::TT and MyApp::Extended::Model::DBIC will be created.

MyApp::Extended::Controller::Root takes precedence over the base class, so only the local component will be loaded. MyApp::Extended::Model::XML::Feed only exists in the MyApp::Extended namespace, so it just works like a normal Catalyst model.

GENERATING VIRTUAL CLASSES WITHOUT INHERITANCE

If you don't want to subclass, or use a more fine-grained control on which namespaces to look for base components, specify the namespaces in a config element:

    __PACKAGE__->config(
        VirtualComponents => {
            inherit => [
                'NamespaceA',
                'NamespaceB'
            ]
        }
    );

USING IN CONJUNCTION WITH CatalystX::AppBuilder

Simply add CatalystX::VirtualComponents in the plugin list:

    package MyApp::Extended::Builder;
    use Moose;

    extends 'CatalystX::AppBuilder';

    override _build_plugins {
        my $plugins = super();
        push @$plugins, '+CatalystX::VirtualComponents';
        return $plugins;
    };

    1;

METHODS

search_components($class)

Finds the list of components for Catalyst app $class.

setup_components()

Overrides Catalyst's setup_components() method.

TODO

Documentation. Samples. Tests.

AUTHOR

Daisuke Maki <daisuke@endeworks.jp>

LICENSE

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html