Template::Plugin::Filter
Author: Andy Wardley

TT2 Home Page

- Modules
- Template::*
- Plugin::*
- Filter.pm

Click to view the menu. It's very nice. Click to hide the menu and go all widescreen!
Back

#### Template::Plugin::File

Plugin providing information about files Up

#### Template::Plugin::* Modules

Next

#### Template::Plugin::Format

Plugin to create formatting functions

# Template::Plugin::Filter

## Base class for plugin filters

# Contents

Top

# SYNOPSIS

Top

    package MyOrg::Template::Plugin::MyFilter;

    use Template::Plugin::Filter;
    use base qw( Template::Plugin::Filter );

    sub filter {
        my ($self, $text) = @_;

        # ...mungify $text...

        return $text;
    }

    # now load it...
    [% USE MyFilter %]

    # ...and use the returned object as a filter
    [% FILTER $MyFilter %]
      ...
    [% END %]

# DESCRIPTION

Top

This module implements a base class for plugin filters. It hides the underlying complexity involved in creating and using filters that get defined and made available by loading a plugin.

To use the module, simply create your own plugin module that is inherited from the `Template::Plugin::Filter` class.

    package MyOrg::Template::Plugin::MyFilter;

    use Template::Plugin::Filter;
    use base qw( Template::Plugin::Filter );

Then simply define your `filter()` method. When called, you get passed a reference to your plugin object (`$self`) and the text to be filtered.

    sub filter {
        my ($self, $text) = @_;

        # ...mungify $text...

        return $text;
    }

To use your custom plugin, you have to make sure that the Template Toolkit knows about your plugin namespace.

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

Or for individual plugins you can do it like this:

    my $tt2 = Template->new({
        PLUGINS => {
            MyFilter => 'MyOrg::Template::Plugin::MyFilter',
        },
    });

Then you `USE` your plugin in the normal way.

    [% USE MyFilter %]

The object returned is stored in the variable of the same name, '`MyFilter`'. When you come to use it as a `FILTER`, you should add a dollar prefix. This indicates that you want to use the filter stored in the variable '`MyFilter`' rather than the filter named '`MyFilter`', which is an entirely different thing (see later for information on defining filters by name).

    [% FILTER $MyFilter %]
       ...text to be filtered...
    [% END %]

You can, of course, assign it to a different variable.

    [% USE blat = MyFilter %]

    [% FILTER $blat %]
       ...text to be filtered...
    [% END %]

Any configuration parameters passed to the plugin constructor from the `USE` directive are stored internally in the object for inspection by the `filter()` method (or indeed any other method). Positional arguments are stored as a reference to a list in the `_ARGS` item while named configuration parameters are stored as a reference to a hash array in the `_CONFIG` item.

For example, loading a plugin as shown here:

    [% USE blat = MyFilter 'foo' 'bar' baz = 'blam' %]

would allow the `filter()` method to do something like this:

    sub filter {
        my ($self, $text) = @_;

        my $args = $self->{ _ARGS   };  # [ 'foo', 'bar' ]
        my $conf = $self->{ _CONFIG };  # { baz => 'blam' }

        # ...munge $text...

        return $text;
    }

By default, plugins derived from this module will create static filters. A static filter is created once when the plugin gets loaded via the `USE` directive and re-used for all subsequent `FILTER` operations. That means that any argument specified with the `FILTER` directive are ignored.

Dynamic filters, on the other hand, are re-created each time they are used by a `FILTER` directive. This allows them to act on any parameters passed from the `FILTER` directive and modify their behaviour accordingly.

There are two ways to create a dynamic filter. The first is to define a `$DYNAMIC` class variable set to a true value.

    package MyOrg::Template::Plugin::MyFilter;
    use base 'Template::Plugin::Filter';
    our $DYNAMIC = 1;

The other way is to set the internal `_DYNAMIC` value within the `init()` method which gets called by the `new()` constructor.

    sub init {
        my $self = shift;
        $self->{ _DYNAMIC } = 1;
        return $self;
    }

When this is set to a true value, the plugin will automatically create a dynamic filter. The outcome is that the `filter()` method will now also get passed a reference to an array of postional arguments and a reference to a hash array of named parameters.

So, using a plugin filter like this:

    [% FILTER $blat 'foo' 'bar' baz = 'blam' %]

would allow the `filter()` method to work like this:

    sub filter {
        my ($self, $text, $args, $conf) = @_;

        # $args = [ 'foo', 'bar' ]
        # $conf = { baz => 'blam' }
    }

In this case can pass parameters to both the USE and FILTER directives, so your filter() method should probably take that into account.

    [% USE MyFilter 'foo' wiz => 'waz' %]

    [% FILTER $MyFilter 'bar' biz => 'baz' %]
       ...
    [% END %]

You can use the `merge_args()` and `merge_config()` methods to do a quick and easy job of merging the local (e.g. `FILTER`) parameters with the internal (e.g. `USE`) values and returning new sets of conglomerated data.

    sub filter {
        my ($self, $text, $args, $conf) = @_;

        $args = $self->merge_args($args);
        $conf = $self->merge_config($conf);

        # $args = [ 'foo', 'bar' ]
        # $conf = { wiz => 'waz', biz => 'baz' }
        ...
    }

You can also have your plugin install itself as a named filter by calling the `install_filter()` method from the `init()` method. You should provide a name for the filter, something that you might like to make a configuration option.

    sub init {
        my $self = shift;
        my $name = $self->{ _CONFIG }->{ name } || 'myfilter';
        $self->install_filter($name);
        return $self;
    }

This allows the plugin filter to be used as follows:

    [% USE MyFilter %]

    [% FILTER myfilter %]
       ...
    [% END %]

or

    [% USE MyFilter name = 'swipe' %]

    [% FILTER swipe %]
       ...
    [% END %]

Alternately, you can allow a filter name to be specified as the first positional argument.

    sub init {
        my $self = shift;
        my $name = $self->{ _ARGS }->[0] || 'myfilter';
        $self->install_filter($name);
        return $self;
    }

    [% USE MyFilter 'swipe' %]

    [% FILTER swipe %]
       ...
    [% END %]

# EXAMPLE

Top

Here's a complete example of a plugin filter module.

    package My::Template::Plugin::Change;
    use Template::Plugin::Filter;
    use base qw( Template::Plugin::Filter );

    sub init {
        my $self = shift;

        $self->{ _DYNAMIC } = 1;

        # first arg can specify filter name
        $self->install_filter($self->{ _ARGS }->[0] || 'change');

        return $self;
    }

    sub filter {
        my ($self, $text, $args, $config) = @_;

        $config = $self->merge_config($config);
        my $regex = join('|', keys %$config);

        $text =~ s/($regex)/$config->{ $1 }/ge;

        return $text;
    }

    1;

# AUTHOR

Top

Andy Wardley <abw@wardley.org> http://wardley.org/

# COPYRIGHT

Top

Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.

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

# SEE ALSO

Top

Template::Plugin, Template::Filters, Template::Manual::Filters

/modules/Template/Plugin/Filter.html last modified 10:55:00 31-May-2007