Alexander Kühne > Template-Plugin-TwoStage > Template::Plugin::TwoStage

Download:
Template-Plugin-TwoStage-0.08.tar.gz

Dependencies

Annotate this POD

View/Report Bugs
Module Version: 0.08   Source  

NAME ^

Template::Plugin::TwoStage - two stage processing of template blocks with first stage caching

VERSION ^

version 0.08

SYNOPSIS ^

This is a plugin for the Template Toolkit that facilitates a two stage processing of BLOCKs/templates with first stage caching. Processing results of the first (precompilation) stage are cached away for subsequent repeated processing in the second (runtime) stage. Precompilation and runtime tags are seperated by using different tag styles.

Sample Configuration via TT configuration:

   Template->new( { ..., TwoStage => { caching_dir => My::Application->path_to_tmp(), ... } } );

Basic usage in the a TT2-template:

   [%   USE TwoStage; 
        TwoStage.process( 
                template => 'cached_page', 
                keys => { bar => bar  }, 
                ttl => 60 * 60 
        );

        BLOCK cached_page; 
                # use precompile tags or runtime tags here
   %]
                [* foo # runtime stage evaluation *]    
   [%              IF bar; # precompilation stage evaluation 
                        # ... 
                   ELSE;
                        # ...
                   END;
        END 
   %]

FEATURES ^

USE CASES ^

You might benefit from this module if ...

CONFIGURATION ^

Plugin behaviour can be controlled using following options:

Options

caching_dir

The TwoStage plugin will store the resulting precompiled templates from the first stage on disk in a 'caching directory', that can be specified with the 'caching_dir' option.

The directory 'TT_P_TwoStage' in your platform specific tmp-directory determined with the help of File::Spec->tmpdir() is the default setting for this option. Pass a path in order to change it to some other directory - it will also be automatically extended by the subdirectories 'TT_P_TwoStage' and the plugin's class name.

This option can NOT be set on plugin construction or calls to include()/process().

dev_mode

Set this configuration option to a TRUE value in order to disable the use of cached - precompiled - files, and see your changes to cached BLOCKs/templates immediately while still having access to the precompiled versions on disk for their validation.

See also the configuration option 'dir_keys' as another interesting feature for development.

ttl

Specify the "time to live" for the precompiled versions of the BLOCKs/templates in seconds - 0 is 'no expiration' and the default setting.

dir_keys

Usually the keys connected to a precompiled version are included among other things into the file name of a BLOCK/template in order to identify a precompiled cached BLOCK/template on disk. This is accomplished by using the SHA1 hash function.

To make the retrieval of a certain caching file easier for humans, the configuration parameter 'dir_keys' lets you include the keys into the file path of the precompiled cached BLOCK/template. This behaviour might be handy in cases where one wants to inspect the precompiled versions produced.

Set 'dir_keys' either to an array reference holding a selection of keys or a scalar holding a TRUE value for all keys. This feature is available in development mode only! See also configuration option 'dev_mode'.

See also the section 'Caching with plugin object methods process() and include()' for more on the 'keys' parameter.

namespace

This option can come to rescue in situations where identities of cached BLOCK/template versions on disk can be ambigious relying only on the standard measures taken by this plugin in order to disambiguate cached disk versions (see section 'Avoiding disk cache overlaps' below).

If e.g. you choose not to subclass this module for an application you can ensure the segmentation of applications by setting the 'namespace' configuration option accordingly. In this example however this approach has the drawback that you need to set this configuration option in each template on plugin construction:

    USE TwoStage( namespace => application_name );

runtime_tag_style

Set this option to one of the predefined tag styles TT is offering like 'php', 'mason', 'html', ..., and that are accepted by TT as a value to its 'TAG_STYLE' configuration option or 'TAGS' directive. Default is: star ([* *]).

Excursus: precompilation tag style

The precompilation tag style is always the tag style set in the TT configuration or 'default'. A tag style defined local to the file the plugin is being called in ( by means of the 'TAGS'-directive at the beginning of the file) will be handled correctly - this file scoped tag style will also be used in the BLOCK to be precompiled as precompilation tag style.

Changing the tag style only for a certain BLOCK that is to be precompiled is not possible, as the 'TAGS' directive can be set only on per template file basis. A centralized configuration of the precompilation tag style to be used is not available to date.

tt_cache_size

As one can produce a lot of precompiled versions of a single BLOCK/template controlled by this plugin using the 'keys' feature of process()/include(), it might be advisable in some situations to set the CACHE_SIZE TT configuration option to a positive value in order to curb memory consumption when having a TT singleton object around in a persistent environment.

As the plugin uses a provider object specific to the plugin it will not respect the CACHE_SIZE configuration property possibly set in your main TT configuration. Use this method in order to set the CACHE_SIZE configuration property for the plugin's specific provider object. By default all precompiled templates are cached.

In contrast to all the other configuration options - except 'caching_dir' - this option can only be set as class data.

Setting options

Configuration options may be set in different ways and with different scopes.

Setting options in TT configuration

This plugin can be configured using the configuration hash provided to the Template Toolkit-constructor. Put your plugin configuration options in a hash, and reference it in the TT configuration hash using the key 'TwoStage'.

Sample code:

   Template->new( { ..., TwoStage => { namespace => 'My::Application', ... } } );

The configuration options will apply to all TwoStage plugin-objects created in this TT object. Note that this does NOT hold true for derived classes of the plugin!

Note! In order to avoid disk cache overlaps of applications using the TwoStage plugin without subclassing, configure a unique namespace or a separate caching directory. See also 'Avoiding disk cache overlaps' below.

Setting options via subclassing

This plugin is subclassable. Configuration with scope restricted to the subclass can be achieved by using the inheritable class data accessors provided (see sample code below).

Subclassing allows you to customize your plugin behaviour at a single place, and to complement the caching keys via a possible callback method extend_keys(). At the same time it avoids disk cache overlaps for applications sharing the same caching directory as long as the derived plugin is not used in different applications.

Subclasses will not read the plugin options specified in the TT configuration hash when configuring.

Sample code:

   # sample code is based on an imaginary Catalyst application Your::Application

   package Your::Application::Template::Plugin::TwoStage;
   use base qw( Template::Plugin::TwoStage );

   __PACKAGE__->caching_dir( Your::Application->config->{home}.'/tmp' );
   __PACKAGE__->dev_mode( 1 );
   __PACKAGE__->ttl( 60 * 60 ); # 1 h
   __PACKAGE__->dir_keys( 1 );
   __PACKAGE__->runtime_tag_style( 'html' );

   sub extend_keys {
        my $plugin = shift; # the callback receives the plugin object as 1st parameter
        
        my $s = $plugin->{CONTEXT}->stash;

        # get Catalyst context from stash
        my $c = $s->get( 'c' );
        my $r = $c->request;

        # hook method for adding standard keys - return the keys => value -hash by reference!
        { domain => $r->uri->authority,
          method => $r->method,
          logged_in => $c->user_exists
        };

   }

Don't forget to add your subclass to the plugin base of your TT2-configuration:

        PLUGIN_BASE => [ 'Your::Application::Template::Plugin' ]

or declare it via the PLUGINS TT2-configuration option

        PLUGINS => { TwoStage => 'Your::Application::Template::Plugin::TwoStage', ... }

Setting options as named parameters to USE or include()/process()

Any option set via subclassing or the TT configuration hash can be overridden on plugin construction ( 'USE TwoStage()' ) or even on the call of the include() or precompile()-methods at your will with only restricted scope. Configuration provided on plugin construction will apply to this specific plugin object only; configuration provided as parameters to include()/process() only to the specific plugin object call.

Sample code:

   USE TwoStage( ttl => 1000 );
   TwoStage.process( template => 'some', ttl => 0 );

Note! The following options can not be overridden this way: caching_dir, tt_cache_size

Object hook methods

extend_keys

With this callback method it is possible to merge some default keys into the template signature. The values of the keys introduced this way will be dominated by the values of identical keys passed to process() or include(). Return a hash reference mapping standard signature keys to its values!

Have a look at the sample code above (section 'Setting options via subclassing').

When setting options in the TT configuration hash simply add a reference to your extend_keys-function with key 'extend_keys'. It will receive the plugin object as the first parameter when being called.

   Template->new( 
        { ..., 
          TwoStage => { 
                extend_keys => sub { 
                        my $plugin = shift; 
                                        
                        return { key => $value };  
                }, ... 
   
          } 
        } 
   );

Avoiding disk cache overlaps

Having precompiled a BLOCK/template the TwoStage plugin tries to assign an unique as possible identity to it - refered to as 'signature' later -, and writes it to disk into the configured caching directory (see also corresponding option 'caching_dir') using a SHA1 fingerprint of the signature as its file name.

What is the unique signature made up of and how unique is it?

Implications

CACHING ^

Caching with plugin object methods process() and include()

Once the plugin object has been pulled into the template by means of the 'USE' directive, calling the plugin object methods include() or process() against it will insert the BLOCK/template content with all the precompilation and caching magic delivered by this plugin into the template.

Named parameters of process/include:

include() is exposing an identical behaviour as process() with the exception that it does stash localisation in the runtime stage.

Reset cached content with purge()

In order to set back caching remove the cached templates from your caching directory. Maybe a script to assist you in this task will be shipped together with a future version of this plugin.

Using purge() you remove all files from the caching directory of the class - use this to set back caching from within templates. This method is used mainly in the self tests of this module. Maybe there are even more useful applications for it - so it became a public class method.

        [% TwoStage = USE TwoStage; 
           TwoStage.purge;
        %]

STAT_TTL and caching

Please note that the STAT_TTL configuration of TT will not work for cached BLOCKs/templates as you make modifications to the "source" BLOCKS/templates of those cached templates. You should turn off caching instead using the plugin option 'dev_mode'.

EXPORTS ^

TT configuration

The compiled plugin configuration is saved with key '_TwoStage' in the main TT configuration hash.

TT stash

There is a temporary stash entry 'TwoStage_precompile_mode = 1;' in the precompilation stage of template processing.

HEURISTICS ^

In order to avoid common pitfalls when using this module you find some tips and reminders below:

BUGS ^

Please report any bugs or feature requests to bug-template-plugin-twostage at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Template-Plugin-TwoStage. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT ^

You can find documentation for this module with the perldoc command.

    perldoc Template::Plugin::TwoStage

You can also look for information at:

ACKNOWLEDGEMENTS ^

This module was inspired to some extent by Perrin Harkins http://search.cpan.org/dist/Template-Plugin-Cache and not least by my CO2 footprint.

SEE ALSO ^

Template::Plugin, http://search.cpan.org/dist/Template-Plugin-Cache

AUTHOR ^

Alexander Kühne <alexk@cpan.org>

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2014 by Alexander Kühne.

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

syntax highlighting: