Catalyst::Plugin::ConfigComponents - Creates components from config entries


Catalyst-Plugin-ConfigComponents documentation Contained in the Catalyst-Plugin-ConfigComponents distribution.

Index


Code Index:

Name

Top

Catalyst::Plugin::ConfigComponents - Creates components from config entries

Version

Top

0.5.$Revision: 125 $

Synopsis

Top

   # In your Catalyst application
   package YourApp;

   use Catalyst qw(ConfigComponents);

   __PACKAGE__->setup;

   Class::C3::initialize();

   # In your applications config file
   <component name="Model::YourModel">
      <parent_classes>YourExternal::ModelE<lt>/parent_classes>
      <parent_classes>Catalyst::ModelE<lt>/parent_classes>
   </component>

   # Do not create YourApp::Model::YourModel this module will do it for you

   # In a controller this will call your_method in
   # the class YourExternal::Model
   $result = $c->model( q(YourModel) )->your_method( ... );

Description

Top

When the application starts this module creates Catalyst component class definitions using config information. The defined class inherits from the list of parent classes referenced in the config file

Configuration and Environment

Top

Specify a Plugin::ConfigComponents config option. Attributes are

component_active

If the component_active config attribute exists and is false the component will not be loaded

parent_classes

List of classes for the derived component to inherit from

search_extra

To add additional search paths, specify a key named search_extra as an array reference. Items in the array beginning with :: will have the application class name prepended to them

setup_method

Defaults to _setup_config_components, the method to call after the call to Catalyst::setup_components

You may want to add the line:

   Class::C3::initialize();

to your Catalyst application after the __PACKAGE__->setup call if the base class creates any "diamond" patterns in the inheritance tree

Subroutines/Methods

Top

setup_components

Calls the setup method (which defaults to setup_config_components) after the parent method

_setup_config_components

For each config key matching \A Model|View|Controller :: it checks if the corresponding component already exists, and if it doesn't this method creates it at run-time

The parent class is set to MyApp->config->{ $component }->{parent_classes} if it exists, Catalyst::$component otherwise. The parent_classes can be an array ref in which case the defined class will inherit from all classes in the list (multiple inheritance)

Diagnostics

Top

None

Dependencies

Top

Moose::Role
Catalyst::Utils
Devel::InnerPackage

Incompatibilities

Top

There are no known incompatibilities in this module

Bugs and Limitations

Top

There are no known bugs in this module. Please report problems to the address below. Patches are welcome

Author

Top

Peter Flanigan, <Support at RoxSoft.co.uk>

Acknowledgements

Top

Larry Wall - For the Perl programming language

This code was originally posted to the Catalyst mailing list by Dagfinn Ilmari Mannsåker as a patch in response to an idea by Castaway. I thought it would be better as a plugin and have extended it to handle MI

License and Copyright

Top


Catalyst-Plugin-ConfigComponents documentation Contained in the Catalyst-Plugin-ConfigComponents distribution.

# @(#)$Id: ConfigComponents.pm 125 2009-07-19 12:47:40Z pjf $

package Catalyst::Plugin::ConfigComponents;

use strict;
use warnings;
use namespace::autoclean;
use version; our $VERSION = qv( sprintf '0.5.%d', q$Rev: 125 $ =~ /\d+/gmx );

use Moose::Role;
use Catalyst::Utils;
use Devel::InnerPackage ();

my $KEY = q(Plugin::ConfigComponents);

after 'setup_components' => sub {
   my $self = shift; my $config = $self->config->{ $KEY } || {}; my $method;

   if ($method = $config->{setup_method}) { $self->$method( $config ) }
   else {  $self->_setup_config_components( $config ) }

   return;
};

# Private methods

sub _setup_config_components {
   my ($self, $plugin_config) = @_;

   my $class  = ref $self || $self;
   my @paths  = qw(::Controller ::Model ::View);

   push @paths, @{ $plugin_config->{ search_extra } || [] };

   my $prefix = join q(|), map { m{ :: (.*) \z }mx } @paths;
   my @comps  = grep { m{ \A (?:$prefix) :: }mx } keys %{ $self->config };

   for my $suffix (sort { length $a <=> length $b } @comps) {
      my $component = "$class\::$suffix";

      next if ($self->components->{ $component });

      my $config = $self->config->{ $suffix };
      my $active = delete $config->{component_active};

      next if (defined $active and not $active);

      my $parents = delete $config->{parent_classes}
                 || delete $config->{base_class} # Deprecated
                 || "Catalyst::$suffix";

      $self->_load_config_component( $component, $parents );

      my %modules = ( $component => $self->setup_component( $component ),
                      map  { $_ => $self->setup_component( $_ ) }
                      grep { not exists $self->components->{ $_ } }
                      Devel::InnerPackage::list_packages( $component ) );

      for my $key ( keys %modules ) {
         $self->components->{ $key } = $modules{ $key };
      }
   }

   return;
}

sub _load_config_component {
   my ($self, $child, $parents) = @_;

   $parents = [ $parents ] unless (ref $parents eq q(ARRAY));

   for my $parent (reverse @{ $parents }) {
      Catalyst::Utils::ensure_class_loaded( $parent );
      ## no critic
      {  no strict q(refs);
         unless ($child eq $parent or $child->isa( $parent )) {
            unshift @{ "$child\::ISA" }, $parent;
         }
      }
      ## critic
   }

   unless (exists $Class::C3::MRO{ $child }) {
      eval "package $child; import Class::C3;"; ## no critic
   }

   return;
}

1;

__END__

# Local Variables:
# mode: perl
# tab-width: 3
# End: