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

NAME

Template::Plugin - Base class for Template plugin objects and general object wrapper

SYNOPSIS

    package Template::Plugin::MyPlugin;
    use base qw( Template::Plugin );
    use MyModule;

    sub new {
        my $class   = shift;
        my $context = shift;
        $class->SUPER::new($context, MyModule->new(@_));
    }

DESCRIPTION

A "plugin" for the Template Toolkit is simply a Perl module which exists in a known package location (e.g. Template::Plugin::*) and conforms to a regular standard, allowing it to be loaded and used automatically.

The Template::Plugin module defines a base class from which other plugin modules can be derived. A plugin does not have to be derived from Template::Plugin but should at least conform to its object-oriented interface.

It is recommended that you create plugins in your own package namespace to avoid conflict with toolkit plugins. e.g.

    package MyOrg::Template::Plugin::FooBar;

Use the PLUGIN_BASE option to specify the namespace that you use. e.g.

    use Template;
    my $template = Template->new({ 
        PLUGIN_BASE => 'MyOrg::Template::Plugin',
    });

PLUGIN API

The following methods form the basic interface between the Template Toolkit and plugin modules.

load($context)

This method is called by the Template Toolkit when the plugin module is first loaded. It is called as a package method and thus implicitly receives the package name as the first parameter. A reference to the Template::Context object loading the plugin is also passed. The default behaviour for the load() method is to simply return the class name. The calling context then uses this class name to call the new() package method.

    package MyPlugin;

    sub load {               # called as MyPlugin->load($context)
        my ($class, $context) = @_;
        return $class;       # returns 'MyPlugin'
    }
new($context, @params)

This method is called to instantiate a new plugin object for the USE directive. It is called as a package method against the class name returned by load(). A reference to the Template::Context object creating the plugin is passed, along with any additional parameters specified in the USE directive.

    sub new {                # called as MyPlugin->new($context)
        my ($class, $context, @params) = @_;
        bless {
            _CONTEXT => $context,
        }, $class;           # returns blessed MyPlugin object
    }
fail($error)

This method is used for reporting errors. It returns undef. e.g.

    sub new {
        my ($class, $context, $dsn) = @_;

        return $class->fail('No data source specified')
            unless $dsn;

        bless {
            _DSN => $dsn,
        }, $class;
    }
error()

This method returns the error as set by the above fail() method. It is called by the loading/creating Template::Context object.

DEEPER MAGIC

The Template::Context object that handles the loading and use of plugins calls the new(), fail() and error() methods against the package name returned by the load() method. In pseudo-code terms, it might look something like this:

    $class  = MyPlugin->load($context);       # returns 'MyPlugin'

    $object = $class->new($context, @params)  # MyPlugin->new(...)
        || die $class->error();               # MyPlugin->error()

The load() method may alterately return a blessed reference to an object instance. In this case, new(), fail() and error() are then called as object methods against that prototype instance.

    package YourPlugin;

    sub load {
        my ($class, $context) = @_;
        bless {
            _CONTEXT => $context,
        }, $class;
    }

    sub new {
        my ($self, $context, @params) = @_;
        return $self;
    }

In this example, we have implemented a 'Singleton' plugin. One object gets created when load() is called and this simply returns itself for each call to new().

Another implementation might require individual objects to be created for every call to new(), but with each object sharing a reference to some other object to maintain cached data, database handles, etc. This pseudo-code example demonstrates the principle.

    package MyServer;

    sub load {
        my ($class, $context) = @_;
        bless {
            _CONTEXT => $context,
            _CACHE   => { },
        }, $class;
    }

    sub new {
        my ($self, $context, @params) = @_;
        MyClient->new($self, @params);
    }

    sub add_to_cache   { ... }

    sub get_from_cache { ... }


    package MyClient;

    sub new {
        my ($class, $server, $blah) = @_;
        bless {
            _SERVER => $server,
            _BLAH   => $blah,
        }, $class;
    }

    sub get {
        my $self = shift;
        $self->{ _SERVER }->get_from_cache(@_);
    }

    sub put {
        my $self = shift;
        $self->{ _SERVER }->add_to_cache(@_);
    }

When the plugin is loaded, a MyServer instance is created. The new() method is called against this object which instantiates and returns a MyClient object, primed to communicate with the creating MyServer.

Template::Plugin BASE CLASS

The Template::Plugin module implements a base class from which other Template Toolkit plugins can be derived. In addition, it also acts as a general-purpose wrapper object, providing a delegation service via an AUTOLOAD method to an underlying object.

A reference to another object should be passed as a parameter (following the context reference) to the base class new() constructor. All methods then called on the Template::Plugin object will be delegated to the underlying object via an AUTOLOAD method.

    package Template::Plugin::MyPlugin;
    use base qw( Template::Plugin );
    use MyModule;

    sub new {
        my $class   = shift;
        my $context = shift;
        $class->SUPER::new($context, MyModule->new(@_));
    }

The name of a Perl module/class may be specified instead of a reference. The constructor will attempt to load the module and instantiate an object via its new() method. Any additional parameters passed will be forwarded onto new().

    package Template::Plugin::CGI;
    use base qw( Template::Plugin );

    sub new {
        my $class   = shift;
        my $context = shift;
        $class->SUPER::new($context, 'CGI', @_);
    }

AUTHOR

Andy Wardley <cre.canon.co.uk>

REVISION

$Revision: 1.12 $

COPYRIGHT

Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved. Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.

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

SEE ALSO

Template, Template::Context, Template::Plugin::CGI