[Templates-cvs] cvs commit: TT3/lib/Template Store.pm
cvs@template-toolkit.org
cvs@template-toolkit.org
Wed, 24 Mar 2004 14:08:38 +0000
cvs 04/03/24 14:08:38
Added: lib/Template Store.pm
Log:
* added Template::Store module
Revision Changes Path
1.1 TT3/lib/Template/Store.pm
Index: Store.pm
===================================================================
#========================================================================
#
# Template::Store
#
# DESCRIPTION
# This module implements a default store object which stored compiled
# template Perl code in files and reloads them back into in-memory
# objects on demand.
#
# AUTHOR
# Andy Wardley <abw@wardley.org>
#
# COPYRIGHT
# Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.
# Copyright (C) 2004 Fotango Ltd.
#
# This module is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
# REVISION
# $Id: Store.pm,v 1.1 2004/03/24 14:08:37 abw Exp $
#
#========================================================================
package Template::Store;
use strict;
use warnings;
use Template::Utils;
use Template::Base;
use base qw( Template::Base );
use vars qw( $VERSION $ERROR $DEBUG $UTILS $THROW );
$VERSION = sprintf("%d.%02d", q$Revision: 1.1 $ =~ /(\d+)\.(\d+)/);
$ERROR = '';
$DEBUG = 0 unless defined $DEBUG;
$UTILS = 'Template::Utils';
$THROW = 'store';
sub init {
my ($self, $config) = @_;
$self->{ extension } = $config->{ extension } || $config->{ ext };
$self->{ directory } = $config->{ directory } || $config->{ dir }
|| return $self->error('no directory defined');
return $self;
}
sub get {
my ($self, $id) = @_;
my $file = $self->filename($id) || return;
my $object;
$self->debug("fetching $id from file $file\n") if $self->{ DEBUG };
# check the file exists
return $self->decline("$id not found")
unless -f $file;
# load the file using require(), first deleteing any
# %INC entry to ensure it is reloaded - we don't want
# require() to return 1 to say it's already in memory
delete $INC{ $file };
eval { $object = require $file; };
return $@
? $self->error("error loading compiled template $file: $@")
: $object;
}
sub set {
my ($self, $id, $code) = @_;
my $file = $self->filename($id) || return;
$self->debug("storing $id in file $file\n") if $self->{ DEBUG };
return $UTILS->save_file($file, $code)
|| $self->error($UTILS->error());
}
sub filename {
my ($self, $id) = @_;
my $ext;
# split id by ':' provider:path separator and also take care
# of any paths with dos-like driver specifiers like C:/blah/blah
my $path = $UTILS->file_path($self->{ directory }, split(':', $id));
# add any file extension
if (defined ($ext = $self->{ extension })) {
if ($ext =~ /^\w/) {
# extension starting with word character (e.g. 'ttc') is
# appended to end of path, with '.' as separator
$path .= ".$ext";
}
else {
# otherwise we assume it's got it's own separator, e.g. '-ttc'
$path .= $ext;
}
}
return $path;
}
1;
__END__
=head1 NAME
Template::Store - secondary storage of compiled templates
=head1 SYNOPSIS
use Template::Store;
my $store = Template::Store->new(
directory => '/tmp/tt3/store',
extension => '.ttc',
);
# set() method to store Perl code in a file
$store->set( foo => $foo_perl_code );
# get() method to require() it back in again
$foo_object = $store->get('foo')
|| die "foo is not in store\n";
=head1 DESCRIPTION
The Template::Store module implements a simple filesystem-based
store, providing persistant storage of compiled templates. It also
acts as a base class for other storage modules that store templates
using different media or mechanisms.
The Template::Store is a little like the Template::Cache module. Both
are designed to save us from having to compile a template from source
code into Perl code whenever possible, given that this is the most
time consuming part of processing a template. The key difference
between them is that the Template::Cache module stores live Perl
objects in memory, whereas Template::Store saves the compiled Perl
code on disk (or some other storage system). However, both return
live Perl objects, from their get() method. In the case of
Template::Store, the file in which the component Perl code is stored
is loaded using Perl's require() function, causing the Perl code to be
loaded and evaluated into a Template::Component object.
=head2 METHODS
=head3 new()
Constructor method used to create a new store module. The
C<directory> argument (or C<dir> for short) must be provided to define
the root directory under which compiled template files should be
stored.
use Template::Store;
my $store = Template::Store->new(
directory => '/tmp/tt3/store'
);
The optional C<extension> (or C<ext> for short) parameter can be
used to define an extension that will be automatically added to the
end of the name of each file used to store compiled templates.
my $store = Template::Store->new(
directory => '/tmp/tt3/store'
extension => 'ttc'
);
If the extension begins with a word character, as shown in the
previous example, then it will be added to the end of the filename
with a C<.> character used to delimit them (e.g. ".ttc"). If the
extension already begins with a non-word character (e.g. ".ttc",
"-ttc", etc) then it is appended as it is with no further delimiter
added.
=head3 set($id, $perl_code)
Public method to store the Perl code generated for a compiled template
based on a unique identifier. The C<$perl_code> argument should be
provided as a scalar or reference to a scalar.
my $perl_code = $compiler->compile($source_code);
$store->set( foo => $perl_code );
=head3 get($id)
Public method to fetch an item from the store if it exists. The unique
identifier is passed as the first argument. The method loads the relevant
file associated with the identifier using Perl's require(), thereby evaluating
the Perl code and generating a Template::Component object (or whatever other
result the Perl code returned).
my $foo = $store->get('foo')
|| die "foo not in store";
=head1 ERROR HANDLING
Any errors raised by the Template::Store module will be thrown as
Template::Exception objects with a C<store> type. This includes
errors in the C<new()> constructor (e.g. no C<directory> defined),
C<get()> and C<set()> methods (e.g. failed to read or write a file).
=head1 AUTHOR
Andy Wardley E<lt>abw@wardley.orgE<gt>
=head1 VERSION
$Revision: 1.1 $
=head1 COPYRIGHT
Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved.
Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.
Copyright (C) 2004 Fotango Ltd.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut
# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4: