=head1 LOADING PLUGINS
-Plugins occupy the C<Maypole::Plugin::*> namespace on CPAN. At time of writing, there are 16 plugin modules
-available - see http://search.cpan.org/search?query=Maypole%3A%3APlugin&mode=module
+Plugins occupy the C<Maypole::Plugin::*> namespace on CPAN. At time of writing,
+there are 16 plugin modules available - see
+http://search.cpan.org/search?query=Maypole%3A%3APlugin&mode=module
-Plugins are loaded into a Maypole application by L<Maypole::Application>. For instance, to add L<HTML::QuickTable>
-support to the BeerDB example application:
+Plugins are loaded into a Maypole application by L<Maypole::Application>. For
+instance, to add L<HTML::QuickTable> support to the BeerDB example application:
package BeerDB;
use strict;
Note that the leading C<Maypole::Plugin::*> is omitted.
-For some plugins, that's it. You probably have a bunch of new methods available on your Maypole request objects -
-see the documentation for the plugin.
+For some plugins, that's it. You probably have a bunch of new methods available
+on your Maypole request objects - see the documentation for the plugin.
For others, you will need to set configuration variables or customise other
-parts of the application. For instance, to add sessions to your application, you can use L<Maypole::Plugin::Session>:
+parts of the application. For instance, to add sessions to your application, you
+can use L<Maypole::Plugin::Session>:
package BeerDB;
use strict;
use Maypole::Application( 'Session' );
-That's all, if you're willing to stick with the defaults (L<Apache::Session::File> backend, session and lock files in C</tmp/sessions> and C</tmp/sessionlock>). Otherwise, you need to supply some configuration:
+That's all, if you're willing to stick with the defaults
+(L<Apache::Session::File> backend, session and lock files in C</tmp/sessions>
+and C</tmp/sessionlock>). Otherwise, you need to supply some configuration:
__PACKAGE__->config->session( { class => "Apache::Session::Flex",
args => {
}
} );
-The plugin module is responsible for adding slots to L<Maypole::Config>, in this case, the C<session> accessor.
+The plugin module is responsible for adding slots to L<Maypole::Config>, in this
+case, the C<session> accessor.
=head1 WRITING PLUGINS
=head2 Modifying the Maypole request object
-Plugins are inserted into the C<@ISA> of the Maypole request object. So method calls on the request object will
-first search the plugin classes, before looking in L<Maypole>. Methods defined in the plugin are
-therefore directly available on the request. That also goes for methods inherited by the plugin. I'm not aware
-of any plugins that currently inherit from another package, but there's no reason not to.
+Plugins are inserted into the C<@ISA> of the Maypole request object. So method
+calls on the request object will first search the plugin classes, before looking
+in L<Maypole>. Methods defined in the plugin are therefore directly available on
+the request. That also goes for methods inherited by the plugin. I'm not aware
+of any plugins that currently inherit from another package, but there's no
+reason not to.
-Note that if you need simple accessor methods on the request, you can add them by saying
+Note that if you need simple accessor methods on the request, you can add them
+by saying
Maypole->mk_accessors( qw/ fee fi fo / );
-at the start of your plugin. Under mod_perl, you've just added these accessors to B<all> Maypole applications
-on the server, even ones that do not use this plugin. You could instead make the call inside the C<setup> method:
+at the start of your plugin. Under mod_perl, you've just added these accessors
+to B<all> Maypole applications on the server, even ones that do not use this
+plugin. You could instead make the call inside the C<setup> method:
$r->mk_accessors( qw/ fee fi fo / );
=head2 Initialisation with C<setup>
-After loading plugins via L<Maypole::Application>, setting configuration variables in calls to
-C<< __PACKAGE__->config->foo( 'bar' ) >>, and optionally defining custom request methods, your
-application should call its C<setup> method, generally including arguments for the database connection:
+After loading plugins via L<Maypole::Application>, setting configuration
+variables in calls to C<< __PACKAGE__->config->foo( 'bar' ) >>, and optionally
+defining custom request methods, your application should call its C<setup>
+method, generally including arguments for the database connection:
__PACKAGE__->setup( $dsn, $user, $pass, @more_args );
-All of these arguments will be passed to the C<setup_database> method of the model class.
+All of these arguments will be passed to the C<setup_database> method of the
+model class.
-C<Maypole::setup()> is responsible for loading the model class, calling the C<setup_database> method
-on the model class, and making each table class in the application inherit from the model. It is therefore
-recommended that you call C<setup> B<after> setting up all your configuration options.
+C<Maypole::setup()> is responsible for loading the model class, calling the
+C<setup_database> method on the model class, and making each table class in the
+application inherit from the model. It is therefore recommended that you call
+C<setup> B<after> setting up all your configuration options.
-Plugins can intercept the call to C<setup> to carry out their own initialisation, as long as they propagate
-the call up through the hierarchy. A common idiom for this is:
+Plugins can intercept the call to C<setup> to carry out their own
+initialisation, as long as they propagate the call up through the hierarchy. A
+common idiom for this is:
Maypole::Plugin::Foo;
use strict;
# do something with $option
}
-L<NEXT> is a replacement for the built-in C<SUPER> syntax. C<SUPER> dispatches a call to the superclass
-of the current package - B<but> it determines the superclass at compile time. At that time, the superclass
-is something like C<main::>. L<NEXT> does the superclass lookup at runtime, after L<Maypole::Application> has
-inserted the plugin into the request class's inheritance chain.
+L<NEXT> is a replacement for the built-in C<SUPER> syntax. C<SUPER> dispatches a
+call to the superclass of the current package - B<but> it determines the
+superclass at compile time. At that time, the superclass is something like
+C<main::>. L<NEXT> does the superclass lookup at runtime, after
+L<Maypole::Application> has inserted the plugin into the request class's
+inheritance chain.
-The C<DISTINCT> modifier ensures each plugin's C<setup> method is only called once, and protects against
-diamond inheritance. This may or may not be an issue in your app - and if you always use the C<DISTINCT>
-syntax, it won't be.
+The C<DISTINCT> modifier ensures each plugin's C<setup> method is only called
+once, and protects against diamond inheritance. This may or may not be an issue
+in your app - and if you always use the C<DISTINCT> syntax, it won't be.
-Notice that the C<setup> call is re-dispatched before running the plugin's own initialisation code. This
-allows C<Maypole::setup()> to set up the database, model, and table classes, before your plugin starts tweaking
-things.
+Notice that the C<setup> call is re-dispatched before running the plugin's own
+initialisation code. This allows C<Maypole::setup()> to set up the database,
+model, and table classes, before your plugin starts tweaking things.
-You can use the C<setup> method to load modules into the request class namespace. L<Maypole::Plugin::I18N> has:
+You can use the C<setup> method to load modules into the request class
+namespace. L<Maypole::Plugin::I18N> has:
sub setup {
my $r = shift;
Path => $r->config->lexicon;
}
-Now the application namespace has a C<_loc> function (exported by L<Locale::Maketext::Simple>), (plus C<lang> and
-C<maketext> methods inherited from L<Maypole::Plugin::I18N>).
+Now the application namespace has a C<_loc> function (exported by
+L<Locale::Maketext::Simple>), (plus C<lang> and C<maketext> methods inherited
+from L<Maypole::Plugin::I18N>).
=head3 More initialisation with C<init>
L<Maypole> also defines an C<init> method. It
-pulls the name of the view class from the config, loads it, instantiates an object in the view class, and
-sets this in the C<view_object> config slot.
+pulls the name of the view class from the config, loads it, instantiates an
+object in the view class, and sets this in the C<view_object> config slot.
In CGI applications, C<init> is called at the start of every request.
-Under mod_perl, this method will only ever be called once per server child, at the start of the first request after
-server startup. If instead, you call this method in your application module (after the call to C<setup>),
-then the code loaded by this call will be shared by all child servers.
+Under mod_perl, this method will only ever be called once per server child, at
+the start of the first request after server startup. If instead, you call this
+method in your application module (after the call to C<setup>), then the code
+loaded by this call will be shared by all child servers.
See B<Hacking the view> for a plugin that uses C<init>.
=head2 Adding configuration
-The configuration object can be retrieved from the Maypole request object (C<< $r->config >>) or as a class method
-on the application (e.g. C<< BeerDB->config >>).
+The configuration object can be retrieved from the Maypole request object
+(C<< $r->config >>) or as a class method on the application (e.g.
+C<< BeerDB->config >>).
-If your plugin needs some custom configuration settings, you can add methods to the config object by
-saying
+If your plugin needs some custom configuration settings, you can add methods to
+the config object by saying
Maypole::Config->mk_accessors( qw/ foo bar baz / );
-at the start of your plugin. In the application, after the C<Maypole::Application> call, these methods will
-be available on the config object.
+at the start of your plugin. In the application, after the
+C<Maypole::Application> call, these methods will be available on the config
+object.
=head2 Modifying the Maypole model
=item Replacing the model
-To load a different model, set C<< __PACKAGE__->config->model( 'Custom::Model' ) >> in the application
-before calling C<setup>. You could instead set C<< $r->config->model >> before re-dispatching the C<setup> call,
-but this is going to confuse and annoy your users.
+To load a different model, set
+C<< __PACKAGE__->config->model( 'Custom::Model' ) >> in the application
+before calling C<setup>. You could instead set C<< $r->config->model >> before
+re-dispatching the C<setup> call, but this is going to confuse and annoy your
+users.
=item Hacking the model
B<CAVEAT>: the way I do this just seems dirty, so there must be a Better Way.
-L<Maypole::Plugin::FormBuilder> (part of the L<Maypole::FormBuilder> distribution), in its C<setup> method,
-loads a custom pager class into the model by saying
+L<Maypole::Plugin::FormBuilder> (part of the L<Maypole::FormBuilder>
+distribution), in its C<setup> method, loads a custom pager class into the model
+by saying
eval "package $model; use $pager";
-Yuk. Note that under mod_perl, you have just forced B<every> application using C<$model> to also use C<$pager>.
+Yuk. Note that under mod_perl, you have just forced B<every> application using
+C<$model> to also use C<$pager>.
-C<Maypole::Plugin::AutoUntaint::setup()> loads an extra method into the model by saying
+C<Maypole::Plugin::AutoUntaint::setup()> loads an extra method into the model by
+saying
no strict 'refs';
*{"$model\::auto_untaint"} = \&Class::DBI::Plugin::AutoUntaint::auto_untaint;
-Yuk again. And again, under mod_perl, now every application using C<$model> has an C<auto_untaint> method
-added to its model.
+Yuk again. And again, under mod_perl, now every application using C<$model> has
+an C<auto_untaint> method added to its model.
Same plugin, next line has
Same yuk, same mod_perl caveat.
-
-
=back
=item Hacking the view
-L<Maypole::Plugin::FormBuilder> intercepts the C<init> call to override the C<vars> method in the view class.
-First it re-dispatches the C<init> call, which will set up either a default view class and object, or those
-configured in the application. Then it builds a new view class on-the-fly, and makes this new class inherit from
-L<Maypole::FormBuilder::View> and from the original view class. Finally it replaces the C<view> and C<view_object>
-in the application's config object.
+L<Maypole::Plugin::FormBuilder> intercepts the C<init> call to override the
+C<vars> method in the view class. First it re-dispatches the C<init> call, which
+will set up either a default view class and object, or those configured in the
+application. Then it builds a new view class on-the-fly, and makes this new
+class inherit from L<Maypole::FormBuilder::View> and from the original view
+class. Finally it replaces the C<view> and C<view_object> in the application's
+config object.
sub init
{