diff options
| author | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
|---|---|---|
| committer | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
| commit | 3282be229999dc36c197b264d63063a18d136331 (patch) | |
| tree | 98a42db29d955b39e7bed1b599fdcc56c3a29de9 /lib/Template | |
| parent | cfdd733c17cfa4f1a43b827a656e9e53cc2524ac (diff) | |
| download | xxv-3282be229999dc36c197b264d63063a18d136331.tar.gz xxv-3282be229999dc36c197b264d63063a18d136331.tar.bz2 | |
* Update installation list with required modules
* Remove unused/doubled provided external perl moduls
Diffstat (limited to 'lib/Template')
85 files changed, 0 insertions, 45026 deletions
diff --git a/lib/Template/Base.pm b/lib/Template/Base.pm deleted file mode 100644 index 5f19d78..0000000 --- a/lib/Template/Base.pm +++ /dev/null @@ -1,314 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Base -# -# DESCRIPTION -# Base class module implementing common functionality for various other -# Template Toolkit modules. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#------------------------------------------------------------------------ -# -# $Id: Base.pm,v 2.69 2004/01/13 16:19:09 abw Exp $ -# -#======================================================================== - -package Template::Base; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use Template::Constants; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.69 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new(\%params) -# -# General purpose constructor method which expects a hash reference of -# configuration parameters, or a list of name => value pairs which are -# folded into a hash. Blesses a hash into an object and calls its -# _init() method, passing the parameter hash reference. Returns a new -# object derived from Template::Base, or undef on error. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my ($argnames, @args, $arg, $cfg); -# $class->error(''); # always clear package $ERROR var? - - { no strict qw( refs ); - $argnames = \@{"$class\::BASEARGS"} || [ ]; - } - - # shift off all mandatory args, returning error if undefined or null - foreach $arg (@$argnames) { - return $class->error("no $arg specified") - unless ($cfg = shift); - push(@args, $cfg); - } - - # fold all remaining args into a hash, or use provided hash ref -# local $" = ', '; -# print STDERR "args: [@_]\n"; - $cfg = defined $_[0] && UNIVERSAL::isa($_[0], 'HASH') ? shift : { @_ }; - - my $self = bless { - map { ($_ => shift @args) } @$argnames, - _ERROR => '', - DEBUG => 0, - }, $class; - - return $self->_init($cfg) ? $self : $class->error($self->error); -} - - -#------------------------------------------------------------------------ -# error() -# error($msg, ...) -# -# May be called as a class or object method to set or retrieve the -# package variable $ERROR (class method) or internal member -# $self->{ _ERROR } (object method). The presence of parameters indicates -# that the error value should be set. Undef is then returned. In the -# abscence of parameters, the current error value is returned. -#------------------------------------------------------------------------ - -sub error { - my $self = shift; - my $errvar; - - { - no strict qw( refs ); - $errvar = ref $self ? \$self->{ _ERROR } : \${"$self\::ERROR"}; - } - if (@_) { - $$errvar = ref($_[0]) ? shift : join('', @_); - return undef; - } - else { - return $$errvar; - } -} - - -#------------------------------------------------------------------------ -# _init() -# -# Initialisation method called by the new() constructor and passing a -# reference to a hash array containing any configuration items specified -# as constructor arguments. Should return $self on success or undef on -# error, via a call to the error() method to set the error message. -#------------------------------------------------------------------------ - -sub _init { - my ($self, $config) = @_; - return $self; -} - - -sub DEBUG { - my $self = shift; - print STDERR "DEBUG: ", @_; -} - -sub debug { - my $self = shift; - my $msg = join('', @_); - my ($pkg, $file, $line) = caller(); - - unless ($msg =~ /\n$/) { - $msg .= ($self->{ DEBUG } & Template::Constants::DEBUG_CALLER) - ? " at $file line $line\n" - : "\n"; - } - - print STDERR "[$pkg] $msg"; -} - - -#------------------------------------------------------------------------ -# module_version() -# -# Returns the current version number. -#------------------------------------------------------------------------ - -sub module_version { - my $self = shift; - my $class = ref $self || $self; - no strict 'refs'; - return ${"${class}::VERSION"}; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Base - Base class module implementing common functionality - -=head1 SYNOPSIS - - package My::Module; - use base qw( Template::Base ); - - sub _init { - my ($self, $config) = @_; - $self->{ doodah } = $config->{ doodah } - || return $self->error("No 'doodah' specified"); - return $self; - } - - package main; - - my $object = My::Module->new({ doodah => 'foobar' }) - || die My::Module->error(); - -=head1 DESCRIPTION - -Base class module which implements a constructor and error reporting -functionality for various Template Toolkit modules. - -=head1 PUBLIC METHODS - -=head2 new(\%config) - -Constructor method which accepts a reference to a hash array or a list -of C<name =E<gt> value> parameters which are folded into a hash. The -_init() method is then called, passing the configuration hash and should -return true/false to indicate success or failure. A new object reference -is returned, or undef on error. Any error message raised can be examined -via the error() class method or directly via the package variable ERROR -in the derived class. - - my $module = My::Module->new({ ... }) - || die My::Module->error(), "\n"; - - my $module = My::Module->new({ ... }) - || die "constructor error: $My::Module::ERROR\n"; - -=head2 error($msg, ...) - -May be called as an object method to get/set the internal _ERROR member -or as a class method to get/set the $ERROR variable in the derived class's -package. - - my $module = My::Module->new({ ... }) - || die My::Module->error(), "\n"; - - $module->do_something() - || die $module->error(), "\n"; - -When called with parameters (multiple params are concatenated), this -method will set the relevant variable and return undef. This is most -often used within object methods to report errors to the caller. - - package My::Module; - - sub foobar { - my $self = shift; - - # some other code... - - return $self->error('some kind of error...') - if $some_condition; - } - -=head2 debug($msg, ...) - -Generates a debugging message by concatenating all arguments -passed into a string and printing it to STDERR. A prefix is -added to indicate the module of the caller. - - package My::Module; - - sub foobar { - my $self = shift; - - $self->debug('called foobar()'); - - # some other code... - } - -When the foobar() method is called, the following message -is sent to STDERR: - - [My::Module] called foobar() - -Objects can set an internal DEBUG value which the debug() -method will examine. If this value sets the relevant bits -to indicate DEBUG_CALLER then the file and line number of -the caller will be appened to the message. - - use Template::Constants qw( :debug ); - - my $module = My::Module->new({ - DEBUG => DEBUG_SERVICE | DEBUG_CONTEXT | DEBUG_CALLER, - }); - - $module->foobar(); - -This generates an error message such as: - - [My::Module] called foobar() at My/Module.pm line 6 - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Config.pm b/lib/Template/Config.pm deleted file mode 100644 index 9a3f378..0000000 --- a/lib/Template/Config.pm +++ /dev/null @@ -1,467 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Config -# -# DESCRIPTION -# Template Toolkit configuration module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#------------------------------------------------------------------------ -# -# $Id: Config.pm,v 2.67 2004/01/13 16:19:10 abw Exp $ -# -#======================================================================== - -package Template::Config; - -require 5.004; - -use strict; -use base qw( Template::Base ); -use vars qw( $VERSION $DEBUG $ERROR $INSTDIR - $PARSER $PROVIDER $PLUGINS $FILTERS $ITERATOR - $LATEX_PATH $PDFLATEX_PATH $DVIPS_PATH - $STASH $SERVICE $CONTEXT $CONSTANTS @PRELOAD ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.67 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; -$ERROR = ''; -$CONTEXT = 'Template::Context'; -$FILTERS = 'Template::Filters'; -$ITERATOR = 'Template::Iterator'; -$PARSER = 'Template::Parser'; -$PLUGINS = 'Template::Plugins'; -$PROVIDER = 'Template::Provider'; -$SERVICE = 'Template::Service'; -$STASH = 'Template::Stash'; -$CONSTANTS = 'Template::Namespace::Constants'; - -@PRELOAD = ( $CONTEXT, $FILTERS, $ITERATOR, $PARSER, - $PLUGINS, $PROVIDER, $SERVICE, $STASH ); - -# the following is set at installation time by the Makefile.PL -$INSTDIR = ''; - -# LaTeX executable paths set at installation time by the Makefile.PL -# Empty strings cause the latex(pdf|dvi|ps) filters to throw an error. -$LATEX_PATH = ''; -$PDFLATEX_PATH = ''; -$DVIPS_PATH = ''; - -#======================================================================== -# --- CLASS METHODS --- -#======================================================================== - -#------------------------------------------------------------------------ -# preload($module, $module, ...) -# -# Preloads all the standard TT modules that are likely to be used, along -# with any other passed as arguments. -#------------------------------------------------------------------------ - -sub preload { - my $class = shift; - - foreach my $module (@PRELOAD, @_) { - $class->load($module) || return; - }; - return 1; -} - - -#------------------------------------------------------------------------ -# load($module) -# -# Load a module via require(). Any occurences of '::' in the module name -# are be converted to '/' and '.pm' is appended. Returns 1 on success -# or undef on error. Use $class->error() to examine the error string. -#------------------------------------------------------------------------ - -sub load { - my ($class, $module) = @_; - $module =~ s[::][/]g; - $module .= '.pm'; -# print STDERR "loading $module\n" -# if $DEBUG; - eval { - require $module; - }; - return $@ ? $class->error("failed to load $module: $@") : 1; -} - - -#------------------------------------------------------------------------ -# parser(\%params) -# -# Instantiate a new parser object of the class whose name is denoted by -# the package variable $PARSER (default: Template::Parser). Returns -# a reference to a newly instantiated parser object or undef on error. -# The class error() method can be called without arguments to examine -# the error message generated by this failure. -#------------------------------------------------------------------------ - -sub parser { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($PARSER); - return $PARSER->new($params) - || $class->error("failed to create parser: ", $PARSER->error); -} - - -#------------------------------------------------------------------------ -# provider(\%params) -# -# Instantiate a new template provider object (default: Template::Provider). -# Returns an object reference or undef on error, as above. -#------------------------------------------------------------------------ - -sub provider { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($PROVIDER); - return $PROVIDER->new($params) - || $class->error("failed to create template provider: ", - $PROVIDER->error); -} - - -#------------------------------------------------------------------------ -# plugins(\%params) -# -# Instantiate a new plugins provider object (default: Template::Plugins). -# Returns an object reference or undef on error, as above. -#------------------------------------------------------------------------ - -sub plugins { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($PLUGINS); - return $PLUGINS->new($params) - || $class->error("failed to create plugin provider: ", - $PLUGINS->error); -} - - -#------------------------------------------------------------------------ -# filters(\%params) -# -# Instantiate a new filters provider object (default: Template::Filters). -# Returns an object reference or undef on error, as above. -#------------------------------------------------------------------------ - -sub filters { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($FILTERS); - return $FILTERS->new($params) - || $class->error("failed to create filter provider: ", - $FILTERS->error); -} - - -#------------------------------------------------------------------------ -# iterator(\@list) -# -# Instantiate a new Template::Iterator object (default: Template::Iterator). -# Returns an object reference or undef on error, as above. -#------------------------------------------------------------------------ - -sub iterator { - my $class = shift; - my $list = shift; - - return undef unless $class->load($ITERATOR); - return $ITERATOR->new($list, @_) - || $class->error("failed to create iterator: ", $ITERATOR->error); -} - - -#------------------------------------------------------------------------ -# stash(\%vars) -# -# Instantiate a new template variable stash object (default: -# Template::Stash). Returns object or undef, as above. -#------------------------------------------------------------------------ - -sub stash { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($STASH); - return $STASH->new($params) - || $class->error("failed to create stash: ", $STASH->error); -} - - -#------------------------------------------------------------------------ -# context(\%params) -# -# Instantiate a new template context object (default: Template::Context). -# Returns object or undef, as above. -#------------------------------------------------------------------------ - -sub context { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($CONTEXT); - return $CONTEXT->new($params) - || $class->error("failed to create context: ", $CONTEXT->error); -} - - -#------------------------------------------------------------------------ -# service(\%params) -# -# Instantiate a new template context object (default: Template::Service). -# Returns object or undef, as above. -#------------------------------------------------------------------------ - -sub service { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($SERVICE); - return $SERVICE->new($params) - || $class->error("failed to create context: ", $SERVICE->error); -} - - -#------------------------------------------------------------------------ -# constants(\%params) -# -# Instantiate a new namespace handler for compile time constant folding -# (default: Template::Namespace::Constants). -# Returns object or undef, as above. -#------------------------------------------------------------------------ - -sub constants { - my $class = shift; - my $params = defined($_[0]) && UNIVERSAL::isa($_[0], 'HASH') - ? shift : { @_ }; - - return undef unless $class->load($CONSTANTS); - return $CONSTANTS->new($params) - || $class->error("failed to create constants namespace: ", - $CONSTANTS->error); -} - - -#------------------------------------------------------------------------ -# instdir($dir) -# -# Returns the root installation directory appended with any local -# component directory passed as an argument. -#------------------------------------------------------------------------ - -sub instdir { - my ($class, $dir) = @_; - my $inst = $INSTDIR - || return $class->error("no installation directory"); - $inst =~ s[/$][]g; - $inst .= "/$dir" if $dir; - return $inst; -} - -#------------------------------------------------------------------------ -# latexpaths() -# -# Returns a reference to a three element array: -# [latex_path, pdf2latex_path, dvips_path] -# These values are determined by Makefile.PL at installation time -# and are used by the latex(pdf|dvi|ps) filters. -#------------------------------------------------------------------------ - -sub latexpaths { - return [$LATEX_PATH, $PDFLATEX_PATH, $DVIPS_PATH]; -} - -#======================================================================== -# This should probably be moved somewhere else in the long term, but for -# now it ensures that Template::TieString is available even if the -# Template::Directive module hasn't been loaded, as is the case when -# using compiled templates and Template::Parser hasn't yet been loaded -# on demand. -#======================================================================== - -#------------------------------------------------------------------------ -# simple package for tying $output variable to STDOUT, used by perl() -#------------------------------------------------------------------------ - -package Template::TieString; - -sub TIEHANDLE { - my ($class, $textref) = @_; - bless $textref, $class; -} -sub PRINT { - my $self = shift; - $$self .= join('', @_); -} - - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Config - Factory module for instantiating other TT2 modules - -=head1 SYNOPSIS - - use Template::Config; - -=head1 DESCRIPTION - -This module implements various methods for loading and instantiating -other modules that comprise the Template Toolkit. It provides a consistent -way to create toolkit components and allows custom modules to be used in -place of the regular ones. - -Package variables such as $STASH, $SERVICE, $CONTEXT, etc., contain -the default module/package name for each component (Template::Stash, -Template::Service and Template::Context, respectively) and are used by -the various factory methods (stash(), service() and context()) to load -the appropriate module. Changing these package variables will cause -subsequent calls to the relevant factory method to load and instantiate -an object from the new class. - -=head1 PUBLIC METHODS - -=head2 load($module) - -Load a module via require(). Any occurences of '::' in the module name -are be converted to '/' and '.pm' is appended. Returns 1 on success -or undef on error. Use $class-E<gt>error() to examine the error string. - -=head2 preload() - -This method preloads all the other Template::* modules that are likely -to be used. It is called by the Template module when running under -mod_perl ($ENV{MOD_PERL} is set). - -=head2 parser(\%config) - -Instantiate a new parser object of the class whose name is denoted by -the package variable $PARSER (default: Template::Parser). Returns -a reference to a newly instantiated parser object or undef on error. - -=head2 provider(\%config) - -Instantiate a new template provider object (default: Template::Provider). -Returns an object reference or undef on error, as above. - -=head2 plugins(\%config) - -Instantiate a new plugins provider object (default: Template::Plugins). -Returns an object reference or undef on error, as above. - -=head2 filters(\%config) - -Instantiate a new filter provider object (default: Template::Filters). -Returns an object reference or undef on error, as above. - -=head2 stash(\%vars) - -Instantiate a new stash object (Template::Stash or Template::Stash::XS -depending on the default set at installation time) using the contents -of the optional hash array passed by parameter as initial variable -definitions. Returns an object reference or undef on error, as above. - -=head2 context(\%config) - -Instantiate a new template context object (default: Template::Context). -Returns an object reference or undef on error, as above. - -=head2 service(\%config) - -Instantiate a new template service object (default: Template::Service). -Returns an object reference or undef on error, as above. - -=head2 instdir($dir) - -Returns the root directory of the Template Toolkit installation under -which optional components are installed. Any relative directory specified -as an argument will be appended to the returned directory. - - # e.g. returns '/usr/local/tt2' - my $ttroot = Template::Config->instdir() - || die "$Template::Config::ERROR\n"; - - # e.g. returns '/usr/local/tt2/templates' - my $template = Template::Config->instdir('templates') - || die "$Template::Config::ERROR\n"; - -Returns undef and sets $Template::Config::ERROR appropriately if the -optional components of the Template Toolkit have not been installed. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.67, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Constants.pm b/lib/Template/Constants.pm deleted file mode 100644 index b227467..0000000 --- a/lib/Template/Constants.pm +++ /dev/null @@ -1,287 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Constants.pm -# -# DESCRIPTION -# Definition of constants for the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Constants.pm,v 2.67 2004/01/13 16:19:10 abw Exp $ -# -#============================================================================ - -package Template::Constants; - -require 5.004; -require Exporter; - -use strict; -use vars qw( $VERSION @ISA @EXPORT_OK %EXPORT_TAGS ); -use vars qw( $DEBUG_OPTIONS @STATUS @ERROR @CHOMP @DEBUG); - -@ISA = qw( Exporter ); -$VERSION = sprintf("%d.%02d", q$Revision: 2.67 $ =~ /(\d+)\.(\d+)/); - - -#======================================================================== -# ----- EXPORTER ----- -#======================================================================== - -# STATUS constants returned by directives -use constant STATUS_OK => 0; # ok -use constant STATUS_RETURN => 1; # ok, block ended by RETURN -use constant STATUS_STOP => 2; # ok, stoppped by STOP -use constant STATUS_DONE => 3; # ok, iterator done -use constant STATUS_DECLINED => 4; # ok, declined to service request -use constant STATUS_ERROR => 255; # error condition - -# ERROR constants for indicating exception types -use constant ERROR_RETURN => 'return'; # return a status code -use constant ERROR_FILE => 'file'; # file error: I/O, parse, recursion -use constant ERROR_VIEW => 'view'; # view error -use constant ERROR_UNDEF => 'undef'; # undefined variable value used -use constant ERROR_PERL => 'perl'; # error in [% PERL %] block -use constant ERROR_FILTER => 'filter'; # filter error -use constant ERROR_PLUGIN => 'plugin'; # plugin error - -# CHOMP constants for PRE_CHOMP and POST_CHOMP -use constant CHOMP_NONE => 0; # do not remove whitespace -use constant CHOMP_ALL => 1; # remove whitespace -use constant CHOMP_COLLAPSE => 2; # collapse whitespace to a single space - -# DEBUG constants to enable various debugging options -use constant DEBUG_OFF => 0; # do nothing -use constant DEBUG_ON => 1; # basic debugging flag -use constant DEBUG_UNDEF => 2; # throw undef on undefined variables -use constant DEBUG_VARS => 4; # general variable debugging -use constant DEBUG_DIRS => 8; # directive debugging -use constant DEBUG_STASH => 16; # general stash debugging -use constant DEBUG_CONTEXT => 32; # context debugging -use constant DEBUG_PARSER => 64; # parser debugging -use constant DEBUG_PROVIDER => 128; # provider debugging -use constant DEBUG_PLUGINS => 256; # plugins debugging -use constant DEBUG_FILTERS => 512; # filters debugging -use constant DEBUG_SERVICE => 1024; # context debugging -use constant DEBUG_ALL => 2047; # everything - -# extra debugging flags -use constant DEBUG_CALLER => 4096; # add caller file/line -use constant DEBUG_FLAGS => 4096; # bitmask to extraxt flags - -$DEBUG_OPTIONS = { - &DEBUG_OFF => off => off => &DEBUG_OFF, - &DEBUG_ON => on => on => &DEBUG_ON, - &DEBUG_UNDEF => undef => undef => &DEBUG_UNDEF, - &DEBUG_VARS => vars => vars => &DEBUG_VARS, - &DEBUG_DIRS => dirs => dirs => &DEBUG_DIRS, - &DEBUG_STASH => stash => stash => &DEBUG_STASH, - &DEBUG_CONTEXT => context => context => &DEBUG_CONTEXT, - &DEBUG_PARSER => parser => parser => &DEBUG_PARSER, - &DEBUG_PROVIDER => provider => provider => &DEBUG_PROVIDER, - &DEBUG_PLUGINS => plugins => plugins => &DEBUG_PLUGINS, - &DEBUG_FILTERS => filters => filters => &DEBUG_FILTERS, - &DEBUG_SERVICE => service => service => &DEBUG_SERVICE, - &DEBUG_ALL => all => all => &DEBUG_ALL, - &DEBUG_CALLER => caller => caller => &DEBUG_CALLER, -}; - -@STATUS = qw( STATUS_OK STATUS_RETURN STATUS_STOP STATUS_DONE - STATUS_DECLINED STATUS_ERROR ); -@ERROR = qw( ERROR_FILE ERROR_VIEW ERROR_UNDEF ERROR_PERL - ERROR_RETURN ERROR_FILTER ERROR_PLUGIN ); -@CHOMP = qw( CHOMP_NONE CHOMP_ALL CHOMP_COLLAPSE ); -@DEBUG = qw( DEBUG_OFF DEBUG_ON DEBUG_UNDEF DEBUG_VARS - DEBUG_DIRS DEBUG_STASH DEBUG_CONTEXT DEBUG_PARSER - DEBUG_PROVIDER DEBUG_PLUGINS DEBUG_FILTERS DEBUG_SERVICE - DEBUG_ALL DEBUG_CALLER DEBUG_FLAGS ); - -@EXPORT_OK = ( @STATUS, @ERROR, @CHOMP, @DEBUG ); -%EXPORT_TAGS = ( - 'all' => [ @EXPORT_OK ], - 'status' => [ @STATUS ], - 'error' => [ @ERROR ], - 'chomp' => [ @CHOMP ], - 'debug' => [ @DEBUG ], -); - - -sub debug_flags { - my ($self, $debug) = @_; - my (@flags, $flag, $value); - $debug = $self unless defined($debug) || ref($self); - - if ($debug =~ /^\d+$/) { - foreach $flag (@DEBUG) { - next if $flag =~ /^DEBUG_(OFF|ALL|FLAGS)$/; - - # don't trash the original - my $copy = $flag; - $flag =~ s/^DEBUG_//; - $flag = lc $flag; - return $self->error("no value for flag: $flag") - unless defined($value = $DEBUG_OPTIONS->{ $flag }); - $flag = $value; - - if ($debug & $flag) { - $value = $DEBUG_OPTIONS->{ $flag }; - return $self->error("no value for flag: $flag") unless defined $value; - push(@flags, $value); - } - } - return wantarray ? @flags : join(', ', @flags); - } - else { - @flags = split(/\W+/, $debug); - $debug = 0; - foreach $flag (@flags) { - $value = $DEBUG_OPTIONS->{ $flag }; - return $self->error("unknown debug flag: $flag") unless defined $value; - $debug |= $value; - } - return $debug; - } -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Constants - Defines constants for the Template Toolkit - -=head1 SYNOPSIS - - use Template::Constants qw( :status :error :all ); - -=head1 DESCRIPTION - -The Template::Constants modules defines, and optionally exports into the -caller's namespace, a number of constants used by the Template package. - -Constants may be used by specifying the Template::Constants package -explicitly: - - use Template::Constants; - - print Template::Constants::STATUS_DECLINED; - -Constants may be imported into the caller's namespace by naming them as -options to the C<use Template::Constants> statement: - - use Template::Constants qw( STATUS_DECLINED ); - - print STATUS_DECLINED; - -Alternatively, one of the following tagset identifiers may be specified -to import sets of constants; :status, :error, :all. - - use Template::Constants qw( :status ); - - print STATUS_DECLINED; - -See L<Exporter> for more information on exporting variables. - -=head1 EXPORTABLE TAG SETS - -The following tag sets and associated constants are defined: - - :status - STATUS_OK # no problem, continue - STATUS_RETURN # ended current block then continue (ok) - STATUS_STOP # controlled stop (ok) - STATUS_DONE # iterator is all done (ok) - STATUS_DECLINED # provider declined to service request (ok) - STATUS_ERROR # general error condition (not ok) - - :error - ERROR_RETURN # return a status code (e.g. 'stop') - ERROR_FILE # file error: I/O, parse, recursion - ERROR_UNDEF # undefined variable value used - ERROR_PERL # error in [% PERL %] block - ERROR_FILTER # filter error - ERROR_PLUGIN # plugin error - - :chomp # for PRE_CHOMP and POST_CHOMP - CHOMP_NONE # do not remove whitespace - CHOMP_ALL # remove whitespace - CHOMP_COLLAPSE # collapse whitespace to a single space - - :debug - DEBUG_OFF # do nothing - DEBUG_ON # basic debugging flag - DEBUG_UNDEF # throw undef on undefined variables - DEBUG_VARS # general variable debugging - DEBUG_DIRS # directive debugging - DEBUG_STASH # general stash debugging - DEBUG_CONTEXT # context debugging - DEBUG_PARSER # parser debugging - DEBUG_PROVIDER # provider debugging - DEBUG_PLUGINS # plugins debugging - DEBUG_FILTERS # filters debugging - DEBUG_SERVICE # context debugging - DEBUG_ALL # everything - DEBUG_CALLER # add caller file/line info - DEBUG_FLAGS # bitmap used internally - - :all All the above constants. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.67, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Exporter|Exporter> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Context.pm b/lib/Template/Context.pm deleted file mode 100644 index cdc699e..0000000 --- a/lib/Template/Context.pm +++ /dev/null @@ -1,1570 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Context -# -# DESCRIPTION -# Module defining a context in which a template document is processed. -# This is the runtime processing interface through which templates -# can access the functionality of the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -# REVISION -# $Id: Context.pm,v 2.89 2004/01/30 18:37:47 abw Exp $ -# -#============================================================================ - -package Template::Context; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $AUTOLOAD $DEBUG_FORMAT ); -use base qw( Template::Base ); - -use Template::Base; -use Template::Config; -use Template::Constants; -use Template::Exception; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.89 $ =~ /(\d+)\.(\d+)/); -$DEBUG_FORMAT = "\n## \$file line \$line : [% \$text %] ##\n"; - - -#======================================================================== -# ----- PUBLIC METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# template($name) -# -# General purpose method to fetch a template and return it in compiled -# form. In the usual case, the $name parameter will be a simple string -# containing the name of a template (e.g. 'header'). It may also be -# a reference to Template::Document object (or sub-class) or a Perl -# sub-routine. These are considered to be compiled templates and are -# returned intact. Finally, it may be a reference to any other kind -# of valid input source accepted by Template::Provider (e.g. scalar -# ref, glob, IO handle, etc). -# -# Templates may be cached at one of 3 different levels. The internal -# BLOCKS member is a local cache which holds references to all -# template blocks used or imported via PROCESS since the context's -# reset() method was last called. This is checked first and if the -# template is not found, the method then walks down the BLOCKSTACK -# list. This contains references to the block definition tables in -# any enclosing Template::Documents that we're visiting (e.g. we've -# been called via an INCLUDE and we want to access a BLOCK defined in -# the template that INCLUDE'd us). If nothing is defined, then we -# iterate through the LOAD_TEMPLATES providers list as a 'chain of -# responsibility' (see Design Patterns) asking each object to fetch() -# the template if it can. -# -# Returns the compiled template. On error, undef is returned and -# the internal ERROR value (read via error()) is set to contain an -# error message of the form "$name: $error". -#------------------------------------------------------------------------ - -sub template { - my ($self, $name) = @_; - my ($prefix, $blocks, $defblocks, $provider, $template, $error); - my ($shortname, $blockname, $providers); - - $self->debug("template($name)") if $self->{ DEBUG }; - - # references to Template::Document (or sub-class) objects objects, or - # CODE references are assumed to be pre-compiled templates and are - # returned intact - return $name - if UNIVERSAL::isa($name, 'Template::Document') - || ref($name) eq 'CODE'; - - $shortname = $name; - - unless (ref $name) { - - $self->debug("looking for block [$name]") if $self->{ DEBUG }; - - # we first look in the BLOCKS hash for a BLOCK that may have - # been imported from a template (via PROCESS) - return $template - if ($template = $self->{ BLOCKS }->{ $name }); - - # then we iterate through the BLKSTACK list to see if any of the - # Template::Documents we're visiting define this BLOCK - foreach $blocks (@{ $self->{ BLKSTACK } }) { - return $template - if $blocks && ($template = $blocks->{ $name }); - } - - # now it's time to ask the providers, so we look to see if any - # prefix is specified to indicate the desired provider set. - if ($^O eq 'MSWin32') { - # let C:/foo through - $prefix = $1 if $shortname =~ s/^(\w{2,})://o; - } - else { - $prefix = $1 if $shortname =~ s/^(\w+)://; - } - - if (defined $prefix) { - $providers = $self->{ PREFIX_MAP }->{ $prefix } - || return $self->throw( Template::Constants::ERROR_FILE, - "no providers for template prefix '$prefix'"); - } - } - $providers = $self->{ PREFIX_MAP }->{ default } - || $self->{ LOAD_TEMPLATES } - unless $providers; - - - # Finally we try the regular template providers which will - # handle references to files, text, etc., as well as templates - # reference by name. If - - $blockname = ''; - while ($shortname) { - $self->debug("asking providers for [$shortname] [$blockname]") - if $self->{ DEBUG }; - - foreach my $provider (@$providers) { - ($template, $error) = $provider->fetch($shortname, $prefix); - if ($error) { - if ($error == Template::Constants::STATUS_ERROR) { - # $template contains exception object - if (UNIVERSAL::isa($template, 'Template::Exception') - && $template->type() eq Template::Constants::ERROR_FILE) { - $self->throw($template); - } - else { - $self->throw( Template::Constants::ERROR_FILE, $template ); - } - } - # DECLINE is ok, carry on - } - elsif (length $blockname) { - return $template - if $template = $template->blocks->{ $blockname }; - } - else { - return $template; - } - } - - last if ref $shortname || ! $self->{ EXPOSE_BLOCKS }; - $shortname =~ s{/([^/]+)$}{} || last; - $blockname = length $blockname ? "$1/$blockname" : $1; - } - - $self->throw(Template::Constants::ERROR_FILE, "$name: not found"); -} - - -#------------------------------------------------------------------------ -# plugin($name, \@args) -# -# Calls on each of the LOAD_PLUGINS providers in turn to fetch() (i.e. load -# and instantiate) a plugin of the specified name. Additional parameters -# passed are propagated to the new() constructor for the plugin. -# Returns a reference to a new plugin object or other reference. On -# error, undef is returned and the appropriate error message is set for -# subsequent retrieval via error(). -#------------------------------------------------------------------------ - -sub plugin { - my ($self, $name, $args) = @_; - my ($provider, $plugin, $error); - - $self->debug("plugin($name, ", defined $args ? @$args : '[ ]', ')') - if $self->{ DEBUG }; - - # request the named plugin from each of the LOAD_PLUGINS providers in turn - foreach my $provider (@{ $self->{ LOAD_PLUGINS } }) { - ($plugin, $error) = $provider->fetch($name, $args, $self); - return $plugin unless $error; - if ($error == Template::Constants::STATUS_ERROR) { - $self->throw($plugin) if ref $plugin; - $self->throw(Template::Constants::ERROR_PLUGIN, $plugin); - } - } - - $self->throw(Template::Constants::ERROR_PLUGIN, "$name: plugin not found"); -} - - -#------------------------------------------------------------------------ -# filter($name, \@args, $alias) -# -# Similar to plugin() above, but querying the LOAD_FILTERS providers to -# return filter instances. An alias may be provided which is used to -# save the returned filter in a local cache. -#------------------------------------------------------------------------ - -sub filter { - my ($self, $name, $args, $alias) = @_; - my ($provider, $filter, $error); - - $self->debug("filter($name, ", - defined $args ? @$args : '[ ]', - defined $alias ? $alias : '<no alias>', ')') - if $self->{ DEBUG }; - - # use any cached version of the filter if no params provided - return $filter - if ! $args && ! ref $name - && ($filter = $self->{ FILTER_CACHE }->{ $name }); - - # request the named filter from each of the FILTERS providers in turn - foreach my $provider (@{ $self->{ LOAD_FILTERS } }) { - ($filter, $error) = $provider->fetch($name, $args, $self); - last unless $error; - if ($error == Template::Constants::STATUS_ERROR) { - $self->throw($filter) if ref $filter; - $self->throw(Template::Constants::ERROR_FILTER, $filter); - } - # return $self->error($filter) - # if $error == &Template::Constants::STATUS_ERROR; - } - - return $self->error("$name: filter not found") - unless $filter; - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # commented out by abw on 19 Nov 2001 to fix problem with xmlstyle - # plugin which may re-define a filter by calling define_filter() - # multiple times. With the automatic aliasing/caching below, any - # new filter definition isn't seen. Don't think this will cause - # any problems as filters explicitly supplied with aliases will - # still work as expected. - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # alias defaults to name if undefined - # $alias = $name - # unless defined($alias) or ref($name) or $args; - - # cache FILTER if alias is valid - $self->{ FILTER_CACHE }->{ $alias } = $filter - if $alias; - - return $filter; -} - - -#------------------------------------------------------------------------ -# view(\%config) -# -# Create a new Template::View bound to this context. -#------------------------------------------------------------------------ - -sub view { - my $self = shift; - require Template::View; - return Template::View->new($self, @_) - || $self->throw(&Template::Constants::ERROR_VIEW, - $Template::View::ERROR); -} - - -#------------------------------------------------------------------------ -# process($template, \%params) [% PROCESS template var=val ... %] -# process($template, \%params, $local) [% INCLUDE template var=val ... %] -# -# Processes the template named or referenced by the first parameter. -# The optional second parameter may reference a hash array of variable -# definitions. These are set before the template is processed by -# calling update() on the stash. Note that, unless the third parameter -# is true, the context is not localised and these, and any other -# variables set in the template will retain their new values after this -# method returns. The third parameter is in place so that this method -# can handle INCLUDE calls: the stash will be localized. -# -# Returns the output of processing the template. Errors are thrown -# as Template::Exception objects via die(). -#------------------------------------------------------------------------ - -sub process { - my ($self, $template, $params, $localize) = @_; - my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) }; - my (@compiled, $name, $compiled); - my ($stash, $component, $tblocks, $error, $tmpout); - my $output = ''; - - $template = [ $template ] unless ref $template eq 'ARRAY'; - - $self->debug("process([ ", join(', '), @$template, ' ], ', - defined $params ? $params : '<no params>', ', ', - $localize ? '<localized>' : '<unlocalized>', ')') - if $self->{ DEBUG }; - - # fetch compiled template for each name specified - foreach $name (@$template) { - push(@compiled, $self->template($name)); - } - - if ($localize) { - # localise the variable stash with any parameters passed - $stash = $self->{ STASH } = $self->{ STASH }->clone($params); - } else { - # update stash with any new parameters passed - $self->{ STASH }->update($params); - $stash = $self->{ STASH }; - } - - eval { - # save current component - eval { $component = $stash->get('component') }; - - foreach $name (@$template) { - $compiled = shift @compiled; - my $element = ref $compiled eq 'CODE' - ? { (name => (ref $name ? '' : $name), modtime => time()) } - : $compiled; - - if (UNIVERSAL::isa($component, 'Template::Document')) { - $element->{ caller } = $component->{ name }; - $element->{ callers } = $component->{ callers } || []; - push(@{$element->{ callers }}, $element->{ caller }); - } - - $stash->set('component', $element); - - unless ($localize) { - # merge any local blocks defined in the Template::Document - # into our local BLOCKS cache - @$blocks{ keys %$tblocks } = values %$tblocks - if UNIVERSAL::isa($compiled, 'Template::Document') - && ($tblocks = $compiled->blocks()); - } - - if (ref $compiled eq 'CODE') { - $tmpout = &$compiled($self); - } - elsif (ref $compiled) { - $tmpout = $compiled->process($self); - } - else { - $self->throw('file', - "invalid template reference: $compiled"); - } - - if ($trim) { - for ($tmpout) { - s/^\s+//; - s/\s+$//; - } - } - $output .= $tmpout; - } - $stash->set('component', $component); - }; - $error = $@; - - if ($localize) { - # ensure stash is delocalised before dying - $self->{ STASH } = $self->{ STASH }->declone(); - } - - $self->throw(ref $error - ? $error : (Template::Constants::ERROR_FILE, $error)) - if $error; - - return $output; -} - - -#------------------------------------------------------------------------ -# include($template, \%params) [% INCLUDE template var = val, ... %] -# -# Similar to process() above but processing the template in a local -# context. Any variables passed by reference to a hash as the second -# parameter will be set before the template is processed and then -# revert to their original values before the method returns. Similarly, -# any changes made to non-global variables within the template will -# persist only until the template is processed. -# -# Returns the output of processing the template. Errors are thrown -# as Template::Exception objects via die(). -#------------------------------------------------------------------------ - -sub include { - my ($self, $template, $params) = @_; - return $self->process($template, $params, 'localize me!'); -} - -#------------------------------------------------------------------------ -# insert($file) -# -# Insert the contents of a file without parsing. -#------------------------------------------------------------------------ - -sub insert { - my ($self, $file) = @_; - my ($prefix, $providers, $text, $error); - my $output = ''; - - my $files = ref $file eq 'ARRAY' ? $file : [ $file ]; - - $self->debug("insert([ ", join(', '), @$files, " ])") - if $self->{ DEBUG }; - - - FILE: foreach $file (@$files) { - my $name = $file; - - if ($^O eq 'MSWin32') { - # let C:/foo through - $prefix = $1 if $name =~ s/^(\w{2,})://o; - } - else { - $prefix = $1 if $name =~ s/^(\w+)://; - } - - if (defined $prefix) { - $providers = $self->{ PREFIX_MAP }->{ $prefix } - || return $self->throw(Template::Constants::ERROR_FILE, - "no providers for file prefix '$prefix'"); - } - else { - $providers = $self->{ PREFIX_MAP }->{ default } - || $self->{ LOAD_TEMPLATES }; - } - - foreach my $provider (@$providers) { - ($text, $error) = $provider->load($name, $prefix); - next FILE unless $error; - if ($error == Template::Constants::STATUS_ERROR) { - $self->throw($text) if ref $text; - $self->throw(Template::Constants::ERROR_FILE, $text); - } - } - $self->throw(Template::Constants::ERROR_FILE, "$file: not found"); - } - continue { - $output .= $text; - } - return $output; -} - - -#------------------------------------------------------------------------ -# throw($type, $info, \$output) [% THROW errtype "Error info" %] -# -# Throws a Template::Exception object by calling die(). This method -# may be passed a reference to an existing Template::Exception object; -# a single value containing an error message which is used to -# instantiate a Template::Exception of type 'undef'; or a pair of -# values representing the exception type and info from which a -# Template::Exception object is instantiated. e.g. -# -# $context->throw($exception); -# $context->throw("I'm sorry Dave, I can't do that"); -# $context->throw('denied', "I'm sorry Dave, I can't do that"); -# -# An optional third parameter can be supplied in the last case which -# is a reference to the current output buffer containing the results -# of processing the template up to the point at which the exception -# was thrown. The RETURN and STOP directives, for example, use this -# to propagate output back to the user, but it can safely be ignored -# in most cases. -# -# This method rides on a one-way ticket to die() oblivion. It does not -# return in any real sense of the word, but should get caught by a -# surrounding eval { } block (e.g. a BLOCK or TRY) and handled -# accordingly, or returned to the caller as an uncaught exception. -#------------------------------------------------------------------------ - -sub throw { - my ($self, $error, $info, $output) = @_; - local $" = ', '; - - # die! die! die! - if (UNIVERSAL::isa($error, 'Template::Exception')) { - die $error; - } - elsif (defined $info) { - die (Template::Exception->new($error, $info, $output)); - } - else { - $error ||= ''; - die (Template::Exception->new('undef', $error, $output)); - } - - # not reached -} - - -#------------------------------------------------------------------------ -# catch($error, \$output) -# -# Called by various directives after catching an error thrown via die() -# from within an eval { } block. The first parameter contains the errror -# which may be a sanitized reference to a Template::Exception object -# (such as that raised by the throw() method above, a plugin object, -# and so on) or an error message thrown via die from somewhere in user -# code. The latter are coerced into 'undef' Template::Exception objects. -# Like throw() above, a reference to a scalar may be passed as an -# additional parameter to represent the current output buffer -# localised within the eval block. As exceptions are thrown upwards -# and outwards from nested blocks, the catch() method reconstructs the -# correct output buffer from these fragments, storing it in the -# exception object for passing further onwards and upwards. -# -# Returns a reference to a Template::Exception object.. -#------------------------------------------------------------------------ - -sub catch { - my ($self, $error, $output) = @_; - - if (UNIVERSAL::isa($error, 'Template::Exception')) { - $error->text($output) if $output; - return $error; - } - else { - return Template::Exception->new('undef', $error, $output); - } -} - - -#------------------------------------------------------------------------ -# localise(\%params) -# delocalise() -# -# The localise() method creates a local copy of the current stash, -# allowing the existing state of variables to be saved and later -# restored via delocalise(). -# -# A reference to a hash array may be passed containing local variable -# definitions which should be added to the cloned namespace. These -# values persist until delocalisation. -#------------------------------------------------------------------------ - -sub localise { - my $self = shift; - $self->{ STASH } = $self->{ STASH }->clone(@_); -} - -sub delocalise { - my $self = shift; - $self->{ STASH } = $self->{ STASH }->declone(); -} - - -#------------------------------------------------------------------------ -# visit($document, $blocks) -# -# Each Template::Document calls the visit() method on the context -# before processing itself. It passes a reference to the hash array -# of named BLOCKs defined within the document, allowing them to be -# added to the internal BLKSTACK list which is subsequently used by -# template() to resolve templates. -# from a provider. -#------------------------------------------------------------------------ - -sub visit { - my ($self, $document, $blocks) = @_; - unshift(@{ $self->{ BLKSTACK } }, $blocks) -} - - -#------------------------------------------------------------------------ -# leave() -# -# The leave() method is called when the document has finished -# processing itself. This removes the entry from the BLKSTACK list -# that was added visit() above. For persistance of BLOCK definitions, -# the process() method (i.e. the PROCESS directive) does some extra -# magic to copy BLOCKs into a shared hash. -#------------------------------------------------------------------------ - -sub leave { - my $self = shift; - shift(@{ $self->{ BLKSTACK } }); -} - - -#------------------------------------------------------------------------ -# define_block($name, $block) -# -# Adds a new BLOCK definition to the local BLOCKS cache. $block may -# be specified as a reference to a sub-routine or Template::Document -# object or as text which is compiled into a template. Returns a true -# value (the $block reference or compiled block reference) if -# succesful or undef on failure. Call error() to retrieve the -# relevent error message (i.e. compilation failure). -#------------------------------------------------------------------------ - -sub define_block { - my ($self, $name, $block) = @_; - $block = $self->template(\$block) - || return undef - unless ref $block; - $self->{ BLOCKS }->{ $name } = $block; -} - - -#------------------------------------------------------------------------ -# define_filter($name, $filter, $is_dynamic) -# -# Adds a new FILTER definition to the local FILTER_CACHE. -#------------------------------------------------------------------------ - -sub define_filter { - my ($self, $name, $filter, $is_dynamic) = @_; - my ($result, $error); - $filter = [ $filter, 1 ] if $is_dynamic; - - foreach my $provider (@{ $self->{ LOAD_FILTERS } }) { - ($result, $error) = $provider->store($name, $filter); - return 1 unless $error; - $self->throw(&Template::Constants::ERROR_FILTER, $result) - if $error == &Template::Constants::STATUS_ERROR; - } - $self->throw(&Template::Constants::ERROR_FILTER, - "FILTER providers declined to store filter $name"); -} - - -#------------------------------------------------------------------------ -# reset() -# -# Reset the state of the internal BLOCKS hash to clear any BLOCK -# definitions imported via the PROCESS directive. Any original -# BLOCKS definitions passed to the constructor will be restored. -#------------------------------------------------------------------------ - -sub reset { - my ($self, $blocks) = @_; - $self->{ BLKSTACK } = [ ]; - $self->{ BLOCKS } = { %{ $self->{ INIT_BLOCKS } } }; -} - - -#------------------------------------------------------------------------ -# stash() -# -# Simple accessor methods to return the STASH values. This is likely -# to be called quite often so we provide a direct method rather than -# relying on the slower AUTOLOAD. -#------------------------------------------------------------------------ - -sub stash { - return $_[0]->{ STASH }; -} - - -#------------------------------------------------------------------------ -# define_vmethod($type, $name, \&sub) -# -# Passes $type, $name, and &sub on to stash->define_vmethod(). -#------------------------------------------------------------------------ -sub define_vmethod { - my $self = shift; - $self->stash->define_vmethod(@_); -} - - -#------------------------------------------------------------------------ -# debugging($command, @args, \%params) -# -# Method for controlling the debugging status of the context. The first -# argument can be 'on' or 'off' to enable/disable debugging, 'format' -# to define the format of the debug message, or 'msg' to generate a -# debugging message reporting the file, line, message text, etc., -# according to the current debug format. -#------------------------------------------------------------------------ - -sub debugging { - my $self = shift; - my $hash = ref $_[-1] eq 'HASH' ? pop : { }; - my @args = @_; - -# print "*** debug(@args)\n"; - if (@args) { - if ($args[0] =~ /^on|1$/i) { - $self->{ DEBUG_DIRS } = 1; - shift(@args); - } - elsif ($args[0] =~ /^off|0$/i) { - $self->{ DEBUG_DIRS } = 0; - shift(@args); - } - } - - if (@args) { - if ($args[0] =~ /^msg$/i) { - return unless $self->{ DEBUG_DIRS }; - my $format = $self->{ DEBUG_FORMAT }; - $format = $DEBUG_FORMAT unless defined $format; - $format =~ s/\$(\w+)/$hash->{ $1 }/ge; - return $format; - } - elsif ($args[0] =~ /^format$/i) { - $self->{ DEBUG_FORMAT } = $args[1]; - } - # else ignore - } - - return ''; -} - - -#------------------------------------------------------------------------ -# AUTOLOAD -# -# Provides pseudo-methods for read-only access to various internal -# members. For example, templates(), plugins(), filters(), -# eval_perl(), load_perl(), etc. These aren't called very often, or -# may never be called at all. -#------------------------------------------------------------------------ - -sub AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - my $result; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; - - warn "no such context method/member: $method\n" - unless defined ($result = $self->{ uc $method }); - - return $result; -} - - -#------------------------------------------------------------------------ -# DESTROY -# -# Stash may contain references back to the Context via macro closures, -# etc. This breaks the circular references. -#------------------------------------------------------------------------ - -sub DESTROY { - my $self = shift; - undef $self->{ STASH }; -} - - - -#======================================================================== -# -- PRIVATE METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# _init(\%config) -# -# Initialisation method called by Template::Base::new() -#------------------------------------------------------------------------ - -sub _init { - my ($self, $config) = @_; - my ($name, $item, $method, $block, $blocks); - my @itemlut = ( - LOAD_TEMPLATES => 'provider', - LOAD_PLUGINS => 'plugins', - LOAD_FILTERS => 'filters' - ); - - # LOAD_TEMPLATE, LOAD_PLUGINS, LOAD_FILTERS - lists of providers - while (($name, $method) = splice(@itemlut, 0, 2)) { - $item = $config->{ $name } - || Template::Config->$method($config) - || return $self->error($Template::Config::ERROR); - $self->{ $name } = ref $item eq 'ARRAY' ? $item : [ $item ]; - } - - my $providers = $self->{ LOAD_TEMPLATES }; - my $prefix_map = $self->{ PREFIX_MAP } = $config->{ PREFIX_MAP } || { }; - while (my ($key, $val) = each %$prefix_map) { - $prefix_map->{ $key } = [ ref $val ? $val : - map { $providers->[$_] } - split(/\D+/, $val) ] - unless ref $val eq 'ARRAY'; -# print(STDERR "prefix $key => $val => [", -# join(', ', @{ $prefix_map->{ $key } }), "]\n"); - } - - # STASH - $self->{ STASH } = $config->{ STASH } || do { - my $predefs = $config->{ VARIABLES } - || $config->{ PRE_DEFINE } - || { }; - - # hack to get stash to know about debug mode - $predefs->{ _DEBUG } = ( ($config->{ DEBUG } || 0) - & &Template::Constants::DEBUG_UNDEF ) ? 1 : 0 - unless defined $predefs->{ _DEBUG }; - - Template::Config->stash($predefs) - || return $self->error($Template::Config::ERROR); - }; - - # compile any template BLOCKS specified as text - $blocks = $config->{ BLOCKS } || { }; - $self->{ INIT_BLOCKS } = $self->{ BLOCKS } = { - map { - $block = $blocks->{ $_ }; - $block = $self->template(\$block) - || return undef - unless ref $block; - ($_ => $block); - } - keys %$blocks - }; - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # RECURSION - flag indicating is recursion into templates is supported - # EVAL_PERL - flag indicating if PERL blocks should be processed - # TRIM - flag to remove leading and trailing whitespace from output - # BLKSTACK - list of hashes of BLOCKs defined in current template(s) - # CONFIG - original configuration hash - # EXPOSE_BLOCKS - make blocks visible as pseudo-files - # DEBUG_FORMAT - format for generating template runtime debugging messages - # DEBUG - format for generating template runtime debugging messages - - $self->{ RECURSION } = $config->{ RECURSION } || 0; - $self->{ EVAL_PERL } = $config->{ EVAL_PERL } || 0; - $self->{ TRIM } = $config->{ TRIM } || 0; - $self->{ BLKSTACK } = [ ]; - $self->{ CONFIG } = $config; - $self->{ EXPOSE_BLOCKS } = defined $config->{ EXPOSE_BLOCKS } - ? $config->{ EXPOSE_BLOCKS } - : 0; - - $self->{ DEBUG_FORMAT } = $config->{ DEBUG_FORMAT }; - $self->{ DEBUG_DIRS } = ($config->{ DEBUG } || 0) - & Template::Constants::DEBUG_DIRS; - $self->{ DEBUG } = defined $config->{ DEBUG } - ? $config->{ DEBUG } & ( Template::Constants::DEBUG_CONTEXT - | Template::Constants::DEBUG_FLAGS ) - : $DEBUG; - - return $self; -} - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which returns a string representing the internal state -# of the context object. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $output = "[Template::Context] {\n"; - my $format = " %-16s => %s\n"; - my $key; - - foreach $key (qw( RECURSION EVAL_PERL TRIM )) { - $output .= sprintf($format, $key, $self->{ $key }); - } - foreach my $pname (qw( LOAD_TEMPLATES LOAD_PLUGINS LOAD_FILTERS )) { - my $provtext = "[\n"; - foreach my $prov (@{ $self->{ $pname } }) { - $provtext .= $prov->_dump(); -# $provtext .= ",\n"; - } - $provtext =~ s/\n/\n /g; - $provtext =~ s/\s+$//; - $provtext .= ",\n ]"; - $output .= sprintf($format, $pname, $provtext); - } - $output .= sprintf($format, STASH => $self->{ STASH }->_dump()); - $output .= '}'; - return $output; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Context - Runtime context in which templates are processed - -=head1 SYNOPSIS - - use Template::Context; - - # constructor - $context = Template::Context->new(\%config) - || die $Template::Context::ERROR; - - # fetch (load and compile) a template - $template = $context->template($template_name); - - # fetch (load and instantiate) a plugin object - $plugin = $context->plugin($name, \@args); - - # fetch (return or create) a filter subroutine - $filter = $context->filter($name, \@args, $alias); - - # process/include a template, errors are thrown via die() - $output = $context->process($template, \%vars); - $output = $context->include($template, \%vars); - - # raise an exception via die() - $context->throw($error_type, $error_message, \$output_buffer); - - # catch an exception, clean it up and fix output buffer - $exception = $context->catch($exception, \$output_buffer); - - # save/restore the stash to effect variable localisation - $new_stash = $context->localise(\%vars); - $old_stash = $context->delocalise(); - - # add new BLOCK or FILTER definitions - $context->define_block($name, $block); - $context->define_filter($name, \&filtersub, $is_dynamic); - - # reset context, clearing any imported BLOCK definitions - $context->reset(); - - # methods for accessing internal items - $stash = $context->stash(); - $tflag = $context->trim(); - $epflag = $context->eval_perl(); - $providers = $context->templates(); - $providers = $context->plugins(); - $providers = $context->filters(); - ... - -=head1 DESCRIPTION - -The Template::Context module defines an object class for representing -a runtime context in which templates are processed. It provides an -interface to the fundamental operations of the Template Toolkit -processing engine through which compiled templates (i.e. Perl code -constructed from the template source) can process templates, load -plugins and filters, raise exceptions and so on. - -A default Template::Context object is created by the Template module. -Any Template::Context options may be passed to the Template new() -constructor method and will be forwarded to the Template::Context -constructor. - - use Template; - - my $template = Template->new({ - TRIM => 1, - EVAL_PERL => 1, - BLOCKS => { - header => 'This is the header', - footer => 'This is the footer', - }, - }); - -Similarly, the Template::Context constructor will forward all configuration -parameters onto other default objects (e.g. Template::Provider, Template::Plugins, -Template::Filters, etc.) that it may need to instantiate. - - $context = Template::Context->new({ - INCLUDE_PATH => '/home/abw/templates', # provider option - TAG_STYLE => 'html', # parser option - }); - -A Template::Context object (or subclass/derivative) can be explicitly -instantiated and passed to the Template new() constructor method as -the CONTEXT item. - - use Template; - use Template::Context; - - my $context = Template::Context->new({ TRIM => 1 }); - my $template = Template->new({ CONTEXT => $context }); - -The Template module uses the Template::Config context() factory method -to create a default context object when required. The -$Template::Config::CONTEXT package variable may be set to specify an -alternate context module. This will be loaded automatically and its -new() constructor method called by the context() factory method when -a default context object is required. - - use Template; - - $Template::Config::CONTEXT = 'MyOrg::Template::Context'; - - my $template = Template->new({ - EVAL_PERL => 1, - EXTRA_MAGIC => 'red hot', # your extra config items - ... - }); - -=head1 METHODS - -=head2 new(\%params) - -The new() constructor method is called to instantiate a Template::Context -object. Configuration parameters may be specified as a HASH reference or -as a list of (name =E<gt> value) pairs. - - my $context = Template::Context->new({ - INCLUDE_PATH => 'header', - POST_PROCESS => 'footer', - }); - - my $context = Template::Context->new( EVAL_PERL => 1 ); - -The new() method returns a Template::Context object (or sub-class) or -undef on error. In the latter case, a relevant error message can be -retrieved by the error() class method or directly from the -$Template::Context::ERROR package variable. - - my $context = Template::Context->new(\%config) - || die Template::Context->error(); - - my $context = Template::Context->new(\%config) - || die $Template::Context::ERROR; - -The following configuration items may be specified. - -=over 4 - - -=item VARIABLES, PRE_DEFINE - -The VARIABLES option (or PRE_DEFINE - they're equivalent) can be used -to specify a hash array of template variables that should be used to -pre-initialise the stash when it is created. These items are ignored -if the STASH item is defined. - - my $context = Template::Context->new({ - VARIABLES => { - title => 'A Demo Page', - author => 'Joe Random Hacker', - version => 3.14, - }, - }; - -or - - my $context = Template::Context->new({ - PRE_DEFINE => { - title => 'A Demo Page', - author => 'Joe Random Hacker', - version => 3.14, - }, - }; - - - - - -=item BLOCKS - -The BLOCKS option can be used to pre-define a default set of template -blocks. These should be specified as a reference to a hash array -mapping template names to template text, subroutines or Template::Document -objects. - - my $context = Template::Context->new({ - BLOCKS => { - header => 'The Header. [% title %]', - footer => sub { return $some_output_text }, - another => Template::Document->new({ ... }), - }, - }); - - - - - -=item TRIM - -The TRIM option can be set to have any leading and trailing whitespace -automatically removed from the output of all template files and BLOCKs. - -By example, the following BLOCK definition - - [% BLOCK foo %] - Line 1 of foo - [% END %] - -will be processed is as "\nLine 1 of foo\n". When INCLUDEd, the surrounding -newlines will also be introduced. - - before - [% INCLUDE foo %] - after - -output: - before - - Line 1 of foo - - after - -With the TRIM option set to any true value, the leading and trailing -newlines (which count as whitespace) will be removed from the output -of the BLOCK. - - before - Line 1 of foo - after - -The TRIM option is disabled (0) by default. - - - - - - -=item EVAL_PERL - -This flag is used to indicate if PERL and/or RAWPERL blocks should be -evaluated. By default, it is disabled and any PERL or RAWPERL blocks -encountered will raise exceptions of type 'perl' with the message -'EVAL_PERL not set'. Note however that any RAWPERL blocks should -always contain valid Perl code, regardless of the EVAL_PERL flag. The -parser will fail to compile templates that contain invalid Perl code -in RAWPERL blocks and will throw a 'file' exception. - -When using compiled templates (see -L<COMPILE_EXT|Template::Manual::Config/Caching_and_Compiling_Options> and -L<COMPILE_DIR|Template::Manual::Config/Caching_and_Compiling_Options>), -the EVAL_PERL has an affect when the template is compiled, and again -when the templates is subsequently processed, possibly in a different -context to the one that compiled it. - -If the EVAL_PERL is set when a template is compiled, then all PERL and -RAWPERL blocks will be included in the compiled template. If the -EVAL_PERL option isn't set, then Perl code will be generated which -B<always> throws a 'perl' exception with the message 'EVAL_PERL not -set' B<whenever> the compiled template code is run. - -Thus, you must have EVAL_PERL set if you want your compiled templates -to include PERL and RAWPERL blocks. - -At some point in the future, using a different invocation of the -Template Toolkit, you may come to process such a pre-compiled -template. Assuming the EVAL_PERL option was set at the time the -template was compiled, then the output of any RAWPERL blocks will be -included in the compiled template and will get executed when the -template is processed. This will happen regardless of the runtime -EVAL_PERL status. - -Regular PERL blocks are a little more cautious, however. If the -EVAL_PERL flag isn't set for the I<current> context, that is, the -one which is trying to process it, then it will throw the familiar 'perl' -exception with the message, 'EVAL_PERL not set'. - -Thus you can compile templates to include PERL blocks, but optionally -disable them when you process them later. Note however that it is -possible for a PERL block to contain a Perl "BEGIN { # some code }" -block which will always get run regardless of the runtime EVAL_PERL -status. Thus, if you set EVAL_PERL when compiling templates, it is -assumed that you trust the templates to Do The Right Thing. Otherwise -you must accept the fact that there's no bulletproof way to prevent -any included code from trampling around in the living room of the -runtime environment, making a real nuisance of itself if it really -wants to. If you don't like the idea of such uninvited guests causing -a bother, then you can accept the default and keep EVAL_PERL disabled. - - - - - - - -=item RECURSION - -The template processor will raise a file exception if it detects -direct or indirect recursion into a template. Setting this option to -any true value will allow templates to include each other recursively. - - - -=item LOAD_TEMPLATES - -The LOAD_TEMPLATE option can be used to provide a reference to a list -of Template::Provider objects or sub-classes thereof which will take -responsibility for loading and compiling templates. - - my $context = Template::Context->new({ - LOAD_TEMPLATES => [ - MyOrg::Template::Provider->new({ ... }), - Template::Provider->new({ ... }), - ], - }); - -When a PROCESS, INCLUDE or WRAPPER directive is encountered, the named -template may refer to a locally defined BLOCK or a file relative to -the INCLUDE_PATH (or an absolute or relative path if the appropriate -ABSOLUTE or RELATIVE options are set). If a BLOCK definition can't be -found (see the Template::Context template() method for a discussion of -BLOCK locality) then each of the LOAD_TEMPLATES provider objects is -queried in turn via the fetch() method to see if it can supply the -required template. Each provider can return a compiled template, an -error, or decline to service the request in which case the -responsibility is passed to the next provider. If none of the -providers can service the request then a 'not found' error is -returned. The same basic provider mechanism is also used for the -INSERT directive but it bypasses any BLOCK definitions and doesn't -attempt is to parse or process the contents of the template file. - -This is an implementation of the 'Chain of Responsibility' -design pattern as described in -"Design Patterns", Erich Gamma, Richard Helm, Ralph Johnson, John -Vlissides), Addision-Wesley, ISBN 0-201-63361-2, page 223 -. - -If LOAD_TEMPLATES is undefined, a single default provider will be -instantiated using the current configuration parameters. For example, -the Template::Provider INCLUDE_PATH option can be specified in the Template::Context configuration and will be correctly passed to the provider's -constructor method. - - my $context = Template::Context->new({ - INCLUDE_PATH => '/here:/there', - }); - - - - - -=item LOAD_PLUGINS - -The LOAD_PLUGINS options can be used to specify a list of provider -objects (i.e. they implement the fetch() method) which are responsible -for loading and instantiating template plugin objects. The -Template::Content plugin() method queries each provider in turn in a -"Chain of Responsibility" as per the template() and filter() methods. - - my $context = Template::Context->new({ - LOAD_PLUGINS => [ - MyOrg::Template::Plugins->new({ ... }), - Template::Plugins->new({ ... }), - ], - }); - -By default, a single Template::Plugins object is created using the -current configuration hash. Configuration items destined for the -Template::Plugins constructor may be added to the Template::Context -constructor. - - my $context = Template::Context->new({ - PLUGIN_BASE => 'MyOrg::Template::Plugins', - LOAD_PERL => 1, - }); - - - - - -=item LOAD_FILTERS - -The LOAD_FILTERS option can be used to specify a list of provider -objects (i.e. they implement the fetch() method) which are responsible -for returning and/or creating filter subroutines. The -Template::Context filter() method queries each provider in turn in a -"Chain of Responsibility" as per the template() and plugin() methods. - - my $context = Template::Context->new({ - LOAD_FILTERS => [ - MyTemplate::Filters->new(), - Template::Filters->new(), - ], - }); - -By default, a single Template::Filters object is created for the -LOAD_FILTERS list. - - - -=item STASH - -A reference to a Template::Stash object or sub-class which will take -responsibility for managing template variables. - - my $stash = MyOrg::Template::Stash->new({ ... }); - my $context = Template::Context->new({ - STASH => $stash, - }); - -If unspecified, a default stash object is created using the VARIABLES -configuration item to initialise the stash variables. These may also -be specified as the PRE_DEFINE option for backwards compatibility with -version 1. - - my $context = Template::Context->new({ - VARIABLES => { - id => 'abw', - name => 'Andy Wardley', - }, - }; - - - -=item DEBUG - -The DEBUG option can be used to enable various debugging features -of the Template::Context module. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_CONTEXT | DEBUG_DIRS, - }); - -The DEBUG value can include any of the following. Multiple values -should be combined using the logical OR operator, '|'. - -=over 4 - -=item DEBUG_CONTEXT - -Enables general debugging messages for the -L<Template::Context|Template::Context> module. - -=item DEBUG_DIRS - -This option causes the Template Toolkit to generate comments -indicating the source file, line and original text of each directive -in the template. These comments are embedded in the template output -using the format defined in the DEBUG_FORMAT configuration item, or a -simple default format if unspecified. - -For example, the following template fragment: - - - Hello World - -would generate this output: - - ## input text line 1 : ## - Hello - ## input text line 2 : World ## - World - - -=back - - - - - -=back - -=head2 template($name) - -Returns a compiled template by querying each of the LOAD_TEMPLATES providers -(instances of Template::Provider, or sub-class) in turn. - - $template = $context->template('header'); - -On error, a Template::Exception object of type 'file' is thrown via -die(). This can be caught by enclosing the call to template() in an -eval block and examining $@. - - eval { - $template = $context->template('header'); - }; - if ($@) { - print "failed to fetch template: $@\n"; - } - -=head2 plugin($name, \@args) - -Instantiates a plugin object by querying each of the LOAD_PLUGINS -providers. The default LOAD_PLUGINS provider is a Template::Plugins -object which attempts to load plugin modules, according the various -configuration items such as PLUGIN_BASE, LOAD_PERL, etc., and then -instantiate an object via new(). A reference to a list of constructor -arguments may be passed as the second parameter. These are forwarded -to the plugin constructor. - -Returns a reference to a plugin (which is generally an object, but -doesn't have to be). Errors are thrown as Template::Exception objects -of type 'plugin'. - - $plugin = $context->plugin('DBI', 'dbi:msql:mydbname'); - -=head2 filter($name, \@args, $alias) - -Instantiates a filter subroutine by querying the LOAD_FILTERS providers. -The default LOAD_FILTERS providers is a Template::Filters object. -Additional arguments may be passed by list reference along with an -optional alias under which the filter will be cached for subsequent -use. The filter is cached under its own $name if $alias is undefined. -Subsequent calls to filter($name) will return the cached entry, if -defined. Specifying arguments bypasses the caching mechanism and -always creates a new filter. Errors are thrown as Template::Exception -objects of typre 'filter'. - - # static filter (no args) - $filter = $context->filter('html'); - - # dynamic filter (args) aliased to 'padright' - $filter = $context->filter('format', '%60s', 'padright'); - - # retrieve previous filter via 'padright' alias - $filter = $context->filter('padright'); - -=head2 process($template, \%vars) - -Processes a template named or referenced by the first parameter and returns -the output generated. An optional reference to a hash array may be passed -as the second parameter, containing variable definitions which will be set -before the template is processed. The template is processed in the current -context, with no localisation of variables performed. Errors are thrown -as Template::Exception objects via die(). - - $output = $context->process('header', { title => 'Hello World' }); - -=head2 include($template, \%vars) - -Similar to process() above, but using localised variables. Changes made to -any variables will only persist until the include() method completes. - - $output = $context->include('header', { title => 'Hello World' }); - -=head2 throw($error_type, $error_message, \$output) - -Raises an exception in the form of a Template::Exception object by -calling die(). This method may be passed a reference to an existing -Template::Exception object; a single value containing an error message -which is used to instantiate a Template::Exception of type 'undef'; or -a pair of values representing the exception type and info from which a -Template::Exception object is instantiated. e.g. - - $context->throw($exception); - $context->throw("I'm sorry Dave, I can't do that"); - $context->throw('denied', "I'm sorry Dave, I can't do that"); - -The optional third parameter may be a reference to the current output -buffer. This is then stored in the exception object when created, -allowing the catcher to examine and use the output up to the point at -which the exception was raised. - - $output .= 'blah blah blah'; - $output .= 'more rhubarb'; - $context->throw('yack', 'Too much yacking', \$output); - -=head2 catch($exception, \$output) - -Catches an exception thrown, either as a reference to a -Template::Exception object or some other value. In the latter case, -the error string is promoted to a Template::Exception object of -'undef' type. This method also accepts a reference to the current -output buffer which is passed to the Template::Exception constructor, -or is appended to the output buffer stored in an existing -Template::Exception object, if unique (i.e. not the same reference). -By this process, the correct state of the output buffer can be -reconstructed for simple or nested throws. - -=head2 define_block($name, $block) - -Adds a new block definition to the internal BLOCKS cache. The first -argument should contain the name of the block and the second a reference -to a Template::Document object or template sub-routine, or template text -which is automatically compiled into a template sub-routine. Returns -a true value (the sub-routine or Template::Document reference) on -success or undef on failure. The relevant error message can be -retrieved by calling the error() method. - -=head2 define_filter($name, \&filter, $is_dynamic) - -Adds a new filter definition by calling the store() method on each of -the LOAD_FILTERS providers until accepted (in the usual case, this is -accepted straight away by the one and only Template::Filters -provider). The first argument should contain the name of the filter -and the second a reference to a filter subroutine. The optional -third argument can be set to any true value to indicate that the -subroutine is a dynamic filter factory. Returns a true value or -throws a 'filter' exception on error. - -=head2 localise(\%vars) - -Clones the stash to create a context with localised variables. Returns a -reference to the newly cloned stash object which is also stored -internally. - - $stash = $context->localise(); - -=head2 delocalise() - -Restore the stash to its state prior to localisation. - - $stash = $context->delocalise(); - -=head2 visit(\%blocks) - -This method is called by Template::Document objects immediately before -they process their content. It is called to register any local BLOCK -definitions with the context object so that they may be subsequently -delivered on request. - -=head2 leave() - -Compliment to visit(), above. Called by Template::Document objects -immediately after they process their content. - -=head2 reset() - -Clears the local BLOCKS cache of any BLOCK definitions. Any initial set of -BLOCKS specified as a configuration item to the constructor will be reinstated. - -=head2 AUTOLOAD - -An AUTOLOAD method provides access to context configuration items. - - $stash = $context->stash(); - $tflag = $context->trim(); - $epflag = $context->eval_perl(); - ... - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.89, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Document|Template::Document>, L<Template::Exception|Template::Exception>, L<Template::Filters|Template::Filters>, L<Template::Plugins|Template::Plugins>, L<Template::Provider|Template::Provider>, L<Template::Service|Template::Service>, L<Template::Stash|Template::Stash> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Directive.pm b/lib/Template/Directive.pm deleted file mode 100644 index c3f86a9..0000000 --- a/lib/Template/Directive.pm +++ /dev/null @@ -1,1004 +0,0 @@ -#================================================================= -*-Perl-*- -# -# Template::Directive -# -# DESCRIPTION -# Factory module for constructing templates from Perl code. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# WARNING -# Much of this module is hairy, even furry in places. It needs -# a lot of tidying up and may even be moved into a different place -# altogether. The generator code is often inefficient, particulary in -# being very anal about pretty-printing the Perl code all neatly, but -# at the moment, that's still high priority for the sake of easier -# debugging. -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Directive.pm,v 2.18 2003/10/08 09:34:41 abw Exp $ -# -#============================================================================ - -package Template::Directive; - -require 5.004; - -use strict; -use Template::Base; -use Template::Constants; -use Template::Exception; - -use base qw( Template::Base ); -use vars qw( $VERSION $DEBUG $PRETTY $WHILE_MAX $OUTPUT ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.18 $ =~ /(\d+)\.(\d+)/); - -$WHILE_MAX = 1000 unless defined $WHILE_MAX; -$PRETTY = 0 unless defined $PRETTY; -$OUTPUT = '$output .= '; - - -sub _init { - my ($self, $config) = @_; - $self->{ NAMESPACE } = $config->{ NAMESPACE }; - return $self; -} - - -sub pad { - my ($text, $pad) = @_; - $pad = ' ' x ($pad * 4); - $text =~ s/^(?!#line)/$pad/gm; - $text; -} - -#======================================================================== -# FACTORY METHODS -# -# These methods are called by the parser to construct directive instances. -#======================================================================== - -#------------------------------------------------------------------------ -# template($block) -#------------------------------------------------------------------------ - -sub template { - my ($class, $block) = @_; - $block = pad($block, 2) if $PRETTY; - - return "sub { return '' }" unless $block =~ /\S/; - - return <<EOF; -sub { - my \$context = shift || die "template sub called without context\\n"; - my \$stash = \$context->stash; - my \$output = ''; - my \$error; - - eval { BLOCK: { -$block - } }; - if (\$@) { - \$error = \$context->catch(\$@, \\\$output); - die \$error unless \$error->type eq 'return'; - } - - return \$output; -} -EOF -} - - -#------------------------------------------------------------------------ -# anon_block($block) [% BLOCK %] ... [% END %] -#------------------------------------------------------------------------ - -sub anon_block { - my ($class, $block) = @_; - $block = pad($block, 2) if $PRETTY; - - return <<EOF; - -# BLOCK -$OUTPUT do { - my \$output = ''; - my \$error; - - eval { BLOCK: { -$block - } }; - if (\$@) { - \$error = \$context->catch(\$@, \\\$output); - die \$error unless \$error->type eq 'return'; - } - - \$output; -}; -EOF -} - - -#------------------------------------------------------------------------ -# block($blocktext) -#------------------------------------------------------------------------ - -sub block { - my ($class, $block) = @_; - return join("\n", @{ $block || [] }); -} - - -#------------------------------------------------------------------------ -# textblock($text) -#------------------------------------------------------------------------ - -sub textblock { - my ($class, $text) = @_; - return "$OUTPUT " . &text($class, $text) . ';'; -} - - -#------------------------------------------------------------------------ -# text($text) -#------------------------------------------------------------------------ - -sub text { - my ($class, $text) = @_; - for ($text) { - s/(["\$\@\\])/\\$1/g; - s/\n/\\n/g; - } - return '"' . $text . '"'; -} - - -#------------------------------------------------------------------------ -# quoted(\@items) "foo$bar" -#------------------------------------------------------------------------ - -sub quoted { - my ($class, $items) = @_; - return '' unless @$items; - return ("('' . " . $items->[0] . ')') if scalar @$items == 1; - return '(' . join(' . ', @$items) . ')'; -# my $r = '(' . join(' . ', @$items) . ' . "")'; -# print STDERR "[$r]\n"; -# return $r; -} - - -#------------------------------------------------------------------------ -# ident(\@ident) foo.bar(baz) -#------------------------------------------------------------------------ - -sub ident { - my ($class, $ident) = @_; - return "''" unless @$ident; - my $ns; - - # does the first element of the identifier have a NAMESPACE - # handler defined? - if (ref $class && @$ident > 2 && ($ns = $class->{ NAMESPACE })) { - my $key = $ident->[0]; - $key =~ s/^'(.+)'$/$1/s; - if ($ns = $ns->{ $key }) { - return $ns->ident($ident); - } - } - - if (scalar @$ident <= 2 && ! $ident->[1]) { - $ident = $ident->[0]; - } - else { - $ident = '[' . join(', ', @$ident) . ']'; - } - return "\$stash->get($ident)"; -} - -#------------------------------------------------------------------------ -# identref(\@ident) \foo.bar(baz) -#------------------------------------------------------------------------ - -sub identref { - my ($class, $ident) = @_; - return "''" unless @$ident; - if (scalar @$ident <= 2 && ! $ident->[1]) { - $ident = $ident->[0]; - } - else { - $ident = '[' . join(', ', @$ident) . ']'; - } - return "\$stash->getref($ident)"; -} - - -#------------------------------------------------------------------------ -# assign(\@ident, $value, $default) foo = bar -#------------------------------------------------------------------------ - -sub assign { - my ($class, $var, $val, $default) = @_; - - if (ref $var) { - if (scalar @$var == 2 && ! $var->[1]) { - $var = $var->[0]; - } - else { - $var = '[' . join(', ', @$var) . ']'; - } - } - $val .= ', 1' if $default; - return "\$stash->set($var, $val)"; -} - - -#------------------------------------------------------------------------ -# args(\@args) foo, bar, baz = qux -#------------------------------------------------------------------------ - -sub args { - my ($class, $args) = @_; - my $hash = shift @$args; - push(@$args, '{ ' . join(', ', @$hash) . ' }') - if @$hash; - - return '0' unless @$args; - return '[ ' . join(', ', @$args) . ' ]'; -} - -#------------------------------------------------------------------------ -# filenames(\@names) -#------------------------------------------------------------------------ - -sub filenames { - my ($class, $names) = @_; - if (@$names > 1) { - $names = '[ ' . join(', ', @$names) . ' ]'; - } - else { - $names = shift @$names; - } - return $names; -} - - -#------------------------------------------------------------------------ -# get($expr) [% foo %] -#------------------------------------------------------------------------ - -sub get { - my ($class, $expr) = @_; - return "$OUTPUT $expr;"; -} - - -#------------------------------------------------------------------------ -# call($expr) [% CALL bar %] -#------------------------------------------------------------------------ - -sub call { - my ($class, $expr) = @_; - $expr .= ';'; - return $expr; -} - - -#------------------------------------------------------------------------ -# set(\@setlist) [% foo = bar, baz = qux %] -#------------------------------------------------------------------------ - -sub set { - my ($class, $setlist) = @_; - my $output; - while (my ($var, $val) = splice(@$setlist, 0, 2)) { - $output .= &assign($class, $var, $val) . ";\n"; - } - chomp $output; - return $output; -} - - -#------------------------------------------------------------------------ -# default(\@setlist) [% DEFAULT foo = bar, baz = qux %] -#------------------------------------------------------------------------ - -sub default { - my ($class, $setlist) = @_; - my $output; - while (my ($var, $val) = splice(@$setlist, 0, 2)) { - $output .= &assign($class, $var, $val, 1) . ";\n"; - } - chomp $output; - return $output; -} - - -#------------------------------------------------------------------------ -# insert(\@nameargs) [% INSERT file %] -# # => [ [ $file, ... ], \@args ] -#------------------------------------------------------------------------ - -sub insert { - my ($class, $nameargs) = @_; - my ($file, $args) = @$nameargs; - $file = $class->filenames($file); - return "$OUTPUT \$context->insert($file);"; -} - - -#------------------------------------------------------------------------ -# include(\@nameargs) [% INCLUDE template foo = bar %] -# # => [ [ $file, ... ], \@args ] -#------------------------------------------------------------------------ - -sub include { - my ($class, $nameargs) = @_; - my ($file, $args) = @$nameargs; - my $hash = shift @$args; - $file = $class->filenames($file); - $file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : ''; - return "$OUTPUT \$context->include($file);"; -} - - -#------------------------------------------------------------------------ -# process(\@nameargs) [% PROCESS template foo = bar %] -# # => [ [ $file, ... ], \@args ] -#------------------------------------------------------------------------ - -sub process { - my ($class, $nameargs) = @_; - my ($file, $args) = @$nameargs; - my $hash = shift @$args; - $file = $class->filenames($file); - $file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : ''; - return "$OUTPUT \$context->process($file);"; -} - - -#------------------------------------------------------------------------ -# if($expr, $block, $else) [% IF foo < bar %] -# ... -# [% ELSE %] -# ... -# [% END %] -#------------------------------------------------------------------------ - -sub if { - my ($class, $expr, $block, $else) = @_; - my @else = $else ? @$else : (); - $else = pop @else; - $block = pad($block, 1) if $PRETTY; - - my $output = "if ($expr) {\n$block\n}\n"; - - foreach my $elsif (@else) { - ($expr, $block) = @$elsif; - $block = pad($block, 1) if $PRETTY; - $output .= "elsif ($expr) {\n$block\n}\n"; - } - if (defined $else) { - $else = pad($else, 1) if $PRETTY; - $output .= "else {\n$else\n}\n"; - } - - return $output; -} - - -#------------------------------------------------------------------------ -# foreach($target, $list, $args, $block) [% FOREACH x = [ foo bar ] %] -# ... -# [% END %] -#------------------------------------------------------------------------ - -sub foreach { - my ($class, $target, $list, $args, $block) = @_; - $args = shift @$args; - $args = @$args ? ', { ' . join(', ', @$args) . ' }' : ''; - - my ($loop_save, $loop_set, $loop_restore, $setiter); - if ($target) { - $loop_save = 'eval { $oldloop = ' . &ident($class, ["'loop'"]) . ' }'; - $loop_set = "\$stash->{'$target'} = \$value"; - $loop_restore = "\$stash->set('loop', \$oldloop)"; - } - else { - $loop_save = '$stash = $context->localise()'; -# $loop_set = "\$stash->set('import', \$value) " -# . "if ref \$value eq 'HASH'"; - $loop_set = "\$stash->get(['import', [\$value]]) " - . "if ref \$value eq 'HASH'"; - $loop_restore = '$stash = $context->delocalise()'; - } - $block = pad($block, 3) if $PRETTY; - - return <<EOF; - -# FOREACH -do { - my (\$value, \$error, \$oldloop); - my \$list = $list; - - unless (UNIVERSAL::isa(\$list, 'Template::Iterator')) { - \$list = Template::Config->iterator(\$list) - || die \$Template::Config::ERROR, "\\n"; - } - - (\$value, \$error) = \$list->get_first(); - $loop_save; - \$stash->set('loop', \$list); - eval { -LOOP: while (! \$error) { - $loop_set; -$block; - (\$value, \$error) = \$list->get_next(); - } - }; - $loop_restore; - die \$@ if \$@; - \$error = 0 if \$error && \$error eq Template::Constants::STATUS_DONE; - die \$error if \$error; -}; -EOF -} - -#------------------------------------------------------------------------ -# next() [% NEXT %] -# -# Next iteration of a FOREACH loop (experimental) -#------------------------------------------------------------------------ - -sub next { - return <<EOF; -(\$value, \$error) = \$list->get_next(); -next LOOP; -EOF -} - - -#------------------------------------------------------------------------ -# wrapper(\@nameargs, $block) [% WRAPPER template foo = bar %] -# # => [ [$file,...], \@args ] -#------------------------------------------------------------------------ - -sub wrapper { - my ($class, $nameargs, $block) = @_; - my ($file, $args) = @$nameargs; - my $hash = shift @$args; - - local $" = ', '; -# print STDERR "wrapper([@$file], { @$hash })\n"; - - return $class->multi_wrapper($file, $hash, $block) - if @$file > 1; - $file = shift @$file; - - $block = pad($block, 1) if $PRETTY; - push(@$hash, "'content'", '$output'); - $file .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : ''; - - return <<EOF; - -# WRAPPER -$OUTPUT do { - my \$output = ''; -$block - \$context->include($file); -}; -EOF -} - - -sub multi_wrapper { - my ($class, $file, $hash, $block) = @_; - $block = pad($block, 1) if $PRETTY; - - push(@$hash, "'content'", '$output'); - $hash = @$hash ? ', { ' . join(', ', @$hash) . ' }' : ''; - - $file = join(', ', reverse @$file); -# print STDERR "multi wrapper: $file\n"; - - return <<EOF; - -# WRAPPER -$OUTPUT do { - my \$output = ''; -$block - foreach ($file) { - \$output = \$context->include(\$_$hash); - } - \$output; -}; -EOF -} - - -#------------------------------------------------------------------------ -# while($expr, $block) [% WHILE x < 10 %] -# ... -# [% END %] -#------------------------------------------------------------------------ - -sub while { - my ($class, $expr, $block) = @_; - $block = pad($block, 2) if $PRETTY; - - return <<EOF; - -# WHILE -do { - my \$failsafe = $WHILE_MAX; -LOOP: - while (--\$failsafe && ($expr)) { -$block - } - die "WHILE loop terminated (> $WHILE_MAX iterations)\\n" - unless \$failsafe; -}; -EOF -} - - -#------------------------------------------------------------------------ -# switch($expr, \@case) [% SWITCH %] -# [% CASE foo %] -# ... -# [% END %] -#------------------------------------------------------------------------ - -sub switch { - my ($class, $expr, $case) = @_; - my @case = @$case; - my ($match, $block, $default); - my $caseblock = ''; - - $default = pop @case; - - foreach $case (@case) { - $match = $case->[0]; - $block = $case->[1]; - $block = pad($block, 1) if $PRETTY; - $caseblock .= <<EOF; -\$match = $match; -\$match = [ \$match ] unless ref \$match eq 'ARRAY'; -if (grep(/^\$result\$/, \@\$match)) { -$block - last SWITCH; -} -EOF - } - - $caseblock .= $default - if defined $default; - $caseblock = pad($caseblock, 2) if $PRETTY; - -return <<EOF; - -# SWITCH -do { - my \$result = $expr; - my \$match; - SWITCH: { -$caseblock - } -}; -EOF -} - - -#------------------------------------------------------------------------ -# try($block, \@catch) [% TRY %] -# ... -# [% CATCH %] -# ... -# [% END %] -#------------------------------------------------------------------------ - -sub try { - my ($class, $block, $catch) = @_; - my @catch = @$catch; - my ($match, $mblock, $default, $final, $n); - my $catchblock = ''; - my $handlers = []; - - $block = pad($block, 2) if $PRETTY; - $final = pop @catch; - $final = "# FINAL\n" . ($final ? "$final\n" : '') - . 'die $error if $error;' . "\n" . '$output;'; - $final = pad($final, 1) if $PRETTY; - - $n = 0; - foreach $catch (@catch) { - $match = $catch->[0] || do { - $default ||= $catch->[1]; - next; - }; - $mblock = $catch->[1]; - $mblock = pad($mblock, 1) if $PRETTY; - push(@$handlers, "'$match'"); - $catchblock .= $n++ - ? "elsif (\$handler eq '$match') {\n$mblock\n}\n" - : "if (\$handler eq '$match') {\n$mblock\n}\n"; - } - $catchblock .= "\$error = 0;"; - $catchblock = pad($catchblock, 3) if $PRETTY; - if ($default) { - $default = pad($default, 1) if $PRETTY; - $default = "else {\n # DEFAULT\n$default\n \$error = '';\n}"; - } - else { - $default = '# NO DEFAULT'; - } - $default = pad($default, 2) if $PRETTY; - - $handlers = join(', ', @$handlers); -return <<EOF; - -# TRY -$OUTPUT do { - my \$output = ''; - my (\$error, \$handler); - eval { -$block - }; - if (\$@) { - \$error = \$context->catch(\$@, \\\$output); - die \$error if \$error->type =~ /^return|stop\$/; - \$stash->set('error', \$error); - \$stash->set('e', \$error); - if (defined (\$handler = \$error->select_handler($handlers))) { -$catchblock - } -$default - } -$final -}; -EOF -} - - -#------------------------------------------------------------------------ -# throw(\@nameargs) [% THROW foo "bar error" %] -# # => [ [$type], \@args ] -#------------------------------------------------------------------------ - -sub throw { - my ($class, $nameargs) = @_; - my ($type, $args) = @$nameargs; - my $hash = shift(@$args); - my $info = shift(@$args); - $type = shift @$type; # uses same parser production as INCLUDE - # etc., which allow multiple names - # e.g. INCLUDE foo+bar+baz - - if (! $info) { - $args = "$type, undef"; - } - elsif (@$hash || @$args) { - local $" = ', '; - my $i = 0; - $args = "$type, { args => [ " - . join(', ', $info, @$args) - . ' ], ' - . join(', ', - (map { "'" . $i++ . "' => $_" } ($info, @$args)), - @$hash) - . ' }'; - } - else { - $args = "$type, $info"; - } - - return "\$context->throw($args, \\\$output);"; -} - - -#------------------------------------------------------------------------ -# clear() [% CLEAR %] -# -# NOTE: this is redundant, being hard-coded (for now) into Parser.yp -#------------------------------------------------------------------------ - -sub clear { - return "\$output = '';"; -} - -#------------------------------------------------------------------------ -# break() [% BREAK %] -# -# NOTE: this is redundant, being hard-coded (for now) into Parser.yp -#------------------------------------------------------------------------ - -sub break { - return 'last LOOP;'; -} - -#------------------------------------------------------------------------ -# return() [% RETURN %] -#------------------------------------------------------------------------ - -sub return { - return "\$context->throw('return', '', \\\$output);"; -} - -#------------------------------------------------------------------------ -# stop() [% STOP %] -#------------------------------------------------------------------------ - -sub stop { - return "\$context->throw('stop', '', \\\$output);"; -} - - -#------------------------------------------------------------------------ -# use(\@lnameargs) [% USE alias = plugin(args) %] -# # => [ [$file, ...], \@args, $alias ] -#------------------------------------------------------------------------ - -sub use { - my ($class, $lnameargs) = @_; - my ($file, $args, $alias) = @$lnameargs; - $file = shift @$file; # same production rule as INCLUDE - $alias ||= $file; - $args = &args($class, $args); - $file .= ", $args" if $args; -# my $set = &assign($class, $alias, '$plugin'); - return "# USE\n" - . "\$stash->set($alias,\n" - . " \$context->plugin($file));"; -} - -#------------------------------------------------------------------------ -# view(\@nameargs, $block) [% VIEW name args %] -# # => [ [$file, ... ], \@args ] -#------------------------------------------------------------------------ - -sub view { - my ($class, $nameargs, $block, $defblocks) = @_; - my ($name, $args) = @$nameargs; - my $hash = shift @$args; - $name = shift @$name; # same production rule as INCLUDE - $block = pad($block, 1) if $PRETTY; - - if (%$defblocks) { - $defblocks = join(",\n", map { "'$_' => $defblocks->{ $_ }" } - keys %$defblocks); - $defblocks = pad($defblocks, 1) if $PRETTY; - $defblocks = "{\n$defblocks\n}"; - push(@$hash, "'blocks'", $defblocks); - } - $hash = @$hash ? '{ ' . join(', ', @$hash) . ' }' : ''; - - return <<EOF; -# VIEW -do { - my \$output = ''; - my \$oldv = \$stash->get('view'); - my \$view = \$context->view($hash); - \$stash->set($name, \$view); - \$stash->set('view', \$view); - -$block - - \$stash->set('view', \$oldv); - \$view->seal(); - \$output; -}; -EOF -} - - -#------------------------------------------------------------------------ -# perl($block) -#------------------------------------------------------------------------ - -sub perl { - my ($class, $block) = @_; - $block = pad($block, 1) if $PRETTY; - - return <<EOF; - -# PERL -\$context->throw('perl', 'EVAL_PERL not set') - unless \$context->eval_perl(); - -$OUTPUT do { - my \$output = "package Template::Perl;\\n"; - -$block - - local(\$Template::Perl::context) = \$context; - local(\$Template::Perl::stash) = \$stash; - - my \$result = ''; - tie *Template::Perl::PERLOUT, 'Template::TieString', \\\$result; - my \$save_stdout = select *Template::Perl::PERLOUT; - - eval \$output; - select \$save_stdout; - \$context->throw(\$@) if \$@; - \$result; -}; -EOF -} - - -#------------------------------------------------------------------------ -# no_perl() -#------------------------------------------------------------------------ - -sub no_perl { - my $class = shift; - return "\$context->throw('perl', 'EVAL_PERL not set');"; -} - - -#------------------------------------------------------------------------ -# rawperl($block) -# -# NOTE: perhaps test context EVAL_PERL switch at compile time rather than -# runtime? -#------------------------------------------------------------------------ - -sub rawperl { - my ($class, $block, $line) = @_; - for ($block) { - s/^\n+//; - s/\n+$//; - } - $block = pad($block, 1) if $PRETTY; - $line = $line ? " (starting line $line)" : ''; - - return <<EOF; -# RAWPERL -#line 1 "RAWPERL block$line" -$block -EOF -} - - - -#------------------------------------------------------------------------ -# filter() -#------------------------------------------------------------------------ - -sub filter { - my ($class, $lnameargs, $block) = @_; - my ($name, $args, $alias) = @$lnameargs; - $name = shift @$name; - $args = &args($class, $args); - $args = $args ? "$args, $alias" : ", undef, $alias" - if $alias; - $name .= ", $args" if $args; - $block = pad($block, 1) if $PRETTY; - - return <<EOF; - -# FILTER -$OUTPUT do { - my \$output = ''; - my \$filter = \$context->filter($name) - || \$context->throw(\$context->error); - -$block - - &\$filter(\$output); -}; -EOF -} - - -#------------------------------------------------------------------------ -# capture($name, $block) -#------------------------------------------------------------------------ - -sub capture { - my ($class, $name, $block) = @_; - - if (ref $name) { - if (scalar @$name == 2 && ! $name->[1]) { - $name = $name->[0]; - } - else { - $name = '[' . join(', ', @$name) . ']'; - } - } - $block = pad($block, 1) if $PRETTY; - - return <<EOF; - -# CAPTURE -\$stash->set($name, do { - my \$output = ''; -$block - \$output; -}); -EOF - -} - - -#------------------------------------------------------------------------ -# macro($name, $block, \@args) -#------------------------------------------------------------------------ - -sub macro { - my ($class, $ident, $block, $args) = @_; - $block = pad($block, 2) if $PRETTY; - - if ($args) { - my $nargs = scalar @$args; - $args = join(', ', map { "'$_'" } @$args); - $args = $nargs > 1 - ? "\@args{ $args } = splice(\@_, 0, $nargs)" - : "\$args{ $args } = shift"; - - return <<EOF; - -# MACRO -\$stash->set('$ident', sub { - my \$output = ''; - my (%args, \$params); - $args; - \$params = shift; - \$params = { } unless ref(\$params) eq 'HASH'; - \$params = { \%args, %\$params }; - - my \$stash = \$context->localise(\$params); - eval { -$block - }; - \$stash = \$context->delocalise(); - die \$@ if \$@; - return \$output; -}); -EOF - - } - else { - return <<EOF; - -# MACRO -\$stash->set('$ident', sub { - my \$params = \$_[0] if ref(\$_[0]) eq 'HASH'; - my \$output = ''; - - my \$stash = \$context->localise(\$params); - eval { -$block - }; - \$stash = \$context->delocalise(); - die \$@ if \$@; - return \$output; -}); -EOF - } -} - - -sub debug { - my ($class, $nameargs) = @_; - my ($file, $args) = @$nameargs; - my $hash = shift @$args; - $args = join(', ', @$file, @$args); - $args .= @$hash ? ', { ' . join(', ', @$hash) . ' }' : ''; - return "$OUTPUT \$context->debugging($args); ## DEBUG ##"; -} - - -1; - -__END__ - diff --git a/lib/Template/Document.pm b/lib/Template/Document.pm deleted file mode 100644 index ce3beb2..0000000 --- a/lib/Template/Document.pm +++ /dev/null @@ -1,492 +0,0 @@ -##============================================================= -*-Perl-*- -# -# Template::Document -# -# DESCRIPTION -# Module defining a class of objects which encapsulate compiled -# templates, storing additional block definitions and metadata -# as well as the compiled Perl sub-routine representing the main -# template content. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Document.pm,v 2.71 2004/01/13 16:19:10 abw Exp $ -# -#============================================================================ - -package Template::Document; - -require 5.004; - -use strict; -use vars qw( $VERSION $ERROR $COMPERR $DEBUG $AUTOLOAD ); -use base qw( Template::Base ); -use Template::Constants; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.71 $ =~ /(\d+)\.(\d+)/); - - -#======================================================================== -# ----- PUBLIC METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# new(\%document) -# -# Creates a new self-contained Template::Document object which -# encapsulates a compiled Perl sub-routine, $block, any additional -# BLOCKs defined within the document ($defblocks, also Perl sub-routines) -# and additional $metadata about the document. -#------------------------------------------------------------------------ - -sub new { - my ($class, $doc) = @_; - my ($block, $defblocks, $metadata) = @$doc{ qw( BLOCK DEFBLOCKS METADATA ) }; - $defblocks ||= { }; - $metadata ||= { }; - - # evaluate Perl code in $block to create sub-routine reference if necessary - unless (ref $block) { - local $SIG{__WARN__} = \&catch_warnings; - $COMPERR = ''; - - # DON'T LOOK NOW! - blindly untainting can make you go blind! - $block =~ /(.*)/s; - $block = $1; - - $block = eval $block; - return $class->error($@) - unless defined $block; - } - - # same for any additional BLOCK definitions - @$defblocks{ keys %$defblocks } = - # MORE BLIND UNTAINTING - turn away if you're squeamish - map { - ref($_) - ? $_ - : ( /(.*)/s && eval($1) or return $class->error($@) ) - } values %$defblocks; - - bless { - %$metadata, - _BLOCK => $block, - _DEFBLOCKS => $defblocks, - _HOT => 0, - }, $class; -} - - -#------------------------------------------------------------------------ -# block() -# -# Returns a reference to the internal sub-routine reference, _BLOCK, -# that constitutes the main document template. -#------------------------------------------------------------------------ - -sub block { - return $_[0]->{ _BLOCK }; -} - - -#------------------------------------------------------------------------ -# blocks() -# -# Returns a reference to a hash array containing any BLOCK definitions -# from the template. The hash keys are the BLOCK nameand the values -# are references to Template::Document objects. Returns 0 (# an empty hash) -# if no blocks are defined. -#------------------------------------------------------------------------ - -sub blocks { - return $_[0]->{ _DEFBLOCKS }; -} - - -#------------------------------------------------------------------------ -# process($context) -# -# Process the document in a particular context. Checks for recursion, -# registers the document with the context via visit(), processes itself, -# and then unwinds with a large gin and tonic. -#------------------------------------------------------------------------ - -sub process { - my ($self, $context) = @_; - my $defblocks = $self->{ _DEFBLOCKS }; - my $output; - - - # check we're not already visiting this template - return $context->throw(Template::Constants::ERROR_FILE, - "recursion into '$self->{ name }'") - if $self->{ _HOT } && ! $context->{ RECURSION }; ## RETURN ## - - $context->visit($self, $defblocks); - - $self->{ _HOT } = 1; - eval { - my $block = $self->{ _BLOCK }; - $output = &$block($context); - }; - $self->{ _HOT } = 0; - - $context->leave(); - - die $context->catch($@) - if $@; - - return $output; -} - - -#------------------------------------------------------------------------ -# AUTOLOAD -# -# Provides pseudo-methods for read-only access to various internal -# members. -#------------------------------------------------------------------------ - -sub AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; -# my ($pkg, $file, $line) = caller(); -# print STDERR "called $self->AUTOLOAD($method) from $file line $line\n"; - return $self->{ $method }; -} - - -#======================================================================== -# ----- PRIVATE METHODS ----- -#======================================================================== - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which returns a string representing the internal state -# of the object. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $dblks; - my $output = "$self : $self->{ name }\n"; - - $output .= "BLOCK: $self->{ _BLOCK }\nDEFBLOCKS:\n"; - - if ($dblks = $self->{ _DEFBLOCKS }) { - foreach my $b (keys %$dblks) { - $output .= " $b: $dblks->{ $b }\n"; - } - } - - return $output; -} - - -#======================================================================== -# ----- CLASS METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# as_perl($content) -# -# This method expects a reference to a hash passed as the first argument -# containing 3 items: -# METADATA # a hash of template metadata -# BLOCK # string containing Perl sub definition for main block -# DEFBLOCKS # hash containing further subs for addional BLOCK defs -# It returns a string containing Perl code which, when evaluated and -# executed, will instantiate a new Template::Document object with the -# above data. On error, it returns undef with an appropriate error -# message set in $ERROR. -#------------------------------------------------------------------------ - -sub as_perl { - my ($class, $content) = @_; - my ($block, $defblocks, $metadata) = @$content{ qw( BLOCK DEFBLOCKS METADATA ) }; - - $block =~ s/\n/\n /g; - $block =~ s/\s+$//; - - $defblocks = join('', map { - my $code = $defblocks->{ $_ }; - $code =~ s/\n/\n /g; - $code =~ s/\s*$//; - " '$_' => $code,\n"; - } keys %$defblocks); - $defblocks =~ s/\s+$//; - - $metadata = join('', map { - my $x = $metadata->{ $_ }; - $x =~ s/(['\\])/\\$1/g; - " '$_' => '$x',\n"; - } keys %$metadata); - $metadata =~ s/\s+$//; - - return <<EOF -#------------------------------------------------------------------------ -# Compiled template generated by the Template Toolkit version $Template::VERSION -#------------------------------------------------------------------------ - -$class->new({ - METADATA => { -$metadata - }, - BLOCK => $block, - DEFBLOCKS => { -$defblocks - }, -}); -EOF -} - - -#------------------------------------------------------------------------ -# write_perl_file($filename, \%content) -# -# This method calls as_perl() to generate the Perl code to represent a -# compiled template with the content passed as the second argument. -# It then writes this to the file denoted by the first argument. -# -# Returns 1 on success. On error, sets the $ERROR package variable -# to contain an error message and returns undef. -#------------------------------------------------------------------------ - -sub write_perl_file { - my ($class, $file, $content) = @_; - my ($fh, $tmpfile); - - return $class->error("invalid filename: $file") - unless $file =~ /^(.+)$/s; - - eval { - require File::Temp; - require File::Basename; - ($fh, $tmpfile) = File::Temp::tempfile( - DIR => File::Basename::dirname($file) - ); - print $fh $class->as_perl($content) || die $!; - close($fh); - }; - return $class->error($@) if $@; - return rename($tmpfile, $file) - || $class->error($!); -} - - -#------------------------------------------------------------------------ -# catch_warnings($msg) -# -# Installed as -#------------------------------------------------------------------------ - -sub catch_warnings { - $COMPERR .= join('', @_); -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Document - Compiled template document object - -=head1 SYNOPSIS - - use Template::Document; - - $doc = Template::Document->new({ - BLOCK => sub { # some perl code; return $some_text }, - DEFBLOCKS => { - header => sub { # more perl code; return $some_text }, - footer => sub { # blah blah blah; return $some_text }, - }, - METADATA => { - author => 'Andy Wardley', - version => 3.14, - } - }) || die $Template::Document::ERROR; - - print $doc->process($context); - -=head1 DESCRIPTION - -This module defines an object class whose instances represent compiled -template documents. The Template::Parser module creates a -Template::Document instance to encapsulate a template as it is compiled -into Perl code. - -The constructor method, new(), expects a reference to a hash array -containing the BLOCK, DEFBLOCKS and METADATA items. The BLOCK item -should contain a reference to a Perl subroutine or a textual -representation of Perl code, as generated by the Template::Parser -module, which is then evaluated into a subroutine reference using -eval(). The DEFLOCKS item should reference a hash array containing -further named BLOCKs which may be defined in the template. The keys -represent BLOCK names and the values should be subroutine references -or text strings of Perl code as per the main BLOCK item. The METADATA -item should reference a hash array of metadata items relevant to the -document. - -The process() method can then be called on the instantiated -Template::Document object, passing a reference to a Template::Content -object as the first parameter. This will install any locally defined -blocks (DEFBLOCKS) in the the contexts() BLOCKS cache (via a call to -visit()) so that they may be subsequently resolved by the context. The -main BLOCK subroutine is then executed, passing the context reference -on as a parameter. The text returned from the template subroutine is -then returned by the process() method, after calling the context leave() -method to permit cleanup and de-registration of named BLOCKS previously -installed. - -An AUTOLOAD method provides access to the METADATA items for the document. -The Template::Service module installs a reference to the main -Template::Document object in the stash as the 'template' variable. -This allows metadata items to be accessed from within templates, -including PRE_PROCESS templates. - -header: - - <html> - <head> - <title>[% template.title %] - </head> - ... - -Template::Document objects are usually created by the Template::Parser -but can be manually instantiated or sub-classed to provide custom -template components. - -=head1 METHODS - -=head2 new(\%config) - -Constructor method which accept a reference to a hash array containing the -structure as shown in this example: - - $doc = Template::Document->new({ - BLOCK => sub { # some perl code; return $some_text }, - DEFBLOCKS => { - header => sub { # more perl code; return $some_text }, - footer => sub { # blah blah blah; return $some_text }, - }, - METADATA => { - author => 'Andy Wardley', - version => 3.14, - } - }) || die $Template::Document::ERROR; - -BLOCK and DEFBLOCKS items may be expressed as references to Perl subroutines -or as text strings containing Perl subroutine definitions, as is generated -by the Template::Parser module. These are evaluated into subroutine references -using eval(). - -Returns a new Template::Document object or undef on error. The error() class -method can be called, or the $ERROR package variable inspected to retrieve -the relevant error message. - -=head2 process($context) - -Main processing routine for the compiled template document. A reference to -a Template::Context object should be passed as the first parameter. The -method installs any locally defined blocks via a call to the context -visit() method, processes it's own template, passing the context reference -by parameter and then calls leave() in the context to allow cleanup. - - print $doc->process($context); - -Returns a text string representing the generated output for the template. -Errors are thrown via die(). - -=head2 block() - -Returns a reference to the main BLOCK subroutine. - -=head2 blocks() - -Returns a reference to the hash array of named DEFBLOCKS subroutines. - -=head2 AUTOLOAD - -An autoload method returns METADATA items. - - print $doc->author(); - -=head1 PACKAGE SUB-ROUTINES - -=head2 write_perl_file(\%config) - -This package subroutine is provided to effect persistance of compiled -templates. If the COMPILE_EXT option (to indicate a file extension -for saving compiled templates) then the Template::Parser module calls -this subroutine before calling the new() constructor. At this stage, -the parser has a representation of the template as text strings -containing Perl code. We can write that to a file, enclosed in a -small wrapper which will allow us to susequently require() the file -and have Perl parse and compile it into a Template::Document. Thus we -have persistance of compiled templates. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.71, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Parser|Template::Parser> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Exception.pm b/lib/Template/Exception.pm deleted file mode 100644 index 9a95af7..0000000 --- a/lib/Template/Exception.pm +++ /dev/null @@ -1,254 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Exception -# -# DESCRIPTION -# Module implementing a generic exception class used for error handling -# in the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#------------------------------------------------------------------------ -# -# $Id: Exception.pm,v 2.64 2004/01/13 16:19:10 abw Exp $ -# -#======================================================================== - - -package Template::Exception; - -require 5.005; - -use strict; -use vars qw( $VERSION ); - -use constant TYPE => 0; -use constant INFO => 1; -use constant TEXT => 2; -use overload q|""| => "as_string", fallback => 1; - - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($type, $info, \$text) -# -# Constructor method used to instantiate a new Template::Exception -# object. The first parameter should contain the exception type. This -# can be any arbitrary string of the caller's choice to represent a -# specific exception. The second parameter should contain any -# information (i.e. error message or data reference) relevant to the -# specific exception event. The third optional parameter may be a -# reference to a scalar containing output text from the template -# block up to the point where the exception was thrown. -#------------------------------------------------------------------------ - -sub new { - my ($class, $type, $info, $textref) = @_; - bless [ $type, $info, $textref ], $class; -} - - -#------------------------------------------------------------------------ -# type() -# info() -# type_info() -# -# Accessor methods to return the internal TYPE and INFO fields. -#------------------------------------------------------------------------ - -sub type { - $_[0]->[ TYPE ]; -} - -sub info { - $_[0]->[ INFO ]; -} - -sub type_info { - my $self = shift; - @$self[ TYPE, INFO ]; -} - -#------------------------------------------------------------------------ -# text() -# text(\$pretext) -# -# Method to return the text referenced by the TEXT member. A text -# reference may be passed as a parameter to supercede the existing -# member. The existing text is added to the *end* of the new text -# before being stored. This facility is provided for template blocks -# to gracefully de-nest when an exception occurs and allows them to -# reconstruct their output in the correct order. -#------------------------------------------------------------------------ - -sub text { - my ($self, $newtextref) = @_; - my $textref = $self->[ TEXT ]; - - if ($newtextref) { - $$newtextref .= $$textref if $textref && $textref ne $newtextref; - $self->[ TEXT ] = $newtextref; - return ''; - - } - elsif ($textref) { - return $$textref; - } - else { - return ''; - } -} - - -#------------------------------------------------------------------------ -# as_string() -# -# Accessor method to return a string indicating the exception type and -# information. -#------------------------------------------------------------------------ - -sub as_string { - my $self = shift; - return $self->[ TYPE ] . ' error - ' . $self->[ INFO ]; -} - - -#------------------------------------------------------------------------ -# select_handler(@types) -# -# Selects the most appropriate handler for the exception TYPE, from -# the list of types passed in as parameters. The method returns the -# item which is an exact match for TYPE or the closest, more -# generic handler (e.g. foo being more generic than foo.bar, etc.) -#------------------------------------------------------------------------ - -sub select_handler { - my ($self, @options) = @_; - my $type = $self->[ TYPE ]; - my %hlut; - @hlut{ @options } = (1) x @options; - - while ($type) { - return $type if $hlut{ $type }; - - # strip .element from the end of the exception type to find a - # more generic handler - $type =~ s/\.?[^\.]*$//; - } - return undef; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Exception - Exception handling class module - -=head1 SYNOPSIS - - use Template::Exception; - - my $exception = Template::Exception->new($type, $info); - $type = $exception->type; - $info = $exception->info; - ($type, $info) = $exception->type_info; - - print $exception->as_string(); - - $handler = $exception->select_handler(\@candidates); - -=head1 DESCRIPTION - -The Template::Exception module defines an object class for -representing exceptions within the template processing life cycle. -Exceptions can be raised by modules within the Template Toolkit, or -can be generated and returned by user code bound to template -variables. - - -Exceptions can be raised in a template using the THROW directive, - - [% THROW user.login 'no user id: please login' %] - -or by calling the throw() method on the current Template::Context object, - - $context->throw('user.passwd', 'Incorrect Password'); - $context->throw('Incorrect Password'); # type 'undef' - -or from Perl code by calling die() with a Template::Exception object, - - die (Template::Exception->new('user.denied', 'Invalid User ID')); - -or by simply calling die() with an error string. This is -automagically caught and converted to an exception of 'undef' -type which can then be handled in the usual way. - - die "I'm sorry Dave, I can't do that"; - - - -Each exception is defined by its type and a information component -(e.g. error message). The type can be any identifying string and may -contain dotted components (e.g. 'foo', 'foo.bar', 'foo.bar.baz'). -Exception types are considered to be hierarchical such that 'foo.bar' -would be a specific type of the more general 'foo' type. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Context|Template::Context> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/FAQ.pod b/lib/Template/FAQ.pod deleted file mode 100644 index 0807ace..0000000 --- a/lib/Template/FAQ.pod +++ /dev/null @@ -1,329 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::FAQ -# -# DESCRIPTION -# This is the Frequently Asked Questions list for the Template -# Toolkit. More accurately, it's a very thin placeholder for where -# the FAQ will soon be. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# 2.69 -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::FAQ - Frequently Asked Questions about the Template Toolkit - -=head1 DESCRIPTION - -This is the Frequently Asked Questions list for the Template Toolkit. -More accurately, it's a very thin placeholder for where the FAQ will -soon be. - - -=head1 Template Toolkit Language - -=head2 Why doesn't [% a = b IF c %] work as expected? - -Because the parser interprets it as - - [% a = (b IF c) %] - -Do this instead: - - [% SET a = b IF c %] - -=head2 If I'm using TT to write out a TT template, is there a good way to escape [% and %]? - -You can do this: - - [% stag = "[\%" - etag = "%\]" - %] - -and then: - - [% stag; 'hello'; etag %] - -Or something like: - - [% TAGS [- -] %] - [- INCLUDE foo -] # is a directive - [% INCLUDE foo %] # not a directive, just plain text, passed through - -=head2 How do I iterate over a hash? - -This is covered in the L<Template::Manual::VMethods|VMethods> section -of the manual page. A list of all the keys that are in the hash can -be obtained with the 'keys' virtual method. You can then iterate -over that list and by looking up each key in turn get the value. - - [% FOREACH key = product.keys %] - [% key %] => [% product.$key %] - [% END %] - -=head1 Plugins - -=head2 How do I get the Table plugin to order data across rather than down? - -Order the data into rows: - - Steve Karen Jeff - Brooklyn Nantucket Fairfax - NY MA VA - - [% USE table(data, rows=3) %] - -Then ask for each column - - [% FOREACH column = table.cols %] - -And then print each item in the column going across the output rows - - [% FOREACH item = column %] - <td>[% item %]</td> - [% END %] - -=head2 Accessing Cookies - -Jeff Boes E<lt>jboes@nexcerpt.comE<gt> asks: - - Does anyone have a quick-n-dirty approach to accessing - cookies from templates? - -Jonas Liljegren answers: - - [% USE CGI %] - - <p>The value is [% CGI.cookie('cookie_name') | html %] - - -=head1 Extending the Template Toolkit - -=head2 Can I serve templates from a database? - -Short answer: yes, Chris Nandor has done this for Slash. You need to -subclass Template::Provider. See the mailing list archives for further -info. - -=head2 Can I fetch templates via http? - -To do the job properly, you should sublcass Template::Provider to -Template::Provider::HTTP and use a PREFIX_MAP option to bind the -'http' template prefix to that particular provider (you may want to -go digging around in the F<Changes> file around version 2.01 for -more info on PREFIX_MAP - it may not be properly documented anywhere -else...yet!). e.g. (untested due to lack of existing HTTP Provider -- patches welcome!). - - use Template::Provider::HTTP; - - my $file = Template::Provider( INCLUDE_PATH => [...] ); - my $http = Template::Provider::HTTP->new(...); - my $tt2 = Template->new({ - LOAD_TEMPLATES => [ $file, $http ], - PREFIX_MAP => { - file => '0', # file:foo.html - http => '1', # http:foo.html - default => '0', # foo.html => file:foo.html - } - }); - -Now a template specified as: - - [% INCLUDE foo %] - -will be served by the 'file' provider (the default). Otherwise you -can explicitly add a prefix: - - [% INCLUDE file:foo.html %] - [% INCLUDE http:foo.html %] - [% INCLUDE http://www.xyz.com/tt2/header.tt2 %] - -This same principal can be used to create a DBI template provider. e.g. - - [% INCLUDE dbi:foo.html %] - -But similarly, alas, we don't yet have a DBI provider as part of the -Template Toolkit. There has been some talk on the mailing list about -efforts to develop DBI and/or HTTP providers but as yet no-one has -stepped forward to take up the challenge... - -In the mean time, Craig's post from the mailing list has some useful -pointers on how to acheive this using existing modules: - - To: Adam Theo <adamtheo@theoretic.com> - From: Craig Barratt <craig@arraycomm.com> - Date: Fri, 18 May 2001 17:06:59 -0700 - - > i was wondering if there is anyway to fetch a file using http:// or - > ftp:// and include that? - - Here's one way. Set the LOAD_PERL option: - - use Template; - - my $template = Template->new({ - LOAD_PERL => 1 - }); - $template->process("example.tt", { stdout => *STDOUT }) - || die $template->error(); - - and then use LWP::UserAgent and HTTP::Request: - - [% - USE ua = LWP.UserAgent; - ua.proxy("http", "http://your_proxy/"); - USE req = HTTP.Request("GET", "http://www.cpan.org"); - ua.request(req).content; - -%] - - For FTP use Net::FTP: - - [% - USE ftp = Net.FTP("ftp.cpan.org"); - x = ftp.login("anonymous", "me@here.there"); - x = ftp.cwd("/"); - x = ftp.get("welcome.msg", stdout); - x = ftp.quit; - -%] - - Normally ftp.get would write the file into the current directory. - Instead we pass stdout as a second argument so that it is written - to stdout. We set stdout to STDOUT in the variables we pass to - process. - - Craig - -=head1 Miscellaneous - -=head2 How can I configure variables on a per-request basis? - -One easy way to acheive this is to define a single PRE_PROCESS template which -loads in other configuration files based on variables defined or other -conditions. - -For example, my setup usually looks something like this: - - PRE_PROCESS => 'config/main' - -config/main: - - [% DEFAULT style = 'text' - section = template.section or 'home'; - - PROCESS config/site - + config/urls - + config/macros - + "config/style/$style" - + "config/section/$section" - + ... - %] - -This allows me to set a single 'style' variable to control which config -file gets pre-processed to set my various style options (colours, img paths, -etc). For example: - -config/style/basic: - - [% style = { - name = style # save existing 'style' var as 'style.name' - - # define various other style variables.... - col = { - back => '#ffffff' - text => '#000000' - # ...etc... - } - - logo = { - # ...etc... - } - - # ...etc... - } - %] - -Each source template can declare which section it's in via a META -directive: - - [% META - title = 'General Information' - section = 'info' - %] - - ... - -This controls which section configuration file gets loaded to set various -other variables for defining the section title, menu, etc. - -config/section/info: - - [% section = { - name = section # save 'section' var as 'section.name' - title = 'Information' - menu = [ ... ] - # ...etc... - } - %] - -This illustrates the basic principal but you can extend it to perform -pretty much any kind of per-document initialisation that you require. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Filters.pm b/lib/Template/Filters.pm deleted file mode 100644 index a9c4846..0000000 --- a/lib/Template/Filters.pm +++ /dev/null @@ -1,1448 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Filters -# -# DESCRIPTION -# Defines filter plugins as used by the FILTER directive. -# -# AUTHORS -# Andy Wardley <abw@kfs.org>, with a number of filters contributed -# by Leslie Michael Orchard <deus_x@nijacode.com> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Filters.pm,v 2.77 2004/01/13 16:19:10 abw Exp $ -# -#============================================================================ - -package Template::Filters; - -require 5.004; - -use strict; -use base qw( Template::Base ); -use vars qw( $VERSION $DEBUG $FILTERS $URI_ESCAPES $PLUGIN_FILTER ); -use Template::Constants; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.77 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# standard filters, defined in one of the following forms: -# name => \&static_filter -# name => [ \&subref, $is_dynamic ] -# If the $is_dynamic flag is set then the sub-routine reference -# is called to create a new filter each time it is requested; if -# not set, then it is a single, static sub-routine which is returned -# for every filter request for that name. -#------------------------------------------------------------------------ - -$FILTERS = { - # static filters - 'html' => \&html_filter, - 'html_para' => \&html_paragraph, - 'html_break' => \&html_para_break, - 'html_para_break' => \&html_para_break, - 'html_line_break' => \&html_line_break, - 'uri' => \&uri_filter, - 'upper' => sub { uc $_[0] }, - 'lower' => sub { lc $_[0] }, - 'ucfirst' => sub { ucfirst $_[0] }, - 'lcfirst' => sub { lcfirst $_[0] }, - 'stderr' => sub { print STDERR @_; return '' }, - 'trim' => sub { for ($_[0]) { s/^\s+//; s/\s+$// }; $_[0] }, - 'null' => sub { return '' }, - 'collapse' => sub { for ($_[0]) { s/^\s+//; s/\s+$//; s/\s+/ /g }; - $_[0] }, - - # dynamic filters - 'html_entity' => [ \&html_entity_filter_factory, 1 ], - 'indent' => [ \&indent_filter_factory, 1 ], - 'format' => [ \&format_filter_factory, 1 ], - 'truncate' => [ \&truncate_filter_factory, 1 ], - 'repeat' => [ \&repeat_filter_factory, 1 ], - 'replace' => [ \&replace_filter_factory, 1 ], - 'remove' => [ \&remove_filter_factory, 1 ], - 'eval' => [ \&eval_filter_factory, 1 ], - 'evaltt' => [ \&eval_filter_factory, 1 ], # alias - 'perl' => [ \&perl_filter_factory, 1 ], - 'evalperl' => [ \&perl_filter_factory, 1 ], # alias - 'redirect' => [ \&redirect_filter_factory, 1 ], - 'file' => [ \&redirect_filter_factory, 1 ], # alias - 'stdout' => [ \&stdout_filter_factory, 1 ], - 'latex' => [ \&latex_filter_factory, 1 ], -}; - -# name of module implementing plugin filters -$PLUGIN_FILTER = 'Template::Plugin::Filter'; - - -#======================================================================== -# -- PUBLIC METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# fetch($name, \@args, $context) -# -# Attempts to instantiate or return a reference to a filter sub-routine -# named by the first parameter, $name, with additional constructor -# arguments passed by reference to a list as the second parameter, -# $args. A reference to the calling Template::Context object is -# passed as the third paramter. -# -# Returns a reference to a filter sub-routine or a pair of values -# (undef, STATUS_DECLINED) or ($error, STATUS_ERROR) to decline to -# deliver the filter or to indicate an error. -#------------------------------------------------------------------------ - -sub fetch { - my ($self, $name, $args, $context) = @_; - my ($factory, $is_dynamic, $filter, $error); - - $self->debug("fetch($name, ", - defined $args ? ('[ ', join(', ', @$args), ' ]') : '<no args>', ', ', - defined $context ? $context : '<no context>', - ')') if $self->{ DEBUG }; - - # allow $name to be specified as a reference to - # a plugin filter object; any other ref is - # assumed to be a coderef and hence already a filter; - # non-refs are assumed to be regular name lookups - - if (ref $name) { - if (UNIVERSAL::isa($name, $PLUGIN_FILTER)) { - $factory = $name->factory() - || return $self->error($name->error()); - } - else { - return $name; - } - } - else { - return (undef, Template::Constants::STATUS_DECLINED) - unless ($factory = $self->{ FILTERS }->{ $name } - || $FILTERS->{ $name }); - } - - # factory can be an [ $code, $dynamic ] or just $code - if (ref $factory eq 'ARRAY') { - ($factory, $is_dynamic) = @$factory; - } - else { - $is_dynamic = 0; - } - - if (ref $factory eq 'CODE') { - if ($is_dynamic) { - # if the dynamic flag is set then the sub-routine is a - # factory which should be called to create the actual - # filter... - eval { - ($filter, $error) = &$factory($context, $args ? @$args : ()); - }; - $error ||= $@; - $error = "invalid FILTER for '$name' (not a CODE ref)" - unless $error || ref($filter) eq 'CODE'; - } - else { - # ...otherwise, it's a static filter sub-routine - $filter = $factory; - } - } - else { - $error = "invalid FILTER entry for '$name' (not a CODE ref)"; - } - - if ($error) { - return $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ($error, Template::Constants::STATUS_ERROR) ; - } - else { - return $filter; - } -} - - -#------------------------------------------------------------------------ -# store($name, \&filter) -# -# Stores a new filter in the internal FILTERS hash. The first parameter -# is the filter name, the second a reference to a subroutine or -# array, as per the standard $FILTERS entries. -#------------------------------------------------------------------------ - -sub store { - my ($self, $name, $filter) = @_; - - $self->debug("store($name, $filter)") if $self->{ DEBUG }; - - $self->{ FILTERS }->{ $name } = $filter; - return 1; -} - - -#======================================================================== -# -- PRIVATE METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# _init(\%config) -# -# Private initialisation method. -#------------------------------------------------------------------------ - -sub _init { - my ($self, $params) = @_; - - $self->{ FILTERS } = $params->{ FILTERS } || { }; - $self->{ TOLERANT } = $params->{ TOLERANT } || 0; - $self->{ DEBUG } = ( $params->{ DEBUG } || 0 ) - & Template::Constants::DEBUG_FILTERS; - - - return $self; -} - - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $output = "[Template::Filters] {\n"; - my $format = " %-16s => %s\n"; - my $key; - - foreach $key (qw( TOLERANT )) { - my $val = $self->{ $key }; - $val = '<undef>' unless defined $val; - $output .= sprintf($format, $key, $val); - } - - my $filters = $self->{ FILTERS }; - $filters = join('', map { - sprintf(" $format", $_, $filters->{ $_ }); - } keys %$filters); - $filters = "{\n$filters }"; - - $output .= sprintf($format, 'FILTERS (local)' => $filters); - - $filters = $FILTERS; - $filters = join('', map { - my $f = $filters->{ $_ }; - my ($ref, $dynamic) = ref $f eq 'ARRAY' ? @$f : ($f, 0); - sprintf(" $format", $_, $dynamic ? 'dynamic' : 'static'); - } sort keys %$filters); - $filters = "{\n$filters }"; - - $output .= sprintf($format, 'FILTERS (global)' => $filters); - - $output .= '}'; - return $output; -} - - -#======================================================================== -# -- STATIC FILTER SUBS -- -#======================================================================== - -#------------------------------------------------------------------------ -# uri_filter() [% FILTER uri %] -# -# URI escape a string. This code is borrowed from Gisle Aas' URI::Escape -# module. For something so simple, I can't see any validation in making -# the user install the URI modules just for this, so we cut and paste. -# -# URI::Escape is Copyright 1995-2000 Gisle Aas. -#------------------------------------------------------------------------ - -sub uri_filter { - my $text = shift; - - # construct and cache a lookup table for escapes (faster than - # doing a sprintf() for every character in every string each - # time) - $URI_ESCAPES ||= { - map { ( chr($_), sprintf("%%%02X", $_) ) } (0..255), - }; - - $text =~ s/([^;\/?:@&=+\$,A-Za-z0-9\-_.!~*'()])/$URI_ESCAPES->{$1}/g; - $text; -} - - -#------------------------------------------------------------------------ -# html_filter() [% FILTER html %] -# -# Convert any '<', '>' or '&' characters to the HTML equivalents, '<', -# '>' and '&', respectively. -#------------------------------------------------------------------------ - -sub html_filter { - my $text = shift; - for ($text) { - s/&/&/g; - s/</</g; - s/>/>/g; - s/"/"/g; - } - return $text; -} - - -#------------------------------------------------------------------------ -# html_paragraph() [% FILTER html_para %] -# -# Wrap each paragraph of text (delimited by two or more newlines) in the -# <p>...</p> HTML tags. -#------------------------------------------------------------------------ - -sub html_paragraph { - my $text = shift; - return "<p>\n" - . join("\n</p>\n\n<p>\n", split(/(?:\r?\n){2,}/, $text)) - . "</p>\n"; -} - - -#------------------------------------------------------------------------ -# html_para_break() [% FILTER html_para_break %] -# -# Join each paragraph of text (delimited by two or more newlines) with -# <br><br> HTML tags. -#------------------------------------------------------------------------ - -sub html_para_break { - my $text = shift; - $text =~ s|(\r?\n){2,}|$1<br />$1<br />$1|g; - return $text; -} - -#------------------------------------------------------------------------ -# html_line_break() [% FILTER html_line_break %] -# -# replaces any newlines with <br> HTML tags. -#------------------------------------------------------------------------ - -sub html_line_break { - my $text = shift; - $text =~ s|(\r?\n)|<br />$1|g; - return $text; -} - -#======================================================================== -# -- DYNAMIC FILTER FACTORIES -- -#======================================================================== - -#------------------------------------------------------------------------ -# html_entity_filter_factory(\%options) [% FILTER html %] -# -# Dynamic version of the static html filter which attempts to locate the -# Apache::Util or HTML::Entities modules to perform full entity encoding -# of the text passed. Returns an exception if one or other of the -# modules can't be located. -#------------------------------------------------------------------------ - -sub html_entity_filter_factory { - my $context = shift; - - # if Apache::Util is installed then we use it - eval { - require Apache::Util; - Apache::Util::escape_html(''); - }; - return \&Apache::Util::escape_html - unless $@; - - # otherwise if HTML::Entities is installed then we use that - eval { - require HTML::Entities; - }; - return \&HTML::Entities::encode_entities - unless $@; - - return (undef, Template::Exception->new( html_entity => - 'cannot locate Apache::Util or HTML::Entities' )); - -} - - -#------------------------------------------------------------------------ -# indent_filter_factory($pad) [% FILTER indent(pad) %] -# -# Create a filter to indent text by a fixed pad string or when $pad is -# numerical, a number of space. -#------------------------------------------------------------------------ - -sub indent_filter_factory { - my ($context, $pad) = @_; - $pad = 4 unless defined $pad; - $pad = ' ' x $pad if $pad =~ /^\d+$/; - - return sub { - my $text = shift; - $text = '' unless defined $text; - $text =~ s/^/$pad/mg; - return $text; - } -} - -#------------------------------------------------------------------------ -# format_filter_factory() [% FILTER format(format) %] -# -# Create a filter to format text according to a printf()-like format -# string. -#------------------------------------------------------------------------ - -sub format_filter_factory { - my ($context, $format) = @_; - $format = '%s' unless defined $format; - - return sub { - my $text = shift; - $text = '' unless defined $text; - return join("\n", map{ sprintf($format, $_) } split(/\n/, $text)); - } -} - - -#------------------------------------------------------------------------ -# repeat_filter_factory($n) [% FILTER repeat(n) %] -# -# Create a filter to repeat text n times. -#------------------------------------------------------------------------ - -sub repeat_filter_factory { - my ($context, $iter) = @_; - $iter = 1 unless defined $iter and length $iter; - - return sub { - my $text = shift; - $text = '' unless defined $text; - return join('\n', $text) x $iter; - } -} - - -#------------------------------------------------------------------------ -# replace_filter_factory($s, $r) [% FILTER replace(search, replace) %] -# -# Create a filter to replace 'search' text with 'replace' -#------------------------------------------------------------------------ - -sub replace_filter_factory { - my ($context, $search, $replace) = @_; - $search = '' unless defined $search; - $replace = '' unless defined $replace; - - return sub { - my $text = shift; - $text = '' unless defined $text; - $text =~ s/$search/$replace/g; - return $text; - } -} - - -#------------------------------------------------------------------------ -# remove_filter_factory($text) [% FILTER remove(text) %] -# -# Create a filter to remove 'search' string from the input text. -#------------------------------------------------------------------------ - -sub remove_filter_factory { - my ($context, $search) = @_; - - return sub { - my $text = shift; - $text = '' unless defined $text; - $text =~ s/$search//g; - return $text; - } -} - - -#------------------------------------------------------------------------ -# truncate_filter_factory($n) [% FILTER truncate(n) %] -# -# Create a filter to truncate text after n characters. -#------------------------------------------------------------------------ - -sub truncate_filter_factory { - my ($context, $len) = @_; - $len = 32 unless defined $len; - - return sub { - my $text = shift; - return $text if length $text < $len; - return substr($text, 0, $len - 3) . "..."; - } -} - - -#------------------------------------------------------------------------ -# eval_filter_factory [% FILTER eval %] -# -# Create a filter to evaluate template text. -#------------------------------------------------------------------------ - -sub eval_filter_factory { - my $context = shift; - - return sub { - my $text = shift; - $context->process(\$text); - } -} - - -#------------------------------------------------------------------------ -# perl_filter_factory [% FILTER perl %] -# -# Create a filter to process Perl text iff the context EVAL_PERL flag -# is set. -#------------------------------------------------------------------------ - -sub perl_filter_factory { - my $context = shift; - my $stash = $context->stash; - - return (undef, Template::Exception->new('perl', 'EVAL_PERL is not set')) - unless $context->eval_perl(); - - return sub { - my $text = shift; - local($Template::Perl::context) = $context; - local($Template::Perl::stash) = $stash; - my $out = eval <<EOF; -package Template::Perl; -\$stash = \$context->stash(); -$text -EOF - $context->throw($@) if $@; - return $out; - } -} - - -#------------------------------------------------------------------------ -# redirect_filter_factory($context, $file) [% FILTER redirect(file) %] -# -# Create a filter to redirect the block text to a file. -#------------------------------------------------------------------------ - -sub redirect_filter_factory { - my ($context, $file, $options) = @_; - my $outpath = $context->config->{ OUTPUT_PATH }; - - return (undef, Template::Exception->new('redirect', - 'OUTPUT_PATH is not set')) - unless $outpath; - - $options = { binmode => $options } unless ref $options; - - sub { - my $text = shift; - my $outpath = $context->config->{ OUTPUT_PATH } - || return ''; - $outpath .= "/$file"; - my $error = Template::_output($outpath, \$text, $options); - die Template::Exception->new('redirect', $error) - if $error; - return ''; - } -} - - -#------------------------------------------------------------------------ -# stdout_filter_factory($context, $binmode) [% FILTER stdout(binmode) %] -# -# Create a filter to print a block to stdout, with an optional binmode. -#------------------------------------------------------------------------ - -sub stdout_filter_factory { - my ($context, $options) = @_; - - $options = { binmode => $options } unless ref $options; - - sub { - my $text = shift; - binmode(STDOUT) if $options->{ binmode }; - print STDOUT $text; - return ''; - } -} - - -#------------------------------------------------------------------------ -# latex_filter_factory($context, $outputType) [% FILTER latex(outputType) %] -# -# Return a filter sub that converts a (hopefully) complete LaTeX source -# file to either "ps", "dvi", or "pdf". Output type should be "ps", "dvi" -# or "pdf" (pdf is default). -# -# Creates a temporary directory below File::Spec->tmpdir() (often /tmp) -# and writes the text into doc.tex. It then runs either pdflatex or -# latex and optionally dvips. Based on the exit status either returns -# the entire doc.(pdf|ps|dvi) output or throws an error with a summary -# of the error messages from doc.log. -# -# Written by Craig Barratt, Apr 28 2001. -# Win32 additions by Richard Tietjen. -#------------------------------------------------------------------------ -use File::Path; -use File::Spec; -use Cwd; - -sub latex_filter_factory -{ - my($context, $output) = @_; - - $output = lc($output); - my $fName = "latex"; - my($LaTeXPath, $PdfLaTeXPath, $DviPSPath) - = @{Template::Config->latexpaths()}; - if ( $output eq "ps" || $output eq "dvi" ) { - $context->throw($fName, - "latex not installed (see Template::Config::LATEX_PATH)") - if ( $LaTeXPath eq "" ); - } else { - $output = "pdf"; - $LaTeXPath = $PdfLaTeXPath; - $context->throw($fName, - "pdflatex not installed (see Template::Config::PDFLATEX_PATH)") - if ( $LaTeXPath eq "" ); - } - if ( $output eq "ps" && $DviPSPath eq "" ) { - $context->throw($fName, - "dvips not installed (see Template::Config::DVIPS_PATH)"); - } - if ( $^O !~ /^(MacOS|os2|VMS)$/i ) { - return sub { - local(*FH); - my $text = shift; - my $tmpRootDir = File::Spec->tmpdir(); - my $cnt = 0; - my($tmpDir, $fileName, $devnull); - my $texDoc = 'doc'; - - do { - $tmpDir = File::Spec->catdir($tmpRootDir, - "tt2latex$$" . "_$cnt"); - $cnt++; - } while ( -e $tmpDir ); - mkpath($tmpDir, 0, 0700); - $context->throw($fName, "can't create temp dir $tmpDir") - if ( !-d $tmpDir ); - $fileName = File::Spec->catfile($tmpDir, "$texDoc.tex"); - $devnull = File::Spec->devnull(); - if ( !open(FH, ">$fileName") ) { - rmtree($tmpDir); - $context->throw($fName, "can't open $fileName for output"); - } - print(FH $text); - close(FH); - - # latex must run in tmpDir directory - my $currDir = cwd(); - if ( !chdir($tmpDir) ) { - rmtree($tmpDir); - $context->throw($fName, "can't chdir $tmpDir"); - } - # - # We don't need to quote the backslashes on windows, but we - # do on other OSs - # - my $LaTeX_arg = "\\nonstopmode\\input{$texDoc}"; - $LaTeX_arg = "'$LaTeX_arg'" if ( $^O ne 'MSWin32' ); - if ( system("$LaTeXPath $LaTeX_arg" - . " 1>$devnull 2>$devnull 0<$devnull") ) { - my $texErrs = ""; - $fileName = File::Spec->catfile($tmpDir, "$texDoc.log"); - if ( open(FH, "<$fileName") ) { - my $state = 0; - # - # Try to extract just the interesting errors from - # the verbose log file - # - while ( <FH> ) { - # - # TeX errors seems to start with a "!" at the - # start of the line, and are followed several - # lines later by a line designator of the - # form "l.nnn" where nnn is the line number. - # We make sure we pick up every /^!/ line, and - # the first /^l.\d/ line after each /^!/ line. - # - if ( /^(!.*)/ ) { - $texErrs .= $1 . "\n"; - $state = 1; - } - if ( $state == 1 && /^(l\.\d.*)/ ) { - $texErrs .= $1 . "\n"; - $state = 0; - } - } - close(FH); - } else { - $texErrs = "Unable to open $fileName\n"; - } - my $ok = chdir($currDir); - rmtree($tmpDir); - $context->throw($fName, "can't chdir $currDir") if ( !$ok ); - $context->throw($fName, "latex exited with errors:\n$texErrs"); - } - if ( $output eq "ps" ) { - $fileName = File::Spec->catfile($tmpDir, "$texDoc.dvi"); - if ( system("$DviPSPath $texDoc -o" - . " 1>$devnull 2>$devnull 0<$devnull") ) { - my $ok = chdir($currDir); - rmtree($tmpDir); - $context->throw($fName, "can't chdir $currDir") if ( !$ok ); - $context->throw($fName, "can't run $DviPSPath $fileName"); - } - } - if ( !chdir($currDir) ) { - rmtree($tmpDir); - $context->throw($fName, "can't chdir $currDir"); - } - - my $retStr; - $fileName = File::Spec->catfile($tmpDir, "$texDoc.$output"); - if ( open(FH, $fileName) ) { - local $/ = undef; # slurp file in one go - binmode(FH); - $retStr = <FH>; - close(FH); - } else { - rmtree($tmpDir); - $context->throw($fName, "Can't open output file $fileName"); - } - rmtree($tmpDir); - return $retStr; - } - } else { - $context->throw("$fName not yet supported on $^O OS." - . " Please contribute code!!"); - } -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Filters - Post-processing filters for template blocks - -=head1 SYNOPSIS - - use Template::Filters; - - $filters = Template::Filters->new(\%config); - - ($filter, $error) = $filters->fetch($name, \@args, $context); - -=head1 DESCRIPTION - -The Template::Filters module implements a provider for creating and/or -returning subroutines that implement the standard filters. Additional -custom filters may be provided via the FILTERS options. - -=head1 METHODS - -=head2 new(\%params) - -Constructor method which instantiates and returns a reference to a -Template::Filters object. A reference to a hash array of configuration -items may be passed as a parameter. These are described below. - - my $filters = Template::Filters->new({ - FILTERS => { ... }, - }); - - my $template = Template->new({ - LOAD_FILTERS => [ $filters ], - }); - -A default Template::Filters module is created by the Template.pm module -if the LOAD_FILTERS option isn't specified. All configuration parameters -are forwarded to the constructor. - - $template = Template->new({ - FILTERS => { ... }, - }); - -=head2 fetch($name, \@args, $context) - -Called to request that a filter of a given name be provided. The name -of the filter should be specified as the first parameter. This should -be one of the standard filters or one specified in the FILTERS -configuration hash. The second argument should be a reference to an -array containing configuration parameters for the filter. This may be -specified as 0, or undef where no parameters are provided. The third -argument should be a reference to the current Template::Context -object. - -The method returns a reference to a filter sub-routine on success. It -may also return (undef, STATUS_DECLINE) to decline the request, to allow -delegation onto other filter providers in the LOAD_FILTERS chain of -responsibility. On error, ($error, STATUS_ERROR) is returned where $error -is an error message or Template::Exception object indicating the error -that occurred. - -When the TOLERANT option is set, errors are automatically downgraded to -a STATUS_DECLINE response. - - -=head1 CONFIGURATION OPTIONS - -The following list details the configuration options that can be provided -to the Template::Filters new() constructor. - -=over 4 - - - - -=item FILTERS - -The FILTERS option can be used to specify custom filters which can -then be used with the FILTER directive like any other. These are -added to the standard filters which are available by default. Filters -specified via this option will mask any standard filters of the same -name. - -The FILTERS option should be specified as a reference to a hash array -in which each key represents the name of a filter. The corresponding -value should contain a reference to an array containing a subroutine -reference and a flag which indicates if the filter is static (0) or -dynamic (1). A filter may also be specified as a solitary subroutine -reference and is assumed to be static. - - $filters = Template::Filters->new({ - FILTERS => { - 'sfilt1' => \&static_filter, # static - 'sfilt2' => [ \&static_filter, 0 ], # same as above - 'dfilt1' => [ \&dyanamic_filter_factory, 1 ], - }, - }); - -Additional filters can be specified at any time by calling the -define_filter() method on the current Template::Context object. -The method accepts a filter name, a reference to a filter -subroutine and an optional flag to indicate if the filter is -dynamic. - - my $context = $template->context(); - $context->define_filter('new_html', \&new_html); - $context->define_filter('new_repeat', \&new_repeat, 1); - -Static filters are those where a single subroutine reference is used -for all invocations of a particular filter. Filters that don't accept -any configuration parameters (e.g. 'html') can be implemented -statically. The subroutine reference is simply returned when that -particular filter is requested. The subroutine is called to filter -the output of a template block which is passed as the only argument. -The subroutine should return the modified text. - - sub static_filter { - my $text = shift; - # do something to modify $text... - return $text; - } - -The following template fragment: - - [% FILTER sfilt1 %] - Blah blah blah. - [% END %] - -is approximately equivalent to: - - &static_filter("\nBlah blah blah.\n"); - -Filters that can accept parameters (e.g. 'truncate') should be -implemented dynamically. In this case, the subroutine is taken to be -a filter 'factory' that is called to create a unique filter subroutine -each time one is requested. A reference to the current -Template::Context object is passed as the first parameter, followed by -any additional parameters specified. The subroutine should return -another subroutine reference (usually a closure) which implements the -filter. - - sub dynamic_filter_factory { - my ($context, @args) = @_; - - return sub { - my $text = shift; - # do something to modify $text... - return $text; - } - } - -The following template fragment: - - [% FILTER dfilt1(123, 456) %] - Blah blah blah - [% END %] - -is approximately equivalent to: - - my $filter = &dynamic_filter_factory($context, 123, 456); - &$filter("\nBlah blah blah.\n"); - -See the FILTER directive for further examples. - - - - -=item TOLERANT - -The TOLERANT flag is used by the various Template Toolkit provider -modules (Template::Provider, Template::Plugins, Template::Filters) to -control their behaviour when errors are encountered. By default, any -errors are reported as such, with the request for the particular -resource (template, plugin, filter) being denied and an exception -raised. When the TOLERANT flag is set to any true values, errors will -be silently ignored and the provider will instead return -STATUS_DECLINED. This allows a subsequent provider to take -responsibility for providing the resource, rather than failing the -request outright. If all providers decline to service the request, -either through tolerated failure or a genuine disinclination to -comply, then a 'E<lt>resourceE<gt> not found' exception is raised. - - - - -=item DEBUG - -The DEBUG option can be used to enable debugging messages from the -Template::Filters module by setting it to include the DEBUG_FILTERS -value. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_FILTERS | DEBUG_PLUGINS, - }); - - - - -=back - -=head1 TEMPLATE TOOLKIT FILTERS - -The following standard filters are distributed with the Template Toolkit. - - - -=head2 format(format) - -The 'format' filter takes a format string as a parameter (as per -printf()) and formats each line of text accordingly. - - [% FILTER format('<!-- %-40s -->') %] - This is a block of text filtered - through the above format. - [% END %] - -output: - - <!-- This is a block of text filtered --> - <!-- through the above format. --> - -=head2 upper - -Folds the input to UPPER CASE. - - [% "hello world" FILTER upper %] - -output: - - HELLO WORLD - -=head2 lower - -Folds the input to lower case. - - [% "Hello World" FILTER lower %] - -output: - - hello world - -=head2 ucfirst - -Folds the first character of the input to UPPER CASE. - - [% "hello" FILTER ucfirst %] - -output: - - Hello - -=head2 lcfirst - -Folds the first character of the input to lower case. - - [% "HELLO" FILTER lcfirst %] - -output: - - hELLO - -=head2 trim - -Trims any leading or trailing whitespace from the input text. Particularly -useful in conjunction with INCLUDE, PROCESS, etc., having the same effect -as the TRIM configuration option. - - [% INCLUDE myfile | trim %] - -=head2 collapse - -Collapse any whitespace sequences in the input text into a single space. -Leading and trailing whitespace (which would be reduced to a single space) -is removed, as per trim. - - [% FILTER collapse %] - - The cat - - sat on - - the mat - - [% END %] - -output: - - The cat sat on the mat - -=head2 html - -Converts the characters 'E<lt>', 'E<gt>' and '&' to '<', '>' and -'&', respectively, protecting them from being interpreted as -representing HTML tags or entities. - - [% FILTER html %] - Binary "<=>" returns -1, 0, or 1 depending on... - [% END %] - -output: - - Binary "<=>" returns -1, 0, or 1 depending on... - -=head2 html_entity - -The html filter is fast and simple but it doesn't encode the full -range of HTML entities that your text may contain. The html_entity -filter uses either the Apache::Util module (which is written in C and -is therefore faster) or the HTML::Entities module (written in Perl but -equally as comprehensive) to perform the encoding. If one or other of -these modules are installed on your system then the text will be -encoded (via the escape_html() or encode_entities() subroutines -respectively) to convert all extended characters into their -appropriate HTML entities (e.g. converting 'é' to 'é'). If -neither module is available on your system then an 'html_entity' exception -will be thrown reporting an appropriate message. - -For further information on HTML entity encoding, see -http://www.w3.org/TR/REC-html40/sgml/entities.html. - -=head2 html_para - -This filter formats a block of text into HTML paragraphs. A sequence of -two or more newlines is used as the delimiter for paragraphs which are -then wrapped in HTML E<lt>pE<gt>...E<lt>/pE<gt> tags. - - [% FILTER html_para %] - The cat sat on the mat. - - Mary had a little lamb. - [% END %] - -output: - - <p> - The cat sat on the mat. - </p> - - <p> - Mary had a little lamb. - </p> - -=head2 html_break / html_para_break - -Similar to the html_para filter described above, but uses the HTML tag -sequence E<lt>brE<gt>E<lt>brE<gt> to join paragraphs. - - [% FILTER html_break %] - The cat sat on the mat. - - Mary had a little lamb. - [% END %] - -output: - - The cat sat on the mat. - <br> - <br> - Mary had a little lamb. - -=head2 html_line_break - -This filter replaces any newlines with E<lt>brE<gt> HTML tags, -thus preserving the line breaks of the original text in the -HTML output. - - [% FILTER html_line_break %] - The cat sat on the mat. - Mary had a little lamb. - [% END %] - -output: - - The cat sat on the mat.<br> - Mary had a little lamb.<br> - -=head2 uri - -This filter URI escapes the input text, converting any characters -outside of the permitted URI character set (as defined by RFC 2396) -into a C<%nn> hex escape. - - [% 'my file.html' | uri %] - -output: - - my%20file.html - -Note that URI escaping isn't always enough when generating hyperlinks in -an HTML document. The C<&> character, for example, is valid in a URI and -will not be escaped by the URI filter. In this case you should also filter -the text through the 'html' filter. - - <a href="[% filename | uri | html %]">click here</a> - -=head2 indent(pad) - -Indents the text block by a fixed pad string or width. The 'pad' argument -can be specified as a string, or as a numerical value to indicate a pad -width (spaces). Defaults to 4 spaces if unspecified. - - [% FILTER indent('ME> ') %] - blah blah blah - cabbages, rhubard, onions - [% END %] - -output: - - ME> blah blah blah - ME> cabbages, rhubard, onions - -=head2 truncate(length) - -Truncates the text block to the length specified, or a default length of -32. Truncated text will be terminated with '...' (i.e. the '...' falls -inside the required length, rather than appending to it). - - [% FILTER truncate(21) %] - I have much to say on this matter that has previously - been said on more than one occasion. - [% END %] - -output: - - I have much to say... - -=head2 repeat(iterations) - -Repeats the text block for as many iterations as are specified (default: 1). - - [% FILTER repeat(3) %] - We want more beer and we want more beer, - [% END %] - We are the more beer wanters! - -output: - - We want more beer and we want more beer, - We want more beer and we want more beer, - We want more beer and we want more beer, - We are the more beer wanters! - -=head2 remove(string) - -Searches the input text for any occurrences of the specified string and -removes them. A Perl regular expression may be specified as the search -string. - - [% "The cat sat on the mat" FILTER remove('\s+') %] - -output: - - Thecatsatonthemat - -=head2 replace(search, replace) - -Similar to the remove filter described above, but taking a second parameter -which is used as a replacement string for instances of the search string. - - [% "The cat sat on the mat" | replace('\s+', '_') %] - -output: - - The_cat_sat_on_the_mat - -=head2 redirect(file, options) - -The 'redirect' filter redirects the output of the block into a separate -file, specified relative to the OUTPUT_PATH configuration item. - - [% FOREACH user = myorg.userlist %] - [% FILTER redirect("users/${user.id}.html") %] - [% INCLUDE userinfo %] - [% END %] - [% END %] - -or more succinctly, using side-effect notation: - - [% INCLUDE userinfo - FILTER redirect("users/${user.id}.html") - FOREACH user = myorg.userlist - %] - -A 'file' exception will be thrown if the OUTPUT_PATH option is undefined. - -An optional 'binmode' argument can follow the filename to explicitly set -the output file to binary mode. - - [% PROCESS my/png/generator - FILTER redirect("images/logo.png", binmode=1) %] - -For backwards compatibility with earlier versions, a single true/false -value can be used to set binary mode. - - [% PROCESS my/png/generator - FILTER redirect("images/logo.png", 1) %] - -For the sake of future compatibility and clarity, if nothing else, we -would strongly recommend you explicitly use the named 'binmode' option -as shown in the first example. - -=head2 eval / evaltt - -The 'eval' filter evaluates the block as template text, processing -any directives embedded within it. This allows template variables to -contain template fragments, or for some method to be provided for -returning template fragments from an external source such as a -database, which can then be processed in the template as required. - - my $vars = { - fragment => "The cat sat on the [% place %]", - }; - $template->process($file, $vars); - -The following example: - - [% fragment | eval %] - -is therefore equivalent to - - The cat sat on the [% place %] - -The 'evaltt' filter is provided as an alias for 'eval'. - -=head2 perl / evalperl - -The 'perl' filter evaluates the block as Perl code. The EVAL_PERL -option must be set to a true value or a 'perl' exception will be -thrown. - - [% my_perl_code | perl %] - -In most cases, the [% PERL %] ... [% END %] block should suffice for -evaluating Perl code, given that template directives are processed -before being evaluate as Perl. Thus, the previous example could have -been written in the more verbose form: - - [% PERL %] - [% my_perl_code %] - [% END %] - -as well as - - [% FILTER perl %] - [% my_perl_code %] - [% END %] - -The 'evalperl' filter is provided as an alias for 'perl' for backwards -compatibility. - -=head2 stdout(options) - -The stdout filter prints the output generated by the enclosing block to -STDOUT. The 'binmode' option can be passed as either a named parameter -or a single argument to set STDOUT to binary mode (see the -binmode perl function). - - [% PROCESS something/cool - FILTER stdout(binmode=1) # recommended %] - - [% PROCESS something/cool - FILTER stdout(1) # alternate %] - -The stdout filter can be used to force binmode on STDOUT, or also inside -redirect, null or stderr blocks to make sure that particular output goes -to stdout. See the null filter below for an example. - -=head2 stderr - -The stderr filter prints the output generated by the enclosing block to -STDERR. - -=head2 null - -The null filter prints nothing. This is useful for plugins whose -methods return values that you don't want to appear in the output. -Rather than assigning every plugin method call to a dummy variable -to silence it, you can wrap the block in a null filter: - - [% FILTER null; - USE im = GD.Image(100,100); - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0, 255); - im.arc(50,50,95,75,0,360,blue); - im.fill(50,50,red); - im.png | stdout(1); - END; - -%] - -Notice the use of the stdout filter to ensure that a particular expression -generates output to stdout (in this case in binary mode). - -=head2 latex(outputType) - -Passes the text block to LaTeX and produces either PDF, DVI or -PostScript output. The 'outputType' argument determines the output -format and it should be set to one of the strings: "pdf" (default), -"dvi", or "ps". - -The text block should be a complete LaTeX source file. - - [% FILTER latex("pdf") -%] - \documentclass{article} - - \begin{document} - - \title{A Sample TT2 \LaTeX\ Source File} - \author{Craig Barratt} - \maketitle - - \section{Introduction} - This is some text. - - \end{document} - [% END -%] - -The output will be a PDF file. You should be careful not to prepend or -append any extraneous characters or text outside the FILTER block, -since this text will wrap the (binary) output of the latex filter. -Notice the END directive uses '-%]' for the END_TAG to remove the -trailing new line. - -One example where you might prepend text is in a CGI script where -you might include the Content-Type before the latex output, eg: - - Content-Type: application/pdf - - [% FILTER latex("pdf") -%] - \documentclass{article} - \begin{document} - ... - \end{document} - [% END -%] - -In other cases you might use the redirect filter to put the output -into a file, rather than delivering it to stdout. This might be -suitable for batch scripts: - - [% output = FILTER latex("pdf") -%] - \documentclass{article} - \begin{document} - ... - \end{document} - [% END; output | redirect("document.pdf", 1) -%] - -(Notice the second argument to redirect to force binary mode.) - -Note that the latex filter runs one or two external programs, so it -isn't very fast. But for modest documents the performance is adequate, -even for interactive applications. - -A error of type 'latex' will be thrown if there is an error reported -by latex, pdflatex or dvips. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.77, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Context|Template::Context>, L<Template::Manual::Filters|Template::Manual::Filters> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Grammar.pm b/lib/Template/Grammar.pm deleted file mode 100644 index 8635426..0000000 --- a/lib/Template/Grammar.pm +++ /dev/null @@ -1,6179 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Grammar -# -# DESCRIPTION -# Grammar file for the Template Toolkit language containing token -# definitions and parser state/rules tables generated by Parse::Yapp. -# -# AUTHOR -# Andy Wardley <abw@wardley.org> -# -# 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. -# -#------------------------------------------------------------------------ -# -# NOTE: this module is constructed from the parser/Grammar.pm.skel -# file by running the parser/yc script. You only need to do this if -# you have modified the grammar in the parser/Parser.yp file and need -# to-recompile it. See the README in the 'parser' directory for more -# information (sub-directory of the Template distribution). -# -#------------------------------------------------------------------------ -# -# $Id: Grammar.pm,v 2.22 2004/01/13 16:19:10 abw Exp $ -# -#======================================================================== - -package Template::Grammar; - -require 5.004; - -use strict; -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.22 $ =~ /(\d+)\.(\d+)/); - -my (@RESERVED, %CMPOP, $LEXTABLE, $RULES, $STATES); -my ($factory, $rawstart); - - -#======================================================================== - -# Reserved words, comparison and binary operators -#======================================================================== - -@RESERVED = qw( - GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER BLOCK END - USE PLUGIN FILTER MACRO PERL RAWPERL TO STEP AND OR NOT DIV MOD - IF UNLESS ELSE ELSIF FOR NEXT WHILE SWITCH CASE META IN - TRY THROW CATCH FINAL LAST RETURN STOP CLEAR VIEW DEBUG - ); - -# for historical reasons, != and == are converted to ne and eq to perform -# stringwise comparison (mainly because it doesn't generate "non-numerical -# comparison" warnings which != and == can) but the others (e.g. < > <= >=) -# are not converted to their stringwise equivalents. I added 'gt' et al, -# briefly for v2.04d and then took them out again in 2.04e. - -%CMPOP = qw( - != ne - == eq - < < - > > - >= >= - <= <= -); - - -#======================================================================== -# Lexer Token Table -#======================================================================== - -# lookup table used by lexer is initialised with special-cases -$LEXTABLE = { - 'FOREACH' => 'FOR', - 'BREAK' => 'LAST', - '&&' => 'AND', - '||' => 'OR', - '!' => 'NOT', - '|' => 'FILTER', - '.' => 'DOT', - '_' => 'CAT', - '..' => 'TO', -# ':' => 'MACRO', - '=' => 'ASSIGN', - '=>' => 'ASSIGN', -# '->' => 'ARROW', - ',' => 'COMMA', - '\\' => 'REF', - 'and' => 'AND', # explicitly specified so that qw( and or - 'or' => 'OR', # not ) can always be used in lower case, - 'not' => 'NOT', # regardless of ANYCASE flag - 'mod' => 'MOD', - 'div' => 'DIV', -}; - -# localise the temporary variables needed to complete lexer table -{ -# my @tokens = qw< ( ) [ ] { } ${ $ / ; : ? >; - my @tokens = qw< ( ) [ ] { } ${ $ + / ; : ? >; - my @cmpop = keys %CMPOP; -# my @binop = qw( + - * % ); # '/' above, in @tokens - my @binop = qw( - * % ); # '+' and '/' above, in @tokens - - # fill lexer table, slice by slice, with reserved words and operators - @$LEXTABLE{ @RESERVED, @cmpop, @binop, @tokens } - = ( @RESERVED, ('CMPOP') x @cmpop, ('BINOP') x @binop, @tokens ); -} - - -#======================================================================== -# CLASS METHODS -#======================================================================== - -sub new { - my $class = shift; - bless { - LEXTABLE => $LEXTABLE, - STATES => $STATES, - RULES => $RULES, - }, $class; -} - -# update method to set package-scoped $factory lexical -sub install_factory { - my ($self, $new_factory) = @_; - $factory = $new_factory; -} - - -#======================================================================== -# States -#======================================================================== - -$STATES = [ - {#State 0 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'template' => 52, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'switch' => 34, - 'try' => 35, - 'assign' => 19, - 'block' => 72, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 1 - ACTIONS => { - "\$" => 43, - 'LITERAL' => 75, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'setlist' => 76, - 'item' => 39, - 'assign' => 19, - 'node' => 23, - 'ident' => 74 - } - }, - {#State 2 - DEFAULT => -130 - }, - {#State 3 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 79, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 4 - DEFAULT => -23 - }, - {#State 5 - ACTIONS => { - ";" => 80 - } - }, - {#State 6 - DEFAULT => -37 - }, - {#State 7 - DEFAULT => -14 - }, - {#State 8 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 90, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 9 - ACTIONS => { - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "]" => 94, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 96, - 'item' => 39, - 'range' => 93, - 'node' => 23, - 'ident' => 77, - 'term' => 95, - 'list' => 92, - 'lterm' => 56 - } - }, - {#State 10 - ACTIONS => { - ";" => 97 - } - }, - {#State 11 - DEFAULT => -5 - }, - {#State 12 - ACTIONS => { - ";" => -20 - }, - DEFAULT => -27 - }, - {#State 13 - DEFAULT => -78, - GOTOS => { - '@5-1' => 98 - } - }, - {#State 14 - ACTIONS => { - 'IDENT' => 99 - }, - DEFAULT => -87, - GOTOS => { - 'blockargs' => 102, - 'metadata' => 101, - 'meta' => 100 - } - }, - {#State 15 - ACTIONS => { - 'IDENT' => 99 - }, - GOTOS => { - 'metadata' => 103, - 'meta' => 100 - } - }, - {#State 16 - ACTIONS => { - 'DOT' => 104, - 'ASSIGN' => 105 - }, - DEFAULT => -109 - }, - {#State 17 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 106, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 18 - ACTIONS => { - 'IDENT' => 107 - } - }, - {#State 19 - DEFAULT => -149 - }, - {#State 20 - DEFAULT => -12 - }, - {#State 21 - ACTIONS => { - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 108, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'loopvar' => 110, - 'node' => 23, - 'ident' => 77, - 'term' => 109, - 'lterm' => 56 - } - }, - {#State 22 - DEFAULT => -40 - }, - {#State 23 - DEFAULT => -127 - }, - {#State 24 - DEFAULT => -6 - }, - {#State 25 - ACTIONS => { - "\"" => 117, - "\$" => 114, - 'LITERAL' => 116, - 'FILENAME' => 83, - 'IDENT' => 111, - 'NUMBER' => 84, - "\${" => 37 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 118, - 'filename' => 85, - 'lvalue' => 112, - 'lnameargs' => 115, - 'item' => 113, - 'name' => 82 - } - }, - {#State 26 - DEFAULT => -113 - }, - {#State 27 - ACTIONS => { - "\$" => 43, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'ident' => 119 - } - }, - {#State 28 - ACTIONS => { - 'LITERAL' => 124, - 'FILENAME' => 83, - 'IDENT' => 120, - 'NUMBER' => 84 - }, - DEFAULT => -87, - GOTOS => { - 'blockargs' => 123, - 'filepart' => 87, - 'filename' => 122, - 'blockname' => 121, - 'metadata' => 101, - 'meta' => 100 - } - }, - {#State 29 - DEFAULT => -43 - }, - {#State 30 - ACTIONS => { - "\$" => 43, - 'LITERAL' => 129, - 'IDENT' => 2, - "\${" => 37 - }, - DEFAULT => -119, - GOTOS => { - 'params' => 128, - 'hash' => 125, - 'item' => 126, - 'param' => 127 - } - }, - {#State 31 - DEFAULT => -25 - }, - {#State 32 - ACTIONS => { - "\"" => 117, - "\$" => 114, - 'LITERAL' => 116, - 'FILENAME' => 83, - 'IDENT' => 111, - 'NUMBER' => 84, - "\${" => 37 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 118, - 'filename' => 85, - 'lvalue' => 112, - 'lnameargs' => 130, - 'item' => 113, - 'name' => 82 - } - }, - {#State 33 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -2, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 131, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 34 - DEFAULT => -22 - }, - {#State 35 - DEFAULT => -24 - }, - {#State 36 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 132, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 37 - ACTIONS => { - "\"" => 60, - "\$" => 43, - 'LITERAL' => 78, - 'IDENT' => 2, - 'REF' => 27, - 'NUMBER' => 26, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 133, - 'item' => 39, - 'node' => 23, - 'ident' => 77 - } - }, - {#State 38 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 134, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 39 - ACTIONS => { - "(" => 135 - }, - DEFAULT => -128 - }, - {#State 40 - ACTIONS => { - ";" => 136 - } - }, - {#State 41 - DEFAULT => -38 - }, - {#State 42 - DEFAULT => -11 - }, - {#State 43 - ACTIONS => { - 'IDENT' => 137 - } - }, - {#State 44 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 138, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 45 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 139, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 46 - DEFAULT => -42 - }, - {#State 47 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 140, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 48 - ACTIONS => { - 'IF' => 144, - 'FILTER' => 143, - 'FOR' => 142, - 'WHILE' => 146, - 'WRAPPER' => 145, - 'UNLESS' => 141 - } - }, - {#State 49 - DEFAULT => -39 - }, - {#State 50 - DEFAULT => -10 - }, - {#State 51 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 147, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 52 - ACTIONS => { - '' => 148 - } - }, - {#State 53 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 57, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 149, - 'term' => 58, - 'expr' => 151, - 'assign' => 150, - 'lterm' => 56 - } - }, - {#State 54 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 152, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 55 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 153, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 56 - DEFAULT => -103 - }, - {#State 57 - ACTIONS => { - 'ASSIGN' => 154 - }, - DEFAULT => -112 - }, - {#State 58 - DEFAULT => -146 - }, - {#State 59 - DEFAULT => -15 - }, - {#State 60 - DEFAULT => -176, - GOTOS => { - 'quoted' => 155 - } - }, - {#State 61 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 156, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 62 - ACTIONS => { - ";" => -16, - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -26 - }, - {#State 63 - DEFAULT => -13 - }, - {#State 64 - DEFAULT => -36 - }, - {#State 65 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 167, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 66 - DEFAULT => -9 - }, - {#State 67 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 168, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 68 - DEFAULT => -104 - }, - {#State 69 - ACTIONS => { - "\$" => 43, - 'LITERAL' => 75, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'setlist' => 169, - 'item' => 39, - 'assign' => 19, - 'node' => 23, - 'ident' => 74 - } - }, - {#State 70 - ACTIONS => { - "\$" => 43, - 'COMMA' => 171, - 'LITERAL' => 75, - 'IDENT' => 2, - "\${" => 37 - }, - DEFAULT => -19, - GOTOS => { - 'item' => 39, - 'assign' => 170, - 'node' => 23, - 'ident' => 74 - } - }, - {#State 71 - DEFAULT => -8 - }, - {#State 72 - DEFAULT => -1 - }, - {#State 73 - DEFAULT => -21 - }, - {#State 74 - ACTIONS => { - 'ASSIGN' => 172, - 'DOT' => 104 - } - }, - {#State 75 - ACTIONS => { - 'ASSIGN' => 154 - } - }, - {#State 76 - ACTIONS => { - "\$" => 43, - 'COMMA' => 171, - 'LITERAL' => 75, - 'IDENT' => 2, - "\${" => 37 - }, - DEFAULT => -30, - GOTOS => { - 'item' => 39, - 'assign' => 170, - 'node' => 23, - 'ident' => 74 - } - }, - {#State 77 - ACTIONS => { - 'DOT' => 104 - }, - DEFAULT => -109 - }, - {#State 78 - DEFAULT => -112 - }, - {#State 79 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - ";" => 173, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - } - }, - {#State 80 - DEFAULT => -7 - }, - {#State 81 - DEFAULT => -173 - }, - {#State 82 - DEFAULT => -166 - }, - {#State 83 - DEFAULT => -172 - }, - {#State 84 - DEFAULT => -174 - }, - {#State 85 - ACTIONS => { - 'DOT' => 174 - }, - DEFAULT => -168 - }, - {#State 86 - ACTIONS => { - "\$" => 43, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'ident' => 175 - } - }, - {#State 87 - DEFAULT => -171 - }, - {#State 88 - DEFAULT => -169 - }, - {#State 89 - DEFAULT => -176, - GOTOS => { - 'quoted' => 176 - } - }, - {#State 90 - DEFAULT => -35 - }, - {#State 91 - ACTIONS => { - "+" => 177, - "(" => 178 - }, - DEFAULT => -156, - GOTOS => { - 'args' => 179 - } - }, - {#State 92 - ACTIONS => { - "{" => 30, - 'COMMA' => 182, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "]" => 180, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 181, - 'lterm' => 56 - } - }, - {#State 93 - ACTIONS => { - "]" => 183 - } - }, - {#State 94 - DEFAULT => -107 - }, - {#State 95 - DEFAULT => -116 - }, - {#State 96 - ACTIONS => { - 'TO' => 184 - }, - DEFAULT => -104 - }, - {#State 97 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 185, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 98 - ACTIONS => { - ";" => 186 - } - }, - {#State 99 - ACTIONS => { - 'ASSIGN' => 187 - } - }, - {#State 100 - DEFAULT => -99 - }, - {#State 101 - ACTIONS => { - 'COMMA' => 189, - 'IDENT' => 99 - }, - DEFAULT => -86, - GOTOS => { - 'meta' => 188 - } - }, - {#State 102 - ACTIONS => { - ";" => 190 - } - }, - {#State 103 - ACTIONS => { - 'COMMA' => 189, - 'IDENT' => 99 - }, - DEFAULT => -17, - GOTOS => { - 'meta' => 188 - } - }, - {#State 104 - ACTIONS => { - "\$" => 43, - 'IDENT' => 2, - 'NUMBER' => 192, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 191 - } - }, - {#State 105 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'WRAPPER' => 55, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - "\"" => 60, - 'PROCESS' => 61, - 'FILTER' => 25, - 'RETURN' => 64, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 193, - 'DEFAULT' => 69, - "{" => 30, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'term' => 58, - 'loop' => 4, - 'expr' => 195, - 'wrapper' => 46, - 'atomexpr' => 48, - 'atomdir' => 12, - 'mdir' => 194, - 'sterm' => 68, - 'filter' => 29, - 'ident' => 149, - 'perl' => 31, - 'setlist' => 70, - 'switch' => 34, - 'try' => 35, - 'assign' => 19, - 'directive' => 196, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 106 - DEFAULT => -33 - }, - {#State 107 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'INCLUDE' => 17, - "(" => 198, - 'SWITCH' => 54, - 'WRAPPER' => 55, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - "\"" => 60, - 'PROCESS' => 61, - 'FILTER' => 25, - 'RETURN' => 64, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 193, - 'DEFAULT' => 69, - "{" => 30, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'term' => 58, - 'loop' => 4, - 'expr' => 199, - 'wrapper' => 46, - 'atomexpr' => 48, - 'atomdir' => 12, - 'mdir' => 197, - 'sterm' => 68, - 'filter' => 29, - 'ident' => 149, - 'perl' => 31, - 'setlist' => 70, - 'switch' => 34, - 'try' => 35, - 'assign' => 19, - 'directive' => 196, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 108 - ACTIONS => { - 'IN' => 201, - 'ASSIGN' => 200 - }, - DEFAULT => -130 - }, - {#State 109 - DEFAULT => -156, - GOTOS => { - 'args' => 202 - } - }, - {#State 110 - ACTIONS => { - ";" => 203 - } - }, - {#State 111 - ACTIONS => { - 'ASSIGN' => -130 - }, - DEFAULT => -173 - }, - {#State 112 - ACTIONS => { - 'ASSIGN' => 204 - } - }, - {#State 113 - DEFAULT => -159 - }, - {#State 114 - ACTIONS => { - "\$" => 43, - 'IDENT' => 205, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'ident' => 175 - } - }, - {#State 115 - ACTIONS => { - ";" => 206 - } - }, - {#State 116 - ACTIONS => { - 'ASSIGN' => -161 - }, - DEFAULT => -169 - }, - {#State 117 - DEFAULT => -176, - GOTOS => { - 'quoted' => 207 - } - }, - {#State 118 - DEFAULT => -158 - }, - {#State 119 - ACTIONS => { - 'DOT' => 104 - }, - DEFAULT => -110 - }, - {#State 120 - ACTIONS => { - 'ASSIGN' => 187 - }, - DEFAULT => -173 - }, - {#State 121 - DEFAULT => -83 - }, - {#State 122 - ACTIONS => { - 'DOT' => 174 - }, - DEFAULT => -84 - }, - {#State 123 - ACTIONS => { - ";" => 208 - } - }, - {#State 124 - DEFAULT => -85 - }, - {#State 125 - ACTIONS => { - "}" => 209 - } - }, - {#State 126 - ACTIONS => { - 'ASSIGN' => 210 - } - }, - {#State 127 - DEFAULT => -122 - }, - {#State 128 - ACTIONS => { - "\$" => 43, - 'COMMA' => 212, - 'LITERAL' => 129, - 'IDENT' => 2, - "\${" => 37 - }, - DEFAULT => -118, - GOTOS => { - 'item' => 126, - 'param' => 211 - } - }, - {#State 129 - ACTIONS => { - 'ASSIGN' => 213 - } - }, - {#State 130 - DEFAULT => -73 - }, - {#State 131 - DEFAULT => -4 - }, - {#State 132 - ACTIONS => { - ";" => 214 - } - }, - {#State 133 - ACTIONS => { - "}" => 215 - } - }, - {#State 134 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'BINOP' => 161 - }, - DEFAULT => -142 - }, - {#State 135 - DEFAULT => -156, - GOTOS => { - 'args' => 216 - } - }, - {#State 136 - DEFAULT => -76, - GOTOS => { - '@4-2' => 217 - } - }, - {#State 137 - DEFAULT => -132 - }, - {#State 138 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - ";" => 218, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - } - }, - {#State 139 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -29 - }, - {#State 140 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -28 - }, - {#State 141 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 219, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 142 - ACTIONS => { - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 108, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'loopvar' => 220, - 'node' => 23, - 'ident' => 77, - 'term' => 109, - 'lterm' => 56 - } - }, - {#State 143 - ACTIONS => { - "\"" => 117, - "\$" => 114, - 'LITERAL' => 116, - 'FILENAME' => 83, - 'IDENT' => 111, - 'NUMBER' => 84, - "\${" => 37 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 118, - 'filename' => 85, - 'lvalue' => 112, - 'lnameargs' => 221, - 'item' => 113, - 'name' => 82 - } - }, - {#State 144 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 222, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 145 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 223, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 146 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 224, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 147 - DEFAULT => -41 - }, - {#State 148 - DEFAULT => 0 - }, - {#State 149 - ACTIONS => { - 'DOT' => 104, - 'ASSIGN' => 172 - }, - DEFAULT => -109 - }, - {#State 150 - ACTIONS => { - ")" => 225 - } - }, - {#State 151 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - ")" => 226, - 'OR' => 162 - } - }, - {#State 152 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - ";" => 227, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - } - }, - {#State 153 - ACTIONS => { - ";" => 228 - } - }, - {#State 154 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 229, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 155 - ACTIONS => { - "\"" => 234, - 'TEXT' => 231, - ";" => 233, - "\$" => 43, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'ident' => 230, - 'quotable' => 232 - } - }, - {#State 156 - DEFAULT => -34 - }, - {#State 157 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 235, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 158 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 236, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 159 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 237, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 160 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 238, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 161 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 239, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 162 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 240, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 163 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 241, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 164 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 242, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 165 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 243, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 166 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 244, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 167 - DEFAULT => -32 - }, - {#State 168 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - ";" => 245, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - } - }, - {#State 169 - ACTIONS => { - "\$" => 43, - 'COMMA' => 171, - 'LITERAL' => 75, - 'IDENT' => 2, - "\${" => 37 - }, - DEFAULT => -31, - GOTOS => { - 'item' => 39, - 'assign' => 170, - 'node' => 23, - 'ident' => 74 - } - }, - {#State 170 - DEFAULT => -147 - }, - {#State 171 - DEFAULT => -148 - }, - {#State 172 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 246, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 173 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 247, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 174 - ACTIONS => { - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 248 - } - }, - {#State 175 - ACTIONS => { - 'DOT' => 104 - }, - DEFAULT => -156, - GOTOS => { - 'args' => 249 - } - }, - {#State 176 - ACTIONS => { - "\"" => 250, - 'TEXT' => 231, - ";" => 233, - "\$" => 43, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'ident' => 230, - 'quotable' => 232 - } - }, - {#State 177 - ACTIONS => { - "\"" => 89, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'filename' => 85, - 'name' => 251 - } - }, - {#State 178 - DEFAULT => -156, - GOTOS => { - 'args' => 252 - } - }, - {#State 179 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - DEFAULT => -163, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 180 - DEFAULT => -105 - }, - {#State 181 - DEFAULT => -114 - }, - {#State 182 - DEFAULT => -115 - }, - {#State 183 - DEFAULT => -106 - }, - {#State 184 - ACTIONS => { - "\"" => 60, - "\$" => 43, - 'LITERAL' => 78, - 'IDENT' => 2, - 'REF' => 27, - 'NUMBER' => 26, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 259, - 'item' => 39, - 'node' => 23, - 'ident' => 77 - } - }, - {#State 185 - ACTIONS => { - 'FINAL' => 260, - 'CATCH' => 262 - }, - DEFAULT => -72, - GOTOS => { - 'final' => 261 - } - }, - {#State 186 - ACTIONS => { - 'TEXT' => 263 - } - }, - {#State 187 - ACTIONS => { - "\"" => 266, - 'LITERAL' => 265, - 'NUMBER' => 264 - } - }, - {#State 188 - DEFAULT => -97 - }, - {#State 189 - DEFAULT => -98 - }, - {#State 190 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'template' => 267, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 72, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 191 - DEFAULT => -125 - }, - {#State 192 - DEFAULT => -126 - }, - {#State 193 - ACTIONS => { - ";" => 268 - } - }, - {#State 194 - DEFAULT => -89 - }, - {#State 195 - ACTIONS => { - ";" => -150, - "+" => 157, - 'LITERAL' => -150, - 'IDENT' => -150, - 'CAT' => 163, - "\$" => -150, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - 'COMMA' => -150, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162, - "\${" => -150 - }, - DEFAULT => -26 - }, - {#State 196 - DEFAULT => -92 - }, - {#State 197 - DEFAULT => -91 - }, - {#State 198 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 57, - 'IDENT' => 269, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'margs' => 270, - 'node' => 23, - 'ident' => 149, - 'term' => 58, - 'expr' => 151, - 'assign' => 150, - 'lterm' => 56 - } - }, - {#State 199 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -26 - }, - {#State 200 - ACTIONS => { - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 271, - 'lterm' => 56 - } - }, - {#State 201 - ACTIONS => { - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 272, - 'lterm' => 56 - } - }, - {#State 202 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - DEFAULT => -64, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 203 - DEFAULT => -56, - GOTOS => { - '@1-3' => 273 - } - }, - {#State 204 - ACTIONS => { - "\"" => 89, - "\$" => 86, - 'LITERAL' => 88, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'names' => 91, - 'nameargs' => 274, - 'filename' => 85, - 'name' => 82 - } - }, - {#State 205 - ACTIONS => { - 'ASSIGN' => -132 - }, - DEFAULT => -130 - }, - {#State 206 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 275, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 207 - ACTIONS => { - "\"" => 276, - 'TEXT' => 231, - ";" => 233, - "\$" => 43, - 'IDENT' => 2, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'ident' => 230, - 'quotable' => 232 - } - }, - {#State 208 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 277, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 209 - DEFAULT => -108 - }, - {#State 210 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 278, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 211 - DEFAULT => -120 - }, - {#State 212 - DEFAULT => -121 - }, - {#State 213 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 279, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 214 - DEFAULT => -74, - GOTOS => { - '@3-3' => 280 - } - }, - {#State 215 - DEFAULT => -131 - }, - {#State 216 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - ")" => 281, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 217 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 282, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 218 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 283, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 219 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -47 - }, - {#State 220 - DEFAULT => -58 - }, - {#State 221 - DEFAULT => -81 - }, - {#State 222 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -45 - }, - {#State 223 - DEFAULT => -66 - }, - {#State 224 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -61 - }, - {#State 225 - DEFAULT => -144 - }, - {#State 226 - DEFAULT => -145 - }, - {#State 227 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 284, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 228 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 285, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 229 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -151 - }, - {#State 230 - ACTIONS => { - 'DOT' => 104 - }, - DEFAULT => -177 - }, - {#State 231 - DEFAULT => -178 - }, - {#State 232 - DEFAULT => -175 - }, - {#State 233 - DEFAULT => -179 - }, - {#State 234 - DEFAULT => -111 - }, - {#State 235 - ACTIONS => { - 'DIV' => 159, - 'MOD' => 165, - "/" => 166 - }, - DEFAULT => -135 - }, - {#State 236 - ACTIONS => { - ":" => 286, - 'CMPOP' => 164, - "?" => 158, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - } - }, - {#State 237 - ACTIONS => { - 'MOD' => 165 - }, - DEFAULT => -136 - }, - {#State 238 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'BINOP' => 161 - }, - DEFAULT => -140 - }, - {#State 239 - ACTIONS => { - "+" => 157, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166 - }, - DEFAULT => -133 - }, - {#State 240 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'BINOP' => 161 - }, - DEFAULT => -141 - }, - {#State 241 - ACTIONS => { - "+" => 157, - 'CMPOP' => 164, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'BINOP' => 161 - }, - DEFAULT => -139 - }, - {#State 242 - ACTIONS => { - "+" => 157, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'BINOP' => 161 - }, - DEFAULT => -138 - }, - {#State 243 - DEFAULT => -137 - }, - {#State 244 - ACTIONS => { - 'DIV' => 159, - 'MOD' => 165 - }, - DEFAULT => -134 - }, - {#State 245 - DEFAULT => -59, - GOTOS => { - '@2-3' => 287 - } - }, - {#State 246 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -150 - }, - {#State 247 - ACTIONS => { - 'ELSIF' => 290, - 'ELSE' => 288 - }, - DEFAULT => -50, - GOTOS => { - 'else' => 289 - } - }, - {#State 248 - DEFAULT => -170 - }, - {#State 249 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - DEFAULT => -162, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 250 - DEFAULT => -167 - }, - {#State 251 - DEFAULT => -165 - }, - {#State 252 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - ")" => 291, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 253 - ACTIONS => { - 'DOT' => 104, - 'ASSIGN' => 292 - }, - DEFAULT => -109 - }, - {#State 254 - ACTIONS => { - "(" => 135, - 'ASSIGN' => 210 - }, - DEFAULT => -128 - }, - {#State 255 - DEFAULT => -153 - }, - {#State 256 - ACTIONS => { - 'ASSIGN' => 213 - }, - DEFAULT => -112 - }, - {#State 257 - DEFAULT => -152 - }, - {#State 258 - DEFAULT => -155 - }, - {#State 259 - DEFAULT => -117 - }, - {#State 260 - ACTIONS => { - ";" => 293 - } - }, - {#State 261 - ACTIONS => { - 'END' => 294 - } - }, - {#State 262 - ACTIONS => { - ";" => 296, - 'DEFAULT' => 297, - 'FILENAME' => 83, - 'IDENT' => 81, - 'NUMBER' => 84 - }, - GOTOS => { - 'filepart' => 87, - 'filename' => 295 - } - }, - {#State 263 - ACTIONS => { - 'END' => 298 - } - }, - {#State 264 - DEFAULT => -102 - }, - {#State 265 - DEFAULT => -100 - }, - {#State 266 - ACTIONS => { - 'TEXT' => 299 - } - }, - {#State 267 - ACTIONS => { - 'END' => 300 - } - }, - {#State 268 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 301, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 269 - ACTIONS => { - 'COMMA' => -96, - 'IDENT' => -96, - ")" => -96 - }, - DEFAULT => -130 - }, - {#State 270 - ACTIONS => { - 'COMMA' => 304, - 'IDENT' => 302, - ")" => 303 - } - }, - {#State 271 - DEFAULT => -156, - GOTOS => { - 'args' => 305 - } - }, - {#State 272 - DEFAULT => -156, - GOTOS => { - 'args' => 306 - } - }, - {#State 273 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 307, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 274 - DEFAULT => -157 - }, - {#State 275 - ACTIONS => { - 'END' => 308 - } - }, - {#State 276 - ACTIONS => { - 'ASSIGN' => -160 - }, - DEFAULT => -167 - }, - {#State 277 - ACTIONS => { - 'END' => 309 - } - }, - {#State 278 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -124 - }, - {#State 279 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -123 - }, - {#State 280 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 310, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 281 - DEFAULT => -129 - }, - {#State 282 - ACTIONS => { - 'END' => 311 - } - }, - {#State 283 - ACTIONS => { - 'ELSIF' => 290, - 'ELSE' => 288 - }, - DEFAULT => -50, - GOTOS => { - 'else' => 312 - } - }, - {#State 284 - ACTIONS => { - 'CASE' => 313 - }, - DEFAULT => -55, - GOTOS => { - 'case' => 314 - } - }, - {#State 285 - ACTIONS => { - 'END' => 315 - } - }, - {#State 286 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 316, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 287 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 317, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 288 - ACTIONS => { - ";" => 318 - } - }, - {#State 289 - ACTIONS => { - 'END' => 319 - } - }, - {#State 290 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 320, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 291 - DEFAULT => -164 - }, - {#State 292 - ACTIONS => { - 'NOT' => 38, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "(" => 53, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'expr' => 321, - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 58, - 'lterm' => 56 - } - }, - {#State 293 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 322, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 294 - DEFAULT => -67 - }, - {#State 295 - ACTIONS => { - 'DOT' => 174, - ";" => 323 - } - }, - {#State 296 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 324, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 297 - ACTIONS => { - ";" => 325 - } - }, - {#State 298 - DEFAULT => -79 - }, - {#State 299 - ACTIONS => { - "\"" => 326 - } - }, - {#State 300 - DEFAULT => -82 - }, - {#State 301 - ACTIONS => { - 'END' => 327 - } - }, - {#State 302 - DEFAULT => -94 - }, - {#State 303 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'WRAPPER' => 55, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - "\"" => 60, - 'PROCESS' => 61, - 'FILTER' => 25, - 'RETURN' => 64, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 193, - 'DEFAULT' => 69, - "{" => 30, - "\${" => 37 - }, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'term' => 58, - 'loop' => 4, - 'expr' => 199, - 'wrapper' => 46, - 'atomexpr' => 48, - 'atomdir' => 12, - 'mdir' => 328, - 'sterm' => 68, - 'filter' => 29, - 'ident' => 149, - 'perl' => 31, - 'setlist' => 70, - 'switch' => 34, - 'try' => 35, - 'assign' => 19, - 'directive' => 196, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 304 - DEFAULT => -95 - }, - {#State 305 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - DEFAULT => -62, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 306 - ACTIONS => { - "{" => 30, - 'COMMA' => 258, - 'LITERAL' => 256, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - DEFAULT => -63, - GOTOS => { - 'sterm' => 68, - 'item' => 254, - 'param' => 255, - 'node' => 23, - 'ident' => 253, - 'term' => 257, - 'lterm' => 56 - } - }, - {#State 307 - ACTIONS => { - 'END' => 329 - } - }, - {#State 308 - DEFAULT => -80 - }, - {#State 309 - DEFAULT => -88 - }, - {#State 310 - ACTIONS => { - 'END' => 330 - } - }, - {#State 311 - DEFAULT => -77 - }, - {#State 312 - ACTIONS => { - 'END' => 331 - } - }, - {#State 313 - ACTIONS => { - ";" => 332, - 'DEFAULT' => 334, - "{" => 30, - 'LITERAL' => 78, - 'IDENT' => 2, - "\"" => 60, - "\$" => 43, - "[" => 9, - 'NUMBER' => 26, - 'REF' => 27, - "\${" => 37 - }, - GOTOS => { - 'sterm' => 68, - 'item' => 39, - 'node' => 23, - 'ident' => 77, - 'term' => 333, - 'lterm' => 56 - } - }, - {#State 314 - ACTIONS => { - 'END' => 335 - } - }, - {#State 315 - DEFAULT => -65 - }, - {#State 316 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -143 - }, - {#State 317 - ACTIONS => { - 'END' => 336 - } - }, - {#State 318 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 337, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 319 - DEFAULT => -46 - }, - {#State 320 - ACTIONS => { - 'CMPOP' => 164, - "?" => 158, - ";" => 338, - "+" => 157, - 'MOD' => 165, - 'DIV' => 159, - "/" => 166, - 'AND' => 160, - 'CAT' => 163, - 'BINOP' => 161, - 'OR' => 162 - } - }, - {#State 321 - ACTIONS => { - "+" => 157, - 'CAT' => 163, - 'CMPOP' => 164, - "?" => 158, - 'DIV' => 159, - 'MOD' => 165, - "/" => 166, - 'AND' => 160, - 'BINOP' => 161, - 'OR' => 162 - }, - DEFAULT => -154 - }, - {#State 322 - DEFAULT => -71 - }, - {#State 323 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 339, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 324 - ACTIONS => { - 'FINAL' => 260, - 'CATCH' => 262 - }, - DEFAULT => -72, - GOTOS => { - 'final' => 340 - } - }, - {#State 325 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 341, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 326 - DEFAULT => -101 - }, - {#State 327 - DEFAULT => -93 - }, - {#State 328 - DEFAULT => -90 - }, - {#State 329 - DEFAULT => -57 - }, - {#State 330 - DEFAULT => -75 - }, - {#State 331 - DEFAULT => -44 - }, - {#State 332 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 342, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 333 - ACTIONS => { - ";" => 343 - } - }, - {#State 334 - ACTIONS => { - ";" => 344 - } - }, - {#State 335 - DEFAULT => -51 - }, - {#State 336 - DEFAULT => -60 - }, - {#State 337 - DEFAULT => -49 - }, - {#State 338 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 345, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 339 - ACTIONS => { - 'FINAL' => 260, - 'CATCH' => 262 - }, - DEFAULT => -72, - GOTOS => { - 'final' => 346 - } - }, - {#State 340 - DEFAULT => -70 - }, - {#State 341 - ACTIONS => { - 'FINAL' => 260, - 'CATCH' => 262 - }, - DEFAULT => -72, - GOTOS => { - 'final' => 347 - } - }, - {#State 342 - DEFAULT => -54 - }, - {#State 343 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 348, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 344 - ACTIONS => { - 'SET' => 1, - 'PERL' => 40, - 'NOT' => 38, - 'IDENT' => 2, - 'CLEAR' => 41, - 'UNLESS' => 3, - 'IF' => 44, - "\$" => 43, - 'STOP' => 6, - 'CALL' => 45, - 'THROW' => 8, - 'GET' => 47, - "[" => 9, - 'TRY' => 10, - 'LAST' => 49, - 'DEBUG' => 51, - 'RAWPERL' => 13, - 'META' => 15, - 'INCLUDE' => 17, - "(" => 53, - 'SWITCH' => 54, - 'MACRO' => 18, - 'WRAPPER' => 55, - ";" => -18, - 'FOR' => 21, - 'NEXT' => 22, - 'LITERAL' => 57, - 'TEXT' => 24, - "\"" => 60, - 'PROCESS' => 61, - 'RETURN' => 64, - 'FILTER' => 25, - 'INSERT' => 65, - 'NUMBER' => 26, - 'REF' => 27, - 'WHILE' => 67, - 'BLOCK' => 28, - 'DEFAULT' => 69, - "{" => 30, - 'USE' => 32, - 'VIEW' => 36, - "\${" => 37 - }, - DEFAULT => -3, - GOTOS => { - 'item' => 39, - 'node' => 23, - 'rawperl' => 59, - 'term' => 58, - 'loop' => 4, - 'use' => 63, - 'expr' => 62, - 'capture' => 42, - 'statement' => 5, - 'view' => 7, - 'wrapper' => 46, - 'atomexpr' => 48, - 'chunk' => 11, - 'defblock' => 66, - 'atomdir' => 12, - 'anonblock' => 50, - 'sterm' => 68, - 'defblockname' => 14, - 'filter' => 29, - 'ident' => 16, - 'perl' => 31, - 'setlist' => 70, - 'chunks' => 33, - 'try' => 35, - 'switch' => 34, - 'assign' => 19, - 'block' => 349, - 'directive' => 71, - 'macro' => 20, - 'condition' => 73, - 'lterm' => 56 - } - }, - {#State 345 - ACTIONS => { - 'ELSIF' => 290, - 'ELSE' => 288 - }, - DEFAULT => -50, - GOTOS => { - 'else' => 350 - } - }, - {#State 346 - DEFAULT => -68 - }, - {#State 347 - DEFAULT => -69 - }, - {#State 348 - ACTIONS => { - 'CASE' => 313 - }, - DEFAULT => -55, - GOTOS => { - 'case' => 351 - } - }, - {#State 349 - DEFAULT => -53 - }, - {#State 350 - DEFAULT => -48 - }, - {#State 351 - DEFAULT => -52 - } -]; - - -#======================================================================== -# Rules -#======================================================================== - -$RULES = [ - [#Rule 0 - '$start', 2, undef - ], - [#Rule 1 - 'template', 1, -sub -#line 64 "Parser.yp" -{ $factory->template($_[1]) } - ], - [#Rule 2 - 'block', 1, -sub -#line 67 "Parser.yp" -{ $factory->block($_[1]) } - ], - [#Rule 3 - 'block', 0, -sub -#line 68 "Parser.yp" -{ $factory->block() } - ], - [#Rule 4 - 'chunks', 2, -sub -#line 71 "Parser.yp" -{ push(@{$_[1]}, $_[2]) - if defined $_[2]; $_[1] } - ], - [#Rule 5 - 'chunks', 1, -sub -#line 73 "Parser.yp" -{ defined $_[1] ? [ $_[1] ] : [ ] } - ], - [#Rule 6 - 'chunk', 1, -sub -#line 76 "Parser.yp" -{ $factory->textblock($_[1]) } - ], - [#Rule 7 - 'chunk', 2, -sub -#line 77 "Parser.yp" -{ return '' unless $_[1]; - $_[0]->location() . $_[1]; - } - ], - [#Rule 8 - 'statement', 1, undef - ], - [#Rule 9 - 'statement', 1, undef - ], - [#Rule 10 - 'statement', 1, undef - ], - [#Rule 11 - 'statement', 1, undef - ], - [#Rule 12 - 'statement', 1, undef - ], - [#Rule 13 - 'statement', 1, undef - ], - [#Rule 14 - 'statement', 1, undef - ], - [#Rule 15 - 'statement', 1, undef - ], - [#Rule 16 - 'statement', 1, -sub -#line 90 "Parser.yp" -{ $factory->get($_[1]) } - ], - [#Rule 17 - 'statement', 2, -sub -#line 91 "Parser.yp" -{ $_[0]->add_metadata($_[2]); } - ], - [#Rule 18 - 'statement', 0, undef - ], - [#Rule 19 - 'directive', 1, -sub -#line 95 "Parser.yp" -{ $factory->set($_[1]) } - ], - [#Rule 20 - 'directive', 1, undef - ], - [#Rule 21 - 'directive', 1, undef - ], - [#Rule 22 - 'directive', 1, undef - ], - [#Rule 23 - 'directive', 1, undef - ], - [#Rule 24 - 'directive', 1, undef - ], - [#Rule 25 - 'directive', 1, undef - ], - [#Rule 26 - 'atomexpr', 1, -sub -#line 109 "Parser.yp" -{ $factory->get($_[1]) } - ], - [#Rule 27 - 'atomexpr', 1, undef - ], - [#Rule 28 - 'atomdir', 2, -sub -#line 113 "Parser.yp" -{ $factory->get($_[2]) } - ], - [#Rule 29 - 'atomdir', 2, -sub -#line 114 "Parser.yp" -{ $factory->call($_[2]) } - ], - [#Rule 30 - 'atomdir', 2, -sub -#line 115 "Parser.yp" -{ $factory->set($_[2]) } - ], - [#Rule 31 - 'atomdir', 2, -sub -#line 116 "Parser.yp" -{ $factory->default($_[2]) } - ], - [#Rule 32 - 'atomdir', 2, -sub -#line 117 "Parser.yp" -{ $factory->insert($_[2]) } - ], - [#Rule 33 - 'atomdir', 2, -sub -#line 118 "Parser.yp" -{ $factory->include($_[2]) } - ], - [#Rule 34 - 'atomdir', 2, -sub -#line 119 "Parser.yp" -{ $factory->process($_[2]) } - ], - [#Rule 35 - 'atomdir', 2, -sub -#line 120 "Parser.yp" -{ $factory->throw($_[2]) } - ], - [#Rule 36 - 'atomdir', 1, -sub -#line 121 "Parser.yp" -{ $factory->return() } - ], - [#Rule 37 - 'atomdir', 1, -sub -#line 122 "Parser.yp" -{ $factory->stop() } - ], - [#Rule 38 - 'atomdir', 1, -sub -#line 123 "Parser.yp" -{ "\$output = '';"; } - ], - [#Rule 39 - 'atomdir', 1, -sub -#line 124 "Parser.yp" -{ $_[0]->{ INFOR } || $_[0]->{ INWHILE } - ? 'last LOOP;' - : 'last;' } - ], - [#Rule 40 - 'atomdir', 1, -sub -#line 127 "Parser.yp" -{ $_[0]->{ INFOR } - ? $factory->next() - : ($_[0]->{ INWHILE } - ? 'next LOOP;' - : 'next;') } - ], - [#Rule 41 - 'atomdir', 2, -sub -#line 132 "Parser.yp" -{ if ($_[2]->[0]->[0] =~ /^'(on|off)'$/) { - $_[0]->{ DEBUG_DIRS } = ($1 eq 'on'); - $factory->debug($_[2]); - } - else { - $_[0]->{ DEBUG_DIRS } ? $factory->debug($_[2]) : ''; - } - } - ], - [#Rule 42 - 'atomdir', 1, undef - ], - [#Rule 43 - 'atomdir', 1, undef - ], - [#Rule 44 - 'condition', 6, -sub -#line 145 "Parser.yp" -{ $factory->if(@_[2, 4, 5]) } - ], - [#Rule 45 - 'condition', 3, -sub -#line 146 "Parser.yp" -{ $factory->if(@_[3, 1]) } - ], - [#Rule 46 - 'condition', 6, -sub -#line 148 "Parser.yp" -{ $factory->if("!($_[2])", @_[4, 5]) } - ], - [#Rule 47 - 'condition', 3, -sub -#line 149 "Parser.yp" -{ $factory->if("!($_[3])", $_[1]) } - ], - [#Rule 48 - 'else', 5, -sub -#line 153 "Parser.yp" -{ unshift(@{$_[5]}, [ @_[2, 4] ]); - $_[5]; } - ], - [#Rule 49 - 'else', 3, -sub -#line 155 "Parser.yp" -{ [ $_[3] ] } - ], - [#Rule 50 - 'else', 0, -sub -#line 156 "Parser.yp" -{ [ undef ] } - ], - [#Rule 51 - 'switch', 6, -sub -#line 160 "Parser.yp" -{ $factory->switch(@_[2, 5]) } - ], - [#Rule 52 - 'case', 5, -sub -#line 164 "Parser.yp" -{ unshift(@{$_[5]}, [ @_[2, 4] ]); - $_[5]; } - ], - [#Rule 53 - 'case', 4, -sub -#line 166 "Parser.yp" -{ [ $_[4] ] } - ], - [#Rule 54 - 'case', 3, -sub -#line 167 "Parser.yp" -{ [ $_[3] ] } - ], - [#Rule 55 - 'case', 0, -sub -#line 168 "Parser.yp" -{ [ undef ] } - ], - [#Rule 56 - '@1-3', 0, -sub -#line 171 "Parser.yp" -{ $_[0]->{ INFOR }++ } - ], - [#Rule 57 - 'loop', 6, -sub -#line 172 "Parser.yp" -{ $_[0]->{ INFOR }--; - $factory->foreach(@{$_[2]}, $_[5]) } - ], - [#Rule 58 - 'loop', 3, -sub -#line 176 "Parser.yp" -{ $factory->foreach(@{$_[3]}, $_[1]) } - ], - [#Rule 59 - '@2-3', 0, -sub -#line 177 "Parser.yp" -{ $_[0]->{ INWHILE }++ } - ], - [#Rule 60 - 'loop', 6, -sub -#line 178 "Parser.yp" -{ $_[0]->{ INWHILE }--; - $factory->while(@_[2, 5]) } - ], - [#Rule 61 - 'loop', 3, -sub -#line 180 "Parser.yp" -{ $factory->while(@_[3, 1]) } - ], - [#Rule 62 - 'loopvar', 4, -sub -#line 183 "Parser.yp" -{ [ @_[1, 3, 4] ] } - ], - [#Rule 63 - 'loopvar', 4, -sub -#line 184 "Parser.yp" -{ [ @_[1, 3, 4] ] } - ], - [#Rule 64 - 'loopvar', 2, -sub -#line 185 "Parser.yp" -{ [ 0, @_[1, 2] ] } - ], - [#Rule 65 - 'wrapper', 5, -sub -#line 189 "Parser.yp" -{ $factory->wrapper(@_[2, 4]) } - ], - [#Rule 66 - 'wrapper', 3, -sub -#line 191 "Parser.yp" -{ $factory->wrapper(@_[3, 1]) } - ], - [#Rule 67 - 'try', 5, -sub -#line 195 "Parser.yp" -{ $factory->try(@_[3, 4]) } - ], - [#Rule 68 - 'final', 5, -sub -#line 199 "Parser.yp" -{ unshift(@{$_[5]}, [ @_[2,4] ]); - $_[5]; } - ], - [#Rule 69 - 'final', 5, -sub -#line 202 "Parser.yp" -{ unshift(@{$_[5]}, [ undef, $_[4] ]); - $_[5]; } - ], - [#Rule 70 - 'final', 4, -sub -#line 205 "Parser.yp" -{ unshift(@{$_[4]}, [ undef, $_[3] ]); - $_[4]; } - ], - [#Rule 71 - 'final', 3, -sub -#line 207 "Parser.yp" -{ [ $_[3] ] } - ], - [#Rule 72 - 'final', 0, -sub -#line 208 "Parser.yp" -{ [ 0 ] } - ], - [#Rule 73 - 'use', 2, -sub -#line 211 "Parser.yp" -{ $factory->use($_[2]) } - ], - [#Rule 74 - '@3-3', 0, -sub -#line 214 "Parser.yp" -{ $_[0]->push_defblock(); } - ], - [#Rule 75 - 'view', 6, -sub -#line 215 "Parser.yp" -{ $factory->view(@_[2,5], - $_[0]->pop_defblock) } - ], - [#Rule 76 - '@4-2', 0, -sub -#line 219 "Parser.yp" -{ ${$_[0]->{ INPERL }}++; } - ], - [#Rule 77 - 'perl', 5, -sub -#line 220 "Parser.yp" -{ ${$_[0]->{ INPERL }}--; - $_[0]->{ EVAL_PERL } - ? $factory->perl($_[4]) - : $factory->no_perl(); } - ], - [#Rule 78 - '@5-1', 0, -sub -#line 226 "Parser.yp" -{ ${$_[0]->{ INPERL }}++; - $rawstart = ${$_[0]->{'LINE'}}; } - ], - [#Rule 79 - 'rawperl', 5, -sub -#line 228 "Parser.yp" -{ ${$_[0]->{ INPERL }}--; - $_[0]->{ EVAL_PERL } - ? $factory->rawperl($_[4], $rawstart) - : $factory->no_perl(); } - ], - [#Rule 80 - 'filter', 5, -sub -#line 235 "Parser.yp" -{ $factory->filter(@_[2,4]) } - ], - [#Rule 81 - 'filter', 3, -sub -#line 237 "Parser.yp" -{ $factory->filter(@_[3,1]) } - ], - [#Rule 82 - 'defblock', 5, -sub -#line 242 "Parser.yp" -{ my $name = join('/', @{ $_[0]->{ DEFBLOCKS } }); - pop(@{ $_[0]->{ DEFBLOCKS } }); - $_[0]->define_block($name, $_[4]); - undef - } - ], - [#Rule 83 - 'defblockname', 2, -sub -#line 249 "Parser.yp" -{ push(@{ $_[0]->{ DEFBLOCKS } }, $_[2]); - $_[2]; - } - ], - [#Rule 84 - 'blockname', 1, undef - ], - [#Rule 85 - 'blockname', 1, -sub -#line 255 "Parser.yp" -{ $_[1] =~ s/^'(.*)'$/$1/; $_[1] } - ], - [#Rule 86 - 'blockargs', 1, undef - ], - [#Rule 87 - 'blockargs', 0, undef - ], - [#Rule 88 - 'anonblock', 5, -sub -#line 263 "Parser.yp" -{ local $" = ', '; - print STDERR "experimental block args: [@{ $_[2] }]\n" - if $_[2]; - $factory->anon_block($_[4]) } - ], - [#Rule 89 - 'capture', 3, -sub -#line 269 "Parser.yp" -{ $factory->capture(@_[1, 3]) } - ], - [#Rule 90 - 'macro', 6, -sub -#line 273 "Parser.yp" -{ $factory->macro(@_[2, 6, 4]) } - ], - [#Rule 91 - 'macro', 3, -sub -#line 274 "Parser.yp" -{ $factory->macro(@_[2, 3]) } - ], - [#Rule 92 - 'mdir', 1, undef - ], - [#Rule 93 - 'mdir', 4, -sub -#line 278 "Parser.yp" -{ $_[3] } - ], - [#Rule 94 - 'margs', 2, -sub -#line 281 "Parser.yp" -{ push(@{$_[1]}, $_[2]); $_[1] } - ], - [#Rule 95 - 'margs', 2, -sub -#line 282 "Parser.yp" -{ $_[1] } - ], - [#Rule 96 - 'margs', 1, -sub -#line 283 "Parser.yp" -{ [ $_[1] ] } - ], - [#Rule 97 - 'metadata', 2, -sub -#line 286 "Parser.yp" -{ push(@{$_[1]}, @{$_[2]}); $_[1] } - ], - [#Rule 98 - 'metadata', 2, undef - ], - [#Rule 99 - 'metadata', 1, undef - ], - [#Rule 100 - 'meta', 3, -sub -#line 291 "Parser.yp" -{ for ($_[3]) { s/^'//; s/'$//; - s/\\'/'/g }; - [ @_[1,3] ] } - ], - [#Rule 101 - 'meta', 5, -sub -#line 294 "Parser.yp" -{ [ @_[1,4] ] } - ], - [#Rule 102 - 'meta', 3, -sub -#line 295 "Parser.yp" -{ [ @_[1,3] ] } - ], - [#Rule 103 - 'term', 1, undef - ], - [#Rule 104 - 'term', 1, undef - ], - [#Rule 105 - 'lterm', 3, -sub -#line 307 "Parser.yp" -{ "[ $_[2] ]" } - ], - [#Rule 106 - 'lterm', 3, -sub -#line 308 "Parser.yp" -{ "[ $_[2] ]" } - ], - [#Rule 107 - 'lterm', 2, -sub -#line 309 "Parser.yp" -{ "[ ]" } - ], - [#Rule 108 - 'lterm', 3, -sub -#line 310 "Parser.yp" -{ "{ $_[2] }" } - ], - [#Rule 109 - 'sterm', 1, -sub -#line 313 "Parser.yp" -{ $factory->ident($_[1]) } - ], - [#Rule 110 - 'sterm', 2, -sub -#line 314 "Parser.yp" -{ $factory->identref($_[2]) } - ], - [#Rule 111 - 'sterm', 3, -sub -#line 315 "Parser.yp" -{ $factory->quoted($_[2]) } - ], - [#Rule 112 - 'sterm', 1, undef - ], - [#Rule 113 - 'sterm', 1, undef - ], - [#Rule 114 - 'list', 2, -sub -#line 320 "Parser.yp" -{ "$_[1], $_[2]" } - ], - [#Rule 115 - 'list', 2, undef - ], - [#Rule 116 - 'list', 1, undef - ], - [#Rule 117 - 'range', 3, -sub -#line 325 "Parser.yp" -{ $_[1] . '..' . $_[3] } - ], - [#Rule 118 - 'hash', 1, undef - ], - [#Rule 119 - 'hash', 0, -sub -#line 330 "Parser.yp" -{ "" } - ], - [#Rule 120 - 'params', 2, -sub -#line 333 "Parser.yp" -{ "$_[1], $_[2]" } - ], - [#Rule 121 - 'params', 2, undef - ], - [#Rule 122 - 'params', 1, undef - ], - [#Rule 123 - 'param', 3, -sub -#line 338 "Parser.yp" -{ "$_[1] => $_[3]" } - ], - [#Rule 124 - 'param', 3, -sub -#line 339 "Parser.yp" -{ "$_[1] => $_[3]" } - ], - [#Rule 125 - 'ident', 3, -sub -#line 342 "Parser.yp" -{ push(@{$_[1]}, @{$_[3]}); $_[1] } - ], - [#Rule 126 - 'ident', 3, -sub -#line 343 "Parser.yp" -{ push(@{$_[1]}, - map {($_, 0)} split(/\./, $_[3])); - $_[1]; } - ], - [#Rule 127 - 'ident', 1, undef - ], - [#Rule 128 - 'node', 1, -sub -#line 349 "Parser.yp" -{ [ $_[1], 0 ] } - ], - [#Rule 129 - 'node', 4, -sub -#line 350 "Parser.yp" -{ [ $_[1], $factory->args($_[3]) ] } - ], - [#Rule 130 - 'item', 1, -sub -#line 353 "Parser.yp" -{ "'$_[1]'" } - ], - [#Rule 131 - 'item', 3, -sub -#line 354 "Parser.yp" -{ $_[2] } - ], - [#Rule 132 - 'item', 2, -sub -#line 355 "Parser.yp" -{ $_[0]->{ V1DOLLAR } - ? "'$_[2]'" - : $factory->ident(["'$_[2]'", 0]) } - ], - [#Rule 133 - 'expr', 3, -sub -#line 360 "Parser.yp" -{ "$_[1] $_[2] $_[3]" } - ], - [#Rule 134 - 'expr', 3, -sub -#line 361 "Parser.yp" -{ "$_[1] $_[2] $_[3]" } - ], - [#Rule 135 - 'expr', 3, -sub -#line 362 "Parser.yp" -{ "$_[1] $_[2] $_[3]" } - ], - [#Rule 136 - 'expr', 3, -sub -#line 363 "Parser.yp" -{ "int($_[1] / $_[3])" } - ], - [#Rule 137 - 'expr', 3, -sub -#line 364 "Parser.yp" -{ "$_[1] % $_[3]" } - ], - [#Rule 138 - 'expr', 3, -sub -#line 365 "Parser.yp" -{ "$_[1] $CMPOP{ $_[2] } $_[3]" } - ], - [#Rule 139 - 'expr', 3, -sub -#line 366 "Parser.yp" -{ "$_[1] . $_[3]" } - ], - [#Rule 140 - 'expr', 3, -sub -#line 367 "Parser.yp" -{ "$_[1] && $_[3]" } - ], - [#Rule 141 - 'expr', 3, -sub -#line 368 "Parser.yp" -{ "$_[1] || $_[3]" } - ], - [#Rule 142 - 'expr', 2, -sub -#line 369 "Parser.yp" -{ "! $_[2]" } - ], - [#Rule 143 - 'expr', 5, -sub -#line 370 "Parser.yp" -{ "$_[1] ? $_[3] : $_[5]" } - ], - [#Rule 144 - 'expr', 3, -sub -#line 371 "Parser.yp" -{ $factory->assign(@{$_[2]}) } - ], - [#Rule 145 - 'expr', 3, -sub -#line 372 "Parser.yp" -{ "($_[2])" } - ], - [#Rule 146 - 'expr', 1, undef - ], - [#Rule 147 - 'setlist', 2, -sub -#line 376 "Parser.yp" -{ push(@{$_[1]}, @{$_[2]}); $_[1] } - ], - [#Rule 148 - 'setlist', 2, undef - ], - [#Rule 149 - 'setlist', 1, undef - ], - [#Rule 150 - 'assign', 3, -sub -#line 382 "Parser.yp" -{ [ $_[1], $_[3] ] } - ], - [#Rule 151 - 'assign', 3, -sub -#line 383 "Parser.yp" -{ [ @_[1,3] ] } - ], - [#Rule 152 - 'args', 2, -sub -#line 390 "Parser.yp" -{ push(@{$_[1]}, $_[2]); $_[1] } - ], - [#Rule 153 - 'args', 2, -sub -#line 391 "Parser.yp" -{ push(@{$_[1]->[0]}, $_[2]); $_[1] } - ], - [#Rule 154 - 'args', 4, -sub -#line 392 "Parser.yp" -{ push(@{$_[1]->[0]}, "'', " . - $factory->assign(@_[2,4])); $_[1] } - ], - [#Rule 155 - 'args', 2, -sub -#line 394 "Parser.yp" -{ $_[1] } - ], - [#Rule 156 - 'args', 0, -sub -#line 395 "Parser.yp" -{ [ [ ] ] } - ], - [#Rule 157 - 'lnameargs', 3, -sub -#line 405 "Parser.yp" -{ push(@{$_[3]}, $_[1]); $_[3] } - ], - [#Rule 158 - 'lnameargs', 1, undef - ], - [#Rule 159 - 'lvalue', 1, undef - ], - [#Rule 160 - 'lvalue', 3, -sub -#line 410 "Parser.yp" -{ $factory->quoted($_[2]) } - ], - [#Rule 161 - 'lvalue', 1, undef - ], - [#Rule 162 - 'nameargs', 3, -sub -#line 414 "Parser.yp" -{ [ [$factory->ident($_[2])], $_[3] ] } - ], - [#Rule 163 - 'nameargs', 2, -sub -#line 415 "Parser.yp" -{ [ @_[1,2] ] } - ], - [#Rule 164 - 'nameargs', 4, -sub -#line 416 "Parser.yp" -{ [ @_[1,3] ] } - ], - [#Rule 165 - 'names', 3, -sub -#line 419 "Parser.yp" -{ push(@{$_[1]}, $_[3]); $_[1] } - ], - [#Rule 166 - 'names', 1, -sub -#line 420 "Parser.yp" -{ [ $_[1] ] } - ], - [#Rule 167 - 'name', 3, -sub -#line 423 "Parser.yp" -{ $factory->quoted($_[2]) } - ], - [#Rule 168 - 'name', 1, -sub -#line 424 "Parser.yp" -{ "'$_[1]'" } - ], - [#Rule 169 - 'name', 1, undef - ], - [#Rule 170 - 'filename', 3, -sub -#line 436 "Parser.yp" -{ "$_[1].$_[3]" } - ], - [#Rule 171 - 'filename', 1, undef - ], - [#Rule 172 - 'filepart', 1, undef - ], - [#Rule 173 - 'filepart', 1, undef - ], - [#Rule 174 - 'filepart', 1, undef - ], - [#Rule 175 - 'quoted', 2, -sub -#line 450 "Parser.yp" -{ push(@{$_[1]}, $_[2]) - if defined $_[2]; $_[1] } - ], - [#Rule 176 - 'quoted', 0, -sub -#line 452 "Parser.yp" -{ [ ] } - ], - [#Rule 177 - 'quotable', 1, -sub -#line 455 "Parser.yp" -{ $factory->ident($_[1]) } - ], - [#Rule 178 - 'quotable', 1, -sub -#line 456 "Parser.yp" -{ $factory->text($_[1]) } - ], - [#Rule 179 - 'quotable', 1, -sub -#line 457 "Parser.yp" -{ undef } - ] -]; - - - -1; - - - - - - - - - - - - diff --git a/lib/Template/Iterator.pm b/lib/Template/Iterator.pm deleted file mode 100644 index 710ecdc..0000000 --- a/lib/Template/Iterator.pm +++ /dev/null @@ -1,456 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Iterator -# -# DESCRIPTION -# -# Module defining an iterator class which is used by the FOREACH -# directive for iterating through data sets. This may be -# sub-classed to define more specific iterator types. -# -# An iterator is an object which provides a consistent way to -# navigate through data which may have a complex underlying form. -# This implementation uses the get_first() and get_next() methods to -# iterate through a dataset. The get_first() method is called once -# to perform any data initialisation and return the first value, -# then get_next() is called repeatedly to return successive values. -# Both these methods return a pair of values which are the data item -# itself and a status code. The default implementation handles -# iteration through an array (list) of elements which is passed by -# reference to the constructor. An empty list is used if none is -# passed. The module may be sub-classed to provide custom -# implementations which iterate through any kind of data in any -# manner as long as it can conforms to the get_first()/get_next() -# interface. The object also implements the get_all() method for -# returning all remaining elements as a list reference. -# -# For further information on iterators see "Design Patterns", by the -# "Gang of Four" (Erich Gamma, Richard Helm, Ralph Johnson, John -# Vlissides), Addision-Wesley, ISBN 0-201-63361-2. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Iterator.pm,v 2.64 2004/01/13 16:19:15 abw Exp $ -# -#============================================================================ - -package Template::Iterator; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $AUTOLOAD ); # AUTO? -use base qw( Template::Base ); -use Template::Constants; -use Template::Exception; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; - - -#======================================================================== -# ----- CLASS METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# new(\@target, \%options) -# -# Constructor method which creates and returns a reference to a new -# Template::Iterator object. A reference to the target data (array -# or hash) may be passed for the object to iterate through. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $data = shift || [ ]; - my $params = shift || { }; - - if (ref $data eq 'HASH') { - # map a hash into a list of { key => ???, value => ??? } hashes, - # one for each key, sorted by keys - $data = [ map { { key => $_, value => $data->{ $_ } } } - sort keys %$data ]; - } - elsif (UNIVERSAL::can($data, 'as_list')) { - $data = $data->as_list(); - } - elsif (ref $data ne 'ARRAY') { - # coerce any non-list data into an array reference - $data = [ $data ] ; - } - - bless { - _DATA => $data, - _ERROR => '', - }, $class; -} - - -#======================================================================== -# ----- PUBLIC OBJECT METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# get_first() -# -# Initialises the object for iterating through the target data set. The -# first record is returned, if defined, along with the STATUS_OK value. -# If there is no target data, or the data is an empty set, then undef -# is returned with the STATUS_DONE value. -#------------------------------------------------------------------------ - -sub get_first { - my $self = shift; - my $data = $self->{ _DATA }; - - $self->{ _DATASET } = $self->{ _DATA }; - my $size = scalar @$data; - my $index = 0; - - return (undef, Template::Constants::STATUS_DONE) unless $size; - - # initialise various counters, flags, etc. - @$self{ qw( SIZE MAX INDEX COUNT FIRST LAST ) } - = ( $size, $size - 1, $index, 1, 1, $size > 1 ? 0 : 1, undef ); - @$self{ qw( PREV NEXT ) } = ( undef, $self->{ _DATASET }->[ $index + 1 ]); - - return $self->{ _DATASET }->[ $index ]; -} - - - -#------------------------------------------------------------------------ -# get_next() -# -# Called repeatedly to access successive elements in the data set. -# Should only be called after calling get_first() or a warning will -# be raised and (undef, STATUS_DONE) returned. -#------------------------------------------------------------------------ - -sub get_next { - my $self = shift; - my ($max, $index) = @$self{ qw( MAX INDEX ) }; - my $data = $self->{ _DATASET }; - - # warn about incorrect usage - unless (defined $index) { - my ($pack, $file, $line) = caller(); - warn("iterator get_next() called before get_first() at $file line $line\n"); - return (undef, Template::Constants::STATUS_DONE); ## RETURN ## - } - - # if there's still some data to go... - if ($index < $max) { - # update counters and flags - $index++; - @$self{ qw( INDEX COUNT FIRST LAST ) } - = ( $index, $index + 1, 0, $index == $max ? 1 : 0 ); - @$self{ qw( PREV NEXT ) } = @$data[ $index - 1, $index + 1 ]; - return $data->[ $index ]; ## RETURN ## - } - else { - return (undef, Template::Constants::STATUS_DONE); ## RETURN ## - } -} - - -#------------------------------------------------------------------------ -# get_all() -# -# Method which returns all remaining items in the iterator as a Perl list -# reference. May be called at any time in the life-cycle of the iterator. -# The get_first() method will be called automatically if necessary, and -# then subsequent get_next() calls are made, storing each returned -# result until the list is exhausted. -#------------------------------------------------------------------------ - -sub get_all { - my $self = shift; - my ($max, $index) = @$self{ qw( MAX INDEX ) }; - my @data; - - # if there's still some data to go... - if ($index < $max) { - $index++; - @data = @{ $self->{ _DATASET } } [ $index..$max ]; - - # update counters and flags - @$self{ qw( INDEX COUNT FIRST LAST ) } - = ( $max, $max + 1, 0, 1 ); - - return \@data; ## RETURN ## - } - else { - return (undef, Template::Constants::STATUS_DONE); ## RETURN ## - } -} - - -#------------------------------------------------------------------------ -# AUTOLOAD -# -# Provides access to internal fields (e.g. size, first, last, max, etc) -#------------------------------------------------------------------------ - -sub AUTOLOAD { - my $self = shift; - my $item = $AUTOLOAD; - $item =~ s/.*:://; - return if $item eq 'DESTROY'; - - # alias NUMBER to COUNT for backwards compatability - $item = 'COUNT' if $item =~ /NUMBER/i; - - return $self->{ uc $item }; -} - - -#======================================================================== -# ----- PRIVATE DEBUG METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which returns a string detailing the internal state of -# the iterator object. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - join('', - " Data: ", $self->{ _DATA }, "\n", - " Index: ", $self->{ INDEX }, "\n", - "Number: ", $self->{ NUMBER }, "\n", - " Max: ", $self->{ MAX }, "\n", - " Size: ", $self->{ SIZE }, "\n", - " First: ", $self->{ FIRST }, "\n", - " Last: ", $self->{ LAST }, "\n", - "\n" - ); -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Iterator - Data iterator used by the FOREACH directive - -=head1 SYNOPSIS - - my $iter = Template::Iterator->new(\@data, \%options); - -=head1 DESCRIPTION - -The Template::Iterator module defines a generic data iterator for use -by the FOREACH directive. - -It may be used as the base class for custom iterators. - -=head1 PUBLIC METHODS - -=head2 new($data) - -Constructor method. A reference to a list of values is passed as the -first parameter. Subsequent calls to get_first() and get_next() calls -will return each element from the list. - - my $iter = Template::Iterator->new([ 'foo', 'bar', 'baz' ]); - -The constructor will also accept a reference to a hash array and will -expand it into a list in which each entry is a hash array containing -a 'key' and 'value' item, sorted according to the hash keys. - - my $iter = Template::Iterator->new({ - foo => 'Foo Item', - bar => 'Bar Item', - }); - -This is equivalent to: - - my $iter = Template::Iterator->new([ - { key => 'bar', value => 'Bar Item' }, - { key => 'foo', value => 'Foo Item' }, - ]); - -When passed a single item which is not an array reference, the constructor -will automatically create a list containing that single item. - - my $iter = Template::Iterator->new('foo'); - -This is equivalent to: - - my $iter = Template::Iterator->new([ 'foo' ]); - -Note that a single item which is an object based on a blessed ARRAY -references will NOT be treated as an array and will be folded into -a list containing that one object reference. - - my $list = bless [ 'foo', 'bar' ], 'MyListClass'; - my $iter = Template::Iterator->new($list); - -equivalent to: - - my $iter = Template::Iterator->new([ $list ]); - -If the object provides an as_list() method then the Template::Iterator -constructor will call that method to return the list of data. For example: - - package MyListObject; - - sub new { - my $class = shift; - bless [ @_ ], $class; - } - - package main; - - my $list = MyListObject->new('foo', 'bar'); - my $iter = Template::Iterator->new($list); - -This is then functionally equivalent to: - - my $iter = Template::Iterator->new([ $list ]); - -The iterator will return only one item, a reference to the MyListObject -object, $list. - -By adding an as_list() method to the MyListObject class, we can force -the Template::Iterator constructor to treat the object as a list and -use the data contained within. - - package MyListObject; - - ... - - sub as_list { - my $self = shift; - return $self; - } - - package main; - - my $list = MyListObject->new('foo', 'bar'); - my $iter = Template::Iterator->new($list); - -The iterator will now return the two item, 'foo' and 'bar', which the -MyObjectList encapsulates. - -=head2 get_first() - -Returns a ($value, $error) pair for the first item in the iterator set. -The $error returned may be zero or undefined to indicate a valid datum -was successfully returned. Returns an error of STATUS_DONE if the list -is empty. - -=head2 get_next() - -Returns a ($value, $error) pair for the next item in the iterator set. -Returns an error of STATUS_DONE if all items in the list have been -visited. - -=head2 get_all() - -Returns a (\@values, $error) pair for all remaining items in the iterator -set. Returns an error of STATUS_DONE if all items in the list have been -visited. - -=head2 size() - -Returns the size of the data set or undef if unknown. - -=head2 max() - -Returns the maximum index number (i.e. the index of the last element) -which is equivalent to size() - 1. - -=head2 index() - -Returns the current index number which is in the range 0 to max(). - -=head2 count() - -Returns the current iteration count in the range 1 to size(). This is -equivalent to index() + 1. Note that number() is supported as an alias -for count() for backwards compatability. - -=head2 first() - -Returns a boolean value to indicate if the iterator is currently on -the first iteration of the set. - -=head2 last() - -Returns a boolean value to indicate if the iterator is currently on -the last iteration of the set. - -=head2 prev() - -Returns the previous item in the data set, or undef if the iterator is -on the first item. - -=head2 next() - -Returns the next item in the data set or undef if the iterator is on the -last item. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Library/HTML.pod b/lib/Template/Library/HTML.pod deleted file mode 100644 index e39c120..0000000 --- a/lib/Template/Library/HTML.pod +++ /dev/null @@ -1,316 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Library::HTML -# -# DESCRIPTION -# The HTML library provides a number of basic templates for use in -# building HTML pages. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# 2.69 -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Library::HTML - Template library for building basic HTML pages - -=head1 DESCRIPTION - -B<NOTE:> This documentation is incomplete and may be incorrect -in places. - -The 'html' template library is distributed as part of the Template -Toolkit. It can be found in the 'templates' sub-directory of the -installation directory. - - use Template; - - my $tt2 = Template->new({ - INCLUDE_PATH => '/usr/local/tt2/templates', - }); - -For a portable way to determine the installation 'templates' directory, -you can use the C<Template::Config-E<gt>instdir()> class method. - - use Template; - - my $tt2 = Template->new({ - INCLUDE_PATH => Template::Config->instdir('templates'), - }); - -You should now be able to access the html library as, for example: - - [% INCLUDE html/header %] - -Note that some of the more basic elements don't give you much more -than the raw HTML tags. In many cases you might be well advised to -stick to regular HTML rather than complicating matters by the use -of template elements. - -e.g. - - <table> - . . . - </table> - -vs - - [% WRAPPER html/table %] - . . . - [% END %] - -However, the use of template elements to generate the underlying HTML -does have some important benefits, particularly as the constructs start -to get more complicated and more magical. - -See the example in the 'examples' sub-directory of the distribution -directory for further examples and enlightenment on using this library. - -=head2 Headers, Footers and Pages - -=over 4 - -=item header - -The 'header' element generates the regular header required as the -pre-amble for an HTML document. That is, everything from the initial -E<lt>htmlE<gt> to the opening E<lt>bodyE<gt>. - - [% INCLUDE html/header - title = 'This is a Test' - bgcol = '#ffffff' - %] - -Additional header items can be provided by explicitly setting the 'headers' -variable, e.g. - - [% headers = BLOCK %] - <META name="description" content="Template Toolkit"> - <META name="REVISIT-AFTER" content="14 days"> - <META name="keywords" content="Templates, Web, ...etc..."> - [% END %] - - [% INCLUDE html/header - title = 'This is a Test' - bgcol = '#ffffff' - %] - -=item footer - -The 'footer' element generates the terminating E<lt>/bodyE<gt> and -E<lt>/htmlE<gt> element to balance the header. - - [% PROCESS html/header %] - - ...page content here... - - [% PROCESS html/footer %] - -=item page - -The 'page' element combines the 'html/header' and 'html/footer' elements. - - [% WRAPPER html/page %] - - ...page content here... - - [% END %] - -Page content should be defined in the 'content' variable (e.g. via WRAPPER). -Additional HTML headers should be defined in the 'headers' variable. - - [% WRAPPER html/page - headers = '<META name="keywords" content="foo, bar, ...">' - %] - - ...page content here... - - [% END %] - -=back - -=head2 Tables, Bars and Boxes - -=over 4 - -=item table - -A basic element for creating HTML tables. - - [% WRAPPER html/table pad=10 space=4 col='#404040' %] - <tr> - <td>Hello</td> <td>World</td> - </tr> - [% END %] - -The following variables may be defined: - -=over 4 - -=item border - -Set the border width (default: 0) - -=item col - -Set the background colour (default: none). - -=item width - -Set a fixed table width. - -=item pad - -Set the cellpadding. - -=item space - -Set the cellspacing. - -=item content - -Content for the box. Supplied automatically if used via WRAPPER. - -=back - -=item row - -A basic element for creating HTML table rows. - - [% WRAPPER html/table %] - [% WRAPPER html/row %] - <td>Hello</td> <td>World</td> - [% END %] - [% END %] - -The following variables may be defined: - -=over 4 - -=item col - -Set the background colour (default: none). - -=item valign - -Set the vertical alignment. - -=item rowspan - -Specify the number of rows to span. - -=item content - -Content for the box. Supplied automatically if used via WRAPPER. - -=back - -=item cell - -A basic element for creating HTML table cells. - - [% WRAPPER html/table %] - [% WRAPPER html/row %] - [% INCLUDE html/cell - FOREACH content = ['Hello', 'World'] %] - [% END %] - [% END %] - -The following variables may be defined: - -=over 4 - -=item col - -Set the background colour (default: none). - -=item align - -Set the horizontal alignment. - -=item colspan - -Specify the number of columns to span. - -=item content - -Content for the cell. Supplied automatically if used via WRAPPER. - -=back - -=item bar - -The bar element is a wrapping of html/table + html/row. - - [% WRAPPER html/bar %] - <td>Foo</td> <td>Bar</td> - [% END %] - -=item box - -The box element is a wrapping of html/table + html/row + html/cell - - [% WRAPPER html/box %] - Hello World! - [% END %] - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Library::Splash|Template::Library::Splash> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Library/PostScript.pod b/lib/Template/Library/PostScript.pod deleted file mode 100644 index c30246c..0000000 --- a/lib/Template/Library/PostScript.pod +++ /dev/null @@ -1,78 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Library::PostScript -# -# DESCRIPTION -# This library contains a number of useful templates for generating -# PostScript pages. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# 2.69 -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Library::PostScript - Template library for generating PostScript - -=head1 DESCRIPTION - -The PostScript library contains a number of templates for generating -PostScript pages. It's very new, very incomplete, very ad-hoc and -isn't yet documented. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Library/Splash.pod b/lib/Template/Library/Splash.pod deleted file mode 100644 index e8c4f8b..0000000 --- a/lib/Template/Library/Splash.pod +++ /dev/null @@ -1,1030 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Library::Splash -# -# DESCRIPTION -# The Splash! library is built on top of the HTML library and -# implements a set of widgets for easy construction of stylish HTML -# pages -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# 2.69 -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Library::Splash - Template library for building stylish HTML user interfaces - -=head1 DESCRIPTION - -B<NOTE:> This documentation is incomplete, incorrect and outdated. -The Splash! library is still evolving and subject to change. See -the examples for a much more recent and accurate demonstration of -use. - -=head2 Introduction - -The 'Splash' template library is distributed as part of the Template -Toolkit. It can be found in the 'templates' sub-directory of the -installation directory. - - /your/tt2/installation - | - +-- docs - | ... - | - +-- images - | ... - | - +-- examples - | ... - | - +-- templates - | - +-- html - | ... - +-- pod - | ... - +-- splash <<<< YOU ARE HERE - ... - - -To use the Splash library, you first need to tell the Template Toolkit -where to find the template files. - - use Template; - - my $tt2 = Template->new({ - INCLUDE_PATH => '/usr/local/tt2/templates', - }); - -For a portable way to determine the installation 'templates' directory, -you can use the C<Template::Config-E<gt>instdir()> class method. - - use Template; - - my $tt2 = Template->new({ - INCLUDE_PATH => Template::Config->instdir('templates'), - }); - -Note that you should set the INCLUDE_PATH to the 'templates' directory -as shown here and don't be tempted to set the INCLUDE_PATH to -'templates/splash'. Many of the Splash! components use elements in -the 'html' directory and contain directives of the form: - - [% INCLUDE html/something %]. - -=head2 Configuration - -The 'splash/config' template defines a 'splash' hash array which -contains numerous configuration items for the Splash library. You -must PROCESS this template to ensure that the hash definition is -imported into your calling template. An INCLUDE is not sufficient as -it localises variables and prevents the 'splash' hash array from -existing outside the splash/config template. - - [% PROCESS splash/config %] - -Alternately, you can define the splash/config template as a PRE_PROCESS -item when you create the Template processor. - - use Template; - - my $tt2 = Template->new({ - INCLUDE_PATH => Template::Config->instdir('templates'), - PRE_PROCESS => 'splash/config', - }); - -You can modify the default configuration by creating your own -PRE_PROCESS config file which loads the 'splash/config' and then -tweaks the settings to your own preferences. - - my $tt2 = Template->new({ - INCLUDE_PATH => [ '/home/abw/tt2/templates', - Template::Config->instdir('templates') ], - PRE_PROCESS => 'config' - }); - -/home/abw/tt2/templates/config: - - [% # load the 'splash' configuration - PROCESS splash/config; - - # tweak values to personal preferences - splash.images = '/~abw/tt2/images/splash' - splash.select.col = 'leaf' - splash.unselect.col = 'bud' - %] - -The splash/config file includes some instructional comments on -things you might like to tweak. - -=head2 Colours - -The Splash! library uses the colours defined in the html/rgb template. -The 'rgb' hash defined therein is imported as the 'splash.rgb' hash. - - [% INCLUDE splash/box col='grey75' %] - -See the examples for further enlightenment on using colour. - -=head2 Style - -There are two very primitive "styles" implemented called "select" and -"unselect". These are used to indicate which item on a menu is -selected, for example. Each style defines characteristics like -background colour, font face, size and colour, text alignment, and so -on. - -The styles are implemented as hashes within the 'splash' hash. Many -of the components respond to a 'style' variable being set and you can -pass a direct reference to splash.select or splash.unselect (or your -own styles). e.g. - - [% INCLUDE splash/button - content = "Unselected" - style = splash.unselect - %] - [% INCLUDE splash/button - content ="Selected" - style = splash.select - %] - -Alternately, you can use the 'select' variable to indicate either -of the inbuilt styles: splash.select or splash.unselect. - - [% INCLUDE splash/button - content = "Unselected" - select = 0 - %] - [% INCLUDE splash/button - content = "Selected" - select = 1 - %] - -=head1 COMPONENT TEMPLATES - -This section describes some of the component templates in the Splash! -library. This documentation is incomplete and may also be inaccurate -in places. The examples in the 'examples' directory are likely to be -a much better reference. - - -=head2 splash/text - -Simple template to format text according to a selected/unselected style, -adding links, etc. - - [% INCLUDE splash/text - content = 'Template Toolkit' - link = 'http://www.template-toolkit.org' - select = 0 - bold = 1 - %] - - -Configuration items: - -=over 4 - - -=item content - -Text content. - - -=item link - -URL which can be defined to make the text a link. - - -=item style - -Reference to a style hash. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item font (style.font.face) - - -=item bold (style.font.bold) - - -=item size (style.font.size) - - -=back - - - -=head2 splash/table - -A thin wrapper around html/table, allowing a colour to be specified -by name. - - [% WRAPPER splash/table - col = 'aqua' - pad = 4 - width = '100%' - %] - <tr> - <td>Foo</td> - <td>Bar</td> - </tr> - [% END %] - - -Configuration items: - -=over 4 - - -=item content - -Table content. - - -=item col - -Background colour. - - -=item border - -Border width (default: 0) - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item pad - -Cell padding. - - -=item space - -Cell padding. - - -=back - - - -=head2 splash/row - -Creates a row for an HTML table. - - [% WRAPPER splash/table %] - - [% WRAPPER splash/row col='marine' %] - <td>Foo</td><td>Bar</td> - [% END %] - - [% WRAPPER splash/row col='aqua' %] - <td>Foo</td><td>Bar</td> - [% END %] - - [% END %] - - -Configuration items: - -=over 4 - - -=item content - -Row content. - - -=item col - -Background colour. - - -=item valign - -Vertical alignment - - -=item rowspan - -Number of rows to span. - - -=back - - - -=head2 splash/cell - -Creates a cell for an HTML table. - - [% WRAPPER splash/table + splash/row + splash/cell col='grey75' %] - Hello World - [% END %] - - -Configuration items: - -=over 4 - - -=item content - -Cell content. - - -=item col - -Background colour. - - -=item align - -Horizontal alignment - - -=item colspan - -Number of columns to span. - - -=back - - - -=head2 splash/box - -A box created from a union of splash/table, splash/row and splash/cell. -The following is equivalent to the previous example. - - [% WRAPPER splash/box col='grey75' %] - Hello World - [% END %] - -Configuration items are as per the individual templates. - - -=head2 splash/button - -Creates a small button with rounded corners. - - [% INCLUDE splash/button - content = 'Template Toolkit' - select = 1 - width = '50%' - %] - - -Configuration items: - -=over 4 - - -=item content - -Button content. - - -=item style - -Reference to a style hash. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item textcol (style.col.text) - - -=item font (style.font.face) - - -=item size (style.font.size) - - -=item bold (style.font.bold) - - -=item width (style.button.width) - - -=item align (style.button.align) - - -=back - - - -=head2 splash/bar - -Creates a bar with rounded corners at either the top or bottom, and -square corners on the other. Default has rounded at the top, set -'invert' to select bottom. - - [% INCLUDE splash/bar - content = 'Hello World', - select = 1 - %] - - -Configuration items: - -=over 4 - - -=item content - -Bar content. - - -=item style - -Reference to a style hash. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item invert - -Flag to invert bar to hang down instead of sitting -upright. - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item textcol (style.col.text) - - -=item font (style.font.face) - - -=item size (style.font.size) - - -=item bold (style.font.bold) - - -=item width (style.button.width) - - -=item align (style.button.align) - - -=back - - -=head2 splash/hair - -Generates a frame enclosing the content within crosshair corners. - - [% INCLUDE splash/hair - content = 'Template Toolkit' - %] - - -Configuration items: - -=over 4 - - -=item content - -Hair content. - - -=item style - -Reference to a style hash. - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item bgcol (style.col.back) - - -=item align (style.button.align) - - -=back - - -=head2 splash/menu - -Creates a menu as a series of splash/button elements. - - [% buttons = [ - { text => 'One', link => 'one.html' } - { text => 'Two', link => 'two.html' } - ] - %] - - [% INCLUDE splash/menu - select = 2 # Two - %] - - -Configuration items: - -=over 4 - - -=item buttons - -A reference to a list of hash arrays containing 'text' and 'link' items. - - -=item select (n or 0) - -Indicates which button should be selected. First item is 1. 0 indicates -no button selected. - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item align - -Horizontal alignment - - -=back - - - -=head2 splash/menubar - -As above, but incorporated into a wider bar. - - [% WRAPPER splash/menubar %] - Section Title - [% END %] - - -Configuration items: - -=over 4 - - -=item buttons - -A reference to a list of hash arrays containing 'text' and 'link' items. - - -=item select (n or 0) - -Indicates which button should be selected. First item is 1. 0 indicates -no button selected. - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item align - -Horizontal alignment - - -=back - - - -=head2 splash/panel - -A table with a coloured edge. - - [% WRAPPER splash/panel edge='black' fill='grey75' border=2 %] - <tr> - <td>Hello World</td> - </tr> - [% END %] - - -Configuration items: - -=over 4 - - -=item content - -Panel content. - - -=item style - -Reference to a style hash. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item align - -Horizontal alignment - - -=item border - -Border width (default: 0) - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item edge (style.col.edge) - - -=item fill (style.col.fill) - - -=item pad (style.pad) - - -=back - - - -=head2 splash/pane - -A union of splash/row + splash/cell. - - [% WRAPPER splash/panel select=1 %] - [% WRAPPER splash/pane col='grey75' %] - Hello World - [% END %] - - [% WRAPPER splash/pane col='grey50' %] - Hello Again - [% END %] - [% END %] - - -=head2 splash/tab - -A simple button looking like a page tab. - - [% INCLUDE splash/tab - content = 'Option 1' - col = 'aqua' - %] - - -Configuration items: - -=over 4 - - -=item content - -Tab content. - - -=item style - -Reference to a style hash. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item align - -Horizontal alignment - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item textcol (style.col.text) - - -=item font (style.font.face) - - -=item size (style.font.size) - - -=item bold (style.font.bold) - - -=item tabalign (style.tab.align) - - -=back - - - -=head2 splash/tabset - -A set of splash/tab components, similar to a menu. - - -Configuration items: - -=over 4 - - -=item tabs - -List of hash references containing text/link entries, as per -menu buttons. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item invert - -Flag to invert tab to hang down instead of sitting -upright. - - -=back - - - -=head2 splash/tabbox - -Add a splash/tab to the top of a splash/box. - - -Configuration items: - -=over 4 - - -=item title - - title. - - -=item content - - content. - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item tabwidth - -Width of tabs. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item border - -Border width (default: 0) - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item fill (style.col.fill) - - -=item tabalign (style.tab.align) - - -=item tablocate (style.tab.locate) - - -=back - - - -=head2 splash/tabsbox - -Add a splash/tabset to the top of a splash/box. - - -Configuration items: - -=over 4 - - -=item tabs - -List of hash references containing text/link entries, as per -menu buttons. - - -=item select - -Flag to default the style to splash.select (select == true value) or -splash.unselect (select == false value). - - -=item content - - content. - - -=item width - -Width in absolute pixels (e.g. '100') or as a percentage (e.g. '50%'). - -=item border - -Border width (default: 0) - - -=item invert - -Flag to invert to hang down instead of sitting -upright. - - -=back - -The following items default to the relevant style values: - -=over 4 - - -=item col (style.col.text) - - -=item fill (style.col.fill) - - -=item tabalign (style.tab.align) - - -=item tablocate (style.tab.locate) - - -=back - - -=head2 splash/tabspanel - -As per splash/tabsbox, but attached to a splash/panel instead of a -splash/box. - - -=head1 EXAMPLES - -See the examples in the 'examples' sub-directory of the installation -for comprehensive examples showing use of the Splash! library. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Library::HTML|Template::Library::HTML> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual.pod b/lib/Template/Manual.pod deleted file mode 100644 index 8775a5b..0000000 --- a/lib/Template/Manual.pod +++ /dev/null @@ -1,180 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual -# -# DESCRIPTION -# This is the comprehensive user guide and reference manual for the -# Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual - User guide and reference manual for the Template Toolkit - -=head1 DESCRIPTION - -This is the comprehensive user guide and reference manual for the -Template Toolkit. - -=over 4 - -=item L<Template::Manual::Intro|Template::Manual::Intro> - -Introduction to the Template Toolkit - -This section provides a general introduction to the Template Toolkit, -giving a quick overview of features, examples of template directives -and use of the Template.pm module. It also described the basic concept -underlying the toolkit: the separation of presentation elements from -application logic and data. - -=item L<Template::Manual::Syntax|Template::Manual::Syntax> - -Directive syntax, structure and semantics - -This section describes the syntax, structure and semantics of the -Template Toolkit directives and general presentation language. - -=item L<Template::Manual::Directives|Template::Manual::Directives> - -Template directives - -This section provides a reference of all Template Toolkit directives, -complete with examples of use. - -=item L<Template::Manual::Variables|Template::Manual::Variables> - -Template variables and code bindings - -This section describes the different ways in which Perl data can be -bound to template variables and accessed via Template Toolkit -directives. - -=item L<Template::Manual::VMethods|Template::Manual::VMethods> - -Virtual Methods - -The Template Toolkit provides virtual methods for manipulating variable -values. Most of them are analogous to regular Perl functions of the -same names. This section describes the different virtual methods that -can be applied to scalar, list and hash values. - -=item L<Template::Manual::Config|Template::Manual::Config> - -Configuration options - -This section contains details of all the configuration options that can -be used to customise the behaviour and extend the features of the -Template Toolkit. - -=item L<Template::Manual::Filters|Template::Manual::Filters> - -Standard filters - -This section lists all the standard filters distributed with the -Template Toolkit for post-processing output. - -=item L<Template::Manual::Plugins|Template::Manual::Plugins> - -Standard plugins - -This section lists the standard plugins which can be used to extend the -runtime functionality of the Template Toolkit. The plugins are -distributed with the Template Toolkit but may required additional -modules from CPAN. - -=item L<Template::Manual::Internals|Template::Manual::Internals> - -Template Toolkit internals - -This document provides an overview of the internal architecture of the -Template Toolkit. It is a work in progress and is far from complete, -currently providing little more than an overview of how the major -components fit together. Nevertheless, it's a good starting point for -anyone wishing to delve into the source code to find out how it all -works. - -=item L<Template::Manual::Views|Template::Manual::Views> - -Template Toolkit views (experimental) - -This section describes dynamic views: a powerful but experimental new -feature in version 2.01 of the Template Toolkit. - -=item L<Template::Manual::Refs|Template::Manual::Refs> - -Related modules, projects and other resources - -This section provides references to external modules, projects and -other resources related to the Template Toolkit. - -=item L<Template::Manual::Credits|Template::Manual::Credits> - -Author and contributor credits - -This section provides a brief history of the Template Toolkit and -details the primary author and numerous other people who have -contributed to it. - - - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Config.pod b/lib/Template/Manual/Config.pod deleted file mode 100644 index 5020556..0000000 --- a/lib/Template/Manual/Config.pod +++ /dev/null @@ -1,2122 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Config -# -# DESCRIPTION -# This section contains details of all the configuration options that -# can be used to customise the behaviour and extend the features of -# the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Config - Configuration options - -=head1 DESCRIPTION - -This section contains details of all the configuration options that can -be used to customise the behaviour and extend the features of the -Template Toolkit. - -=head2 Template Style and Parsing Options - -=over 4 - - - -=item START_TAG, END_TAG - -The START_TAG and END_TAG options are used to specify character -sequences or regular expressions that mark the start and end of a -template directive. The default values for START_TAG and END_TAG are -'[%' and '%]' respectively, giving us the familiar directive style: - - [% example %] - -Any Perl regex characters can be used and therefore should be escaped -(or use the Perl C<quotemeta> function) if they are intended to -represent literal characters. - - my $template = Template->new({ - START_TAG => quotemeta('<+'), - END_TAG => quotemeta('+>'), - }); - -example: - - <+ INCLUDE foobar +> - -The TAGS directive can also be used to set the START_TAG and END_TAG values -on a per-template file basis. - - [% TAGS <+ +> %] - - - - - - -=item TAG_STYLE - -The TAG_STYLE option can be used to set both START_TAG and END_TAG -according to pre-defined tag styles. - - my $template = Template->new({ - TAG_STYLE => 'star', - }); - -Available styles are: - - template [% ... %] (default) - template1 [% ... %] or %% ... %% (TT version 1) - metatext %% ... %% (Text::MetaText) - star [* ... *] (TT alternate) - php <? ... ?> (PHP) - asp <% ... %> (ASP) - mason <% ... > (HTML::Mason) - html <!-- ... --> (HTML comments) - -Any values specified for START_TAG and/or END_TAG will over-ride -those defined by a TAG_STYLE. - -The TAGS directive may also be used to set a TAG_STYLE - - [% TAGS html %] - <!-- INCLUDE header --> - - - - - - -=item PRE_CHOMP, POST_CHOMP - -Anything outside a directive tag is considered plain text and is -generally passed through unaltered (but see the INTERPOLATE option). -This includes all whitespace and newlines characters surrounding -directive tags. Directives that don't generate any output will leave -gaps in the output document. - -Example: - - Foo - [% a = 10 %] - Bar - -Output: - - Foo - - Bar - -The PRE_CHOMP and POST_CHOMP options can help to clean up some of this -extraneous whitespace. Both are disabled by default. - - my $template = Template->new({ - PRE_CHOMP => 1, - POST_CHOMP => 1, - }); - -With PRE_CHOMP set to 1, the newline and whitespace preceding a directive -at the start of a line will be deleted. This has the effect of -concatenating a line that starts with a directive onto the end of the -previous line. - - Foo <----------. - | - ,---(PRE_CHOMP)----' - | - `-- [% a = 10 %] --. - | - ,---(POST_CHOMP)---' - | - `-> Bar - -With POST_CHOMP set to 1, any whitespace after a directive up to and -including the newline will be deleted. This has the effect of joining -a line that ends with a directive onto the start of the next line. - -If PRE_CHOMP or POST_CHOMP is set to 2, then instead of removing all -the whitespace, the whitespace will be collapsed to a single space. -This is useful for HTML, where (usually) a contiguous block of -whitespace is rendered the same as a single space. - -You may use the CHOMP_NONE, CHOMP_ALL, and CHOMP_COLLAPSE constants -from the Template::Constants module to deactivate chomping, remove -all whitespace, or collapse whitespace to a single space. - -PRE_CHOMP and POST_CHOMP can be activated for individual directives by -placing a '-' immediately at the start and/or end of the directive. - - [% FOREACH user = userlist %] - [%- user -%] - [% END %] - -The '-' characters activate both PRE_CHOMP and POST_CHOMP for the one -directive '[%- name -%]'. Thus, the template will be processed as if -written: - - [% FOREACH user = userlist %][% user %][% END %] - -Note that this is the same as if PRE_CHOMP and POST_CHOMP were set -to CHOMP_ALL; the only way to get the CHOMP_COLLAPSE behavior is -to set PRE_CHOMP or POST_CHOMP accordingly. If PRE_CHOMP or POST_CHOMP -is already set to CHOMP_COLLAPSE, using '-' will give you CHOMP_COLLAPSE -behavior, not CHOMP_ALL behavior. - -Similarly, '+' characters can be used to disable PRE_CHOMP or -POST_CHOMP (i.e. leave the whitespace/newline intact) options on a -per-directive basis. - - [% FOREACH user = userlist %] - User: [% user +%] - [% END %] - -With POST_CHOMP enabled, the above example would be parsed as if written: - - [% FOREACH user = userlist %]User: [% user %] - [% END %] - - - - - -=item TRIM - -The TRIM option can be set to have any leading and trailing whitespace -automatically removed from the output of all template files and BLOCKs. - -By example, the following BLOCK definition - - [% BLOCK foo %] - Line 1 of foo - [% END %] - -will be processed is as "\nLine 1 of foo\n". When INCLUDEd, the surrounding -newlines will also be introduced. - - before - [% INCLUDE foo %] - after - -output: - before - - Line 1 of foo - - after - -With the TRIM option set to any true value, the leading and trailing -newlines (which count as whitespace) will be removed from the output -of the BLOCK. - - before - Line 1 of foo - after - -The TRIM option is disabled (0) by default. - - - - - -=item INTERPOLATE - -The INTERPOLATE flag, when set to any true value will cause variable -references in plain text (i.e. not surrounded by START_TAG and END_TAG) -to be recognised and interpolated accordingly. - - my $template = Template->new({ - INTERPOLATE => 1, - }); - -Variables should be prefixed by a '$' to identify them. Curly braces -can be used in the familiar Perl/shell style to explicitly scope the -variable name where required. - - # INTERPOLATE => 0 - <a href="http://[% server %]/[% help %]"> - <img src="[% images %]/help.gif"></a> - [% myorg.name %] - - # INTERPOLATE => 1 - <a href="http://$server/$help"> - <img src="$images/help.gif"></a> - $myorg.name - - # explicit scoping with { } - <img src="$images/${icon.next}.gif"> - -Note that a limitation in Perl's regex engine restricts the maximum length -of an interpolated template to around 32 kilobytes or possibly less. Files -that exceed this limit in size will typically cause Perl to dump core with -a segmentation fault. If you routinely process templates of this size -then you should disable INTERPOLATE or split the templates in several -smaller files or blocks which can then be joined backed together via -PROCESS or INCLUDE. - - - - - - - -=item ANYCASE - -By default, directive keywords should be expressed in UPPER CASE. The -ANYCASE option can be set to allow directive keywords to be specified -in any case. - - # ANYCASE => 0 (default) - [% INCLUDE foobar %] # OK - [% include foobar %] # ERROR - [% include = 10 %] # OK, 'include' is a variable - - # ANYCASE => 1 - [% INCLUDE foobar %] # OK - [% include foobar %] # OK - [% include = 10 %] # ERROR, 'include' is reserved word - -One side-effect of enabling ANYCASE is that you cannot use a variable -of the same name as a reserved word, regardless of case. The reserved -words are currently: - - GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER - IF UNLESS ELSE ELSIF FOR FOREACH WHILE SWITCH CASE - USE PLUGIN FILTER MACRO PERL RAWPERL BLOCK META - TRY THROW CATCH FINAL NEXT LAST BREAK RETURN STOP - CLEAR TO STEP AND OR NOT MOD DIV END - - -The only lower case reserved words that cannot be used for variables, -regardless of the ANYCASE option, are the operators: - - and or not mod div - - - - - - -=back - -=head2 Template Files and Blocks - -=over 4 - - - -=item INCLUDE_PATH - -The INCLUDE_PATH is used to specify one or more directories in which -template files are located. When a template is requested that isn't -defined locally as a BLOCK, each of the INCLUDE_PATH directories is -searched in turn to locate the template file. Multiple directories -can be specified as a reference to a list or as a single string where -each directory is delimited by ':'. - - my $template = Template->new({ - INCLUDE_PATH => '/usr/local/templates', - }); - - my $template = Template->new({ - INCLUDE_PATH => '/usr/local/templates:/tmp/my/templates', - }); - - my $template = Template->new({ - INCLUDE_PATH => [ '/usr/local/templates', - '/tmp/my/templates' ], - }); - -On Win32 systems, a little extra magic is invoked, ignoring delimiters -that have ':' followed by a '/' or '\'. This avoids confusion when using -directory names like 'C:\Blah Blah'. - -When specified as a list, the INCLUDE_PATH path can contain elements -which dynamically generate a list of INCLUDE_PATH directories. These -generator elements can be specified as a reference to a subroutine or -an object which implements a paths() method. - - my $template = Template->new({ - INCLUDE_PATH => [ '/usr/local/templates', - \&incpath_generator, - My::IncPath::Generator->new( ... ) ], - }); - -Each time a template is requested and the INCLUDE_PATH examined, the -subroutine or object method will be called. A reference to a list of -directories should be returned. Generator subroutines should report -errors using die(). Generator objects should return undef and make an -error available via its error() method. - -For example: - - sub incpath_generator { - - # ...some code... - - if ($all_is_well) { - return \@list_of_directories; - } - else { - die "cannot generate INCLUDE_PATH...\n"; - } - } - -or: - - package My::IncPath::Generator; - - # Template::Base (or Class::Base) provides error() method - use Template::Base; - use base qw( Template::Base ); - - sub paths { - my $self = shift; - - # ...some code... - - if ($all_is_well) { - return \@list_of_directories; - } - else { - return $self->error("cannot generate INCLUDE_PATH...\n"); - } - } - - 1; - - - - - -=item DELIMITER - -Used to provide an alternative delimiter character sequence for -separating paths specified in the INCLUDE_PATH. The default -value for DELIMITER is ':'. - - # tolerate Silly Billy's file system conventions - my $template = Template->new({ - DELIMITER => '; ', - INCLUDE_PATH => 'C:/HERE/NOW; D:/THERE/THEN', - }); - - # better solution: install Linux! :-) - -On Win32 systems, the default delimiter is a little more intelligent, -splitting paths only on ':' characters that aren't followed by a '/'. -This means that the following should work as planned, splitting the -INCLUDE_PATH into 2 separate directories, C:/foo and C:/bar. - - # on Win32 only - my $template = Template->new({ - INCLUDE_PATH => 'C:/Foo:C:/Bar' - }); - -However, if you're using Win32 then it's recommended that you -explicitly set the DELIMITER character to something else (e.g. ';') -rather than rely on this subtle magic. - - - - -=item ABSOLUTE - -The ABSOLUTE flag is used to indicate if templates specified with -absolute filenames (e.g. '/foo/bar') should be processed. It is -disabled by default and any attempt to load a template by such a -name will cause a 'file' exception to be raised. - - my $template = Template->new({ - ABSOLUTE => 1, - }); - - # this is why it's disabled by default - [% INSERT /etc/passwd %] - -On Win32 systems, the regular expression for matching absolute -pathnames is tweaked slightly to also detect filenames that start -with a driver letter and colon, such as: - - C:/Foo/Bar - - - - - - -=item RELATIVE - -The RELATIVE flag is used to indicate if templates specified with -filenames relative to the current directory (e.g. './foo/bar' or -'../../some/where/else') should be loaded. It is also disabled by -default, and will raise a 'file' error if such template names are -encountered. - - my $template = Template->new({ - RELATIVE => 1, - }); - - [% INCLUDE ../logs/error.log %] - - - - - -=item DEFAULT - -The DEFAULT option can be used to specify a default template which should -be used whenever a specified template can't be found in the INCLUDE_PATH. - - my $template = Template->new({ - DEFAULT => 'notfound.html', - }); - -If a non-existant template is requested through the Template process() -method, or by an INCLUDE, PROCESS or WRAPPER directive, then the -DEFAULT template will instead be processed, if defined. Note that the -DEFAULT template is not used when templates are specified with -absolute or relative filenames, or as a reference to a input file -handle or text string. - - - - - -=item BLOCKS - -The BLOCKS option can be used to pre-define a default set of template -blocks. These should be specified as a reference to a hash array -mapping template names to template text, subroutines or Template::Document -objects. - - my $template = Template->new({ - BLOCKS => { - header => 'The Header. [% title %]', - footer => sub { return $some_output_text }, - another => Template::Document->new({ ... }), - }, - }); - - - - -=item AUTO_RESET - -The AUTO_RESET option is set by default and causes the local BLOCKS -cache for the Template::Context object to be reset on each call to the -Template process() method. This ensures that any BLOCKs defined -within a template will only persist until that template is finished -processing. This prevents BLOCKs defined in one processing request -from interfering with other independent requests subsequently -processed by the same context object. - -The BLOCKS item may be used to specify a default set of block definitions -for the Template::Context object. Subsequent BLOCK definitions in templates -will over-ride these but they will be reinstated on each reset if AUTO_RESET -is enabled (default), or if the Template::Context reset() method is called. - - - - - - - - - -=item RECURSION - -The template processor will raise a file exception if it detects -direct or indirect recursion into a template. Setting this option to -any true value will allow templates to include each other recursively. - - - -=back - -=head2 Template Variables - -=over 4 - -=item VARIABLES, PRE_DEFINE - -The VARIABLES option (or PRE_DEFINE - they're equivalent) can be used -to specify a hash array of template variables that should be used to -pre-initialise the stash when it is created. These items are ignored -if the STASH item is defined. - - my $template = Template->new({ - VARIABLES => { - title => 'A Demo Page', - author => 'Joe Random Hacker', - version => 3.14, - }, - }; - -or - - my $template = Template->new({ - PRE_DEFINE => { - title => 'A Demo Page', - author => 'Joe Random Hacker', - version => 3.14, - }, - }; - - - - -=item CONSTANTS - -The CONSTANTS option can be used to specify a hash array of template -variables that are compile-time constants. These variables are -resolved once when the template is compiled, and thus don't require -further resolution at runtime. This results in significantly faster -processing of the compiled templates and can be used for variables that -don't change from one request to the next. - - my $template = Template->new({ - CONSTANTS => { - title => 'A Demo Page', - author => 'Joe Random Hacker', - version => 3.14, - }, - }; - -=item CONSTANT_NAMESPACE - -Constant variables are accessed via the 'constants' namespace by -default. - - [% constants.title %] - -The CONSTANTS_NAMESPACE option can be set to specify an alternate -namespace. - - my $template = Template->new({ - CONSTANTS => { - title => 'A Demo Page', - # ...etc... - }, - CONSTANTS_NAMESPACE => 'const', - }; - -In this case the constants would then be accessed as: - - [% const.title %] - -=item NAMESPACE - -The constant folding mechanism described above is an example of a -namespace handler. Namespace handlers can be defined to provide -alternate parsing mechanisms for variables in different namespaces. - -Under the hood, the Template module converts a constructor configuration -such as: - - my $template = Template->new({ - CONSTANTS => { - title => 'A Demo Page', - # ...etc... - }, - CONSTANTS_NAMESPACE => 'const', - }; - -into one like: - - my $template = Template->new({ - NAMESPACE => { - const => Template:::Namespace::Constants->new({ - title => 'A Demo Page', - # ...etc... - }), - }, - }; - -You can use this mechanism to define multiple constant namespaces, or -to install custom handlers of your own. - - my $template = Template->new({ - NAMESPACE => { - site => Template:::Namespace::Constants->new({ - title => "Wardley's Widgets", - version => 2.718, - }), - author => Template:::Namespace::Constants->new({ - name => 'Andy Wardley', - email => 'abw@andywardley.com', - }), - voodoo => My::Namespace::Handler->new( ... ), - }, - }; - -Now you have 2 constant namespaces, for example: - - [% site.title %] - [% author.name %] - -as well as your own custom namespace handler installed for the 'voodoo' -namespace. - - [% voodoo.magic %] - -See L<Template::Namespace::Constants|Template::Namespace::Constants> -for an example of what a namespace handler looks like on the inside. - - - - - -=back - -=head2 Template Processing Options - - -The following options are used to specify any additional templates -that should be processed before, after, around or instead of the -template passed as the first argument to the Template process() -method. These options can be perform various useful tasks such as -adding standard headers or footers to all pages, wrapping page output -in other templates, pre-defining variables or performing -initialisation or cleanup tasks, automatically generating page summary -information, navigation elements, and so on. - -The task of processing the template is delegated internally to the -Template::Service module which, unsurprisingly, also has a process() -method. Any templates defined by the PRE_PROCESS option are processed -first and any output generated is added to the output buffer. Then -the main template is processed, or if one or more PROCESS templates -are defined then they are instead processed in turn. In this case, -one of the PROCESS templates is responsible for processing the main -template, by a directive such as: - - [% PROCESS $template %] - -The output of processing the main template or the PROCESS template(s) -is then wrapped in any WRAPPER templates, if defined. WRAPPER -templates don't need to worry about explicitly processing the template -because it will have been done for them already. Instead WRAPPER -templates access the content they are wrapping via the 'content' -variable. - - wrapper before - [% content %] - wrapper after - -This output generated from processing the main template, and/or any -PROCESS or WRAPPER templates is added to the output buffer. Finally, -any POST_PROCESS templates are processed and their output is also -added to the output buffer which is then returned. - -If the main template throws an exception during processing then any -relevant template(s) defined via the ERROR option will be processed -instead. If defined and successfully processed, the output from the -error template will be added to the output buffer in place of the -template that generated the error and processing will continue, -applying any WRAPPER and POST_PROCESS templates. If no relevant ERROR -option is defined, or if the error occurs in one of the PRE_PROCESS, -WRAPPER or POST_PROCESS templates, then the process will terminate -immediately and the error will be returned. - - - -=over 4 - - - -=item PRE_PROCESS, POST_PROCESS - -These values may be set to contain the name(s) of template files -(relative to INCLUDE_PATH) which should be processed immediately -before and/or after each template. These do not get added to -templates processed into a document via directives such as INCLUDE, -PROCESS, WRAPPER etc. - - my $template = Template->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - }; - -Multiple templates may be specified as a reference to a list. Each is -processed in the order defined. - - my $template = Template->new({ - PRE_PROCESS => [ 'config', 'header' ], - POST_PROCESS => 'footer', - }; - -Alternately, multiple template may be specified as a single string, -delimited by ':'. This delimiter string can be changed via the -DELIMITER option. - - my $template = Template->new({ - PRE_PROCESS => 'config:header', - POST_PROCESS => 'footer', - }; - -The PRE_PROCESS and POST_PROCESS templates are evaluated in the same -variable context as the main document and may define or update -variables for subsequent use. - -config: - - [% # set some site-wide variables - bgcolor = '#ffffff' - version = 2.718 - %] - -header: - - [% DEFAULT title = 'My Funky Web Site' %] - <html> - <head> - <title>[% title %]</title> - </head> - <body bgcolor="[% bgcolor %]"> - -footer: - - <hr> - Version [% version %] - </body> - </html> - -The Template::Document object representing the main template being processed -is available within PRE_PROCESS and POST_PROCESS templates as the 'template' -variable. Metadata items defined via the META directive may be accessed -accordingly. - - $template->process('mydoc.html', $vars); - -mydoc.html: - - [% META title = 'My Document Title' %] - blah blah blah - ... - -header: - - <html> - <head> - <title>[% template.title %]</title></head> - <body bgcolor="[% bgcolor %]"> - - - - - - - - - - - - - - -=item PROCESS - -The PROCESS option may be set to contain the name(s) of template files -(relative to INCLUDE_PATH) which should be processed instead of the -main template passed to the Template process() method. This can -be used to apply consistent wrappers around all templates, similar to -the use of PRE_PROCESS and POST_PROCESS templates. - - my $template = Template->new({ - PROCESS => 'content', - }; - - # processes 'content' instead of 'foo.html' - $template->process('foo.html'); - -A reference to the original template is available in the 'template' -variable. Metadata items can be inspected and the template can be -processed by specifying it as a variable reference (i.e. prefixed by -'$') to an INCLUDE, PROCESS or WRAPPER directive. - -content: - - <html> - <head> - <title>[% template.title %]</title> - </head> - - <body> - [% PROCESS $template %] - <hr> - © Copyright [% template.copyright %] - </body> - </html> - -foo.html: - - [% META - title = 'The Foo Page' - author = 'Fred Foo' - copyright = '2000 Fred Foo' - %] - <h1>[% template.title %]</h1> - Welcome to the Foo Page, blah blah blah - -output: - - <html> - <head> - <title>The Foo Page</title> - </head> - - <body> - <h1>The Foo Page</h1> - Welcome to the Foo Page, blah blah blah - <hr> - © Copyright 2000 Fred Foo - </body> - </html> - - - - - - - -=item WRAPPER - -The WRAPPER option can be used to specify one or more templates which -should be used to wrap around the output of the main page template. -The main template is processed first (or any PROCESS template(s)) and -the output generated is then passed as the 'content' variable to the -WRAPPER template(s) as they are processed. - - my $template = Template->new({ - WRAPPER => 'wrapper', - }; - - # process 'foo' then wrap in 'wrapper' - $template->process('foo', { message => 'Hello World!' }); - -wrapper: - - <wrapper> - [% content %] - </wrapper> - -foo: - - This is the foo file! - Message: [% message %] - -The output generated from this example is: - - <wrapper> - This is the foo file! - Message: Hello World! - </wrapper> - -You can specify more than one WRAPPER template by setting the value to -be a reference to a list of templates. The WRAPPER templates will be -processed in reverse order with the output of each being passed to the -next (or previous, depending on how you look at it) as the 'content' -variable. It sounds complicated, but the end result is that it just -"Does The Right Thing" to make wrapper templates nest in the order you -specify. - - my $template = Template->new({ - WRAPPER => [ 'outer', 'inner' ], - }; - - # process 'foo' then wrap in 'inner', then in 'outer' - $template->process('foo', { message => 'Hello World!' }); - -outer: - - <outer> - [% content %] - </outer> - -inner: - - <inner> - [% content %] - </inner> - -The output generated is then: - - <outer> - <inner> - This is the foo file! - Message: Hello World! - </inner> - </outer> - -One side-effect of the "inside-out" processing of the WRAPPER -configuration item (and also the WRAPPER directive) is that any -variables set in the template being wrapped will be visible to the -template doing the wrapping, but not the other way around. - -You can use this to good effect in allowing page templates to set -pre-defined values which are then used in the wrapper templates. For -example, our main page template 'foo' might look like this: - -foo: - - [% page = { - title = 'Foo Page' - subtitle = 'Everything There is to Know About Foo' - author = 'Frank Oliver Octagon' - } - %] - - <p> - Welcome to the page that tells you everything about foo - blah blah blah... - </p> - -The 'foo' template is processed before the wrapper template meaning -that the 'page' data structure will be defined for use in the wrapper -template. - -wrapper: - - <html> - <head> - <title>[% page.title %]</title> - </head> - <body> - <h1>[% page.title %]</h1> - <h2>[% page.subtitle %]</h1> - <h3>by [% page.author %]</h3> - - [% content %] - </body> - </html> - -It achieves the same effect as defining META items which are then -accessed via the 'template' variable (which you are still free to -use within WRAPPER templates), but gives you more flexibility in -the type and complexity of data that you can define. - - - - - -=item ERROR - -The ERROR (or ERRORS if you prefer) configuration item can be used to -name a single template or specify a hash array mapping exception types -to templates which should be used for error handling. If an uncaught -exception is raised from within a template then the appropriate error -template will instead be processed. - -If specified as a single value then that template will be processed -for all uncaught exceptions. - - my $template = Template->new({ - ERROR => 'error.html' - }); - -If the ERROR item is a hash reference the keys are assumed to be -exception types and the relevant template for a given exception will -be selected. A 'default' template may be provided for the general -case. Note that 'ERROR' can be pluralised to 'ERRORS' if you find -it more appropriate in this case. - - my $template = Template->new({ - ERRORS => { - user => 'user/index.html', - dbi => 'error/database', - default => 'error/default', - }, - }); - -In this example, any 'user' exceptions thrown will cause the -'user/index.html' template to be processed, 'dbi' errors are handled -by 'error/database' and all others by the 'error/default' template. -Any PRE_PROCESS and/or POST_PROCESS templates will also be applied -to these error templates. - -Note that exception types are hierarchical and a 'foo' handler will -catch all 'foo.*' errors (e.g. foo.bar, foo.bar.baz) if a more -specific handler isn't defined. Be sure to quote any exception types -that contain periods to prevent Perl concatenating them into a single -string (i.e. C<user.passwd> is parsed as 'user'.'passwd'). - - my $template = Template->new({ - ERROR => { - 'user.login' => 'user/login.html', - 'user.passwd' => 'user/badpasswd.html', - 'user' => 'user/index.html', - 'default' => 'error/default', - }, - }); - -In this example, any template processed by the $template object, or -other templates or code called from within, can raise a 'user.login' -exception and have the service redirect to the 'user/login.html' -template. Similarly, a 'user.passwd' exception has a specific -handling template, 'user/badpasswd.html', while all other 'user' or -'user.*' exceptions cause a redirection to the 'user/index.html' page. -All other exception types are handled by 'error/default'. - - -Exceptions can be raised in a template using the THROW directive, - - [% THROW user.login 'no user id: please login' %] - -or by calling the throw() method on the current Template::Context object, - - $context->throw('user.passwd', 'Incorrect Password'); - $context->throw('Incorrect Password'); # type 'undef' - -or from Perl code by calling die() with a Template::Exception object, - - die (Template::Exception->new('user.denied', 'Invalid User ID')); - -or by simply calling die() with an error string. This is -automagically caught and converted to an exception of 'undef' -type which can then be handled in the usual way. - - die "I'm sorry Dave, I can't do that"; - - - - - - -=back - -=head2 Template Runtime Options - -=over 4 - - - - -=item EVAL_PERL - -This flag is used to indicate if PERL and/or RAWPERL blocks should be -evaluated. By default, it is disabled and any PERL or RAWPERL blocks -encountered will raise exceptions of type 'perl' with the message -'EVAL_PERL not set'. Note however that any RAWPERL blocks should -always contain valid Perl code, regardless of the EVAL_PERL flag. The -parser will fail to compile templates that contain invalid Perl code -in RAWPERL blocks and will throw a 'file' exception. - -When using compiled templates (see -L<COMPILE_EXT|Template::Manual::Config/Caching_and_Compiling_Options> and -L<COMPILE_DIR|Template::Manual::Config/Caching_and_Compiling_Options>), -the EVAL_PERL has an affect when the template is compiled, and again -when the templates is subsequently processed, possibly in a different -context to the one that compiled it. - -If the EVAL_PERL is set when a template is compiled, then all PERL and -RAWPERL blocks will be included in the compiled template. If the -EVAL_PERL option isn't set, then Perl code will be generated which -B<always> throws a 'perl' exception with the message 'EVAL_PERL not -set' B<whenever> the compiled template code is run. - -Thus, you must have EVAL_PERL set if you want your compiled templates -to include PERL and RAWPERL blocks. - -At some point in the future, using a different invocation of the -Template Toolkit, you may come to process such a pre-compiled -template. Assuming the EVAL_PERL option was set at the time the -template was compiled, then the output of any RAWPERL blocks will be -included in the compiled template and will get executed when the -template is processed. This will happen regardless of the runtime -EVAL_PERL status. - -Regular PERL blocks are a little more cautious, however. If the -EVAL_PERL flag isn't set for the I<current> context, that is, the -one which is trying to process it, then it will throw the familiar 'perl' -exception with the message, 'EVAL_PERL not set'. - -Thus you can compile templates to include PERL blocks, but optionally -disable them when you process them later. Note however that it is -possible for a PERL block to contain a Perl "BEGIN { # some code }" -block which will always get run regardless of the runtime EVAL_PERL -status. Thus, if you set EVAL_PERL when compiling templates, it is -assumed that you trust the templates to Do The Right Thing. Otherwise -you must accept the fact that there's no bulletproof way to prevent -any included code from trampling around in the living room of the -runtime environment, making a real nuisance of itself if it really -wants to. If you don't like the idea of such uninvited guests causing -a bother, then you can accept the default and keep EVAL_PERL disabled. - - - - - - - -=item OUTPUT - -Default output location or handler. This may be specified as one of: -a file name (relative to OUTPUT_PATH, if defined, or the current -working directory if not specified absolutely); a file handle -(e.g. GLOB or IO::Handle) opened for writing; a reference to a text -string to which the output is appended (the string isn't cleared); a -reference to a subroutine which is called, passing the output text as -an argument; as a reference to an array, onto which the content will be -push()ed; or as a reference to any object that supports the print() -method. This latter option includes the Apache::Request object which -is passed as the argument to Apache/mod_perl handlers. - -example 1 (file name): - - my $template = Template->new({ - OUTPUT => "/tmp/foo", - }); - -example 2 (text string): - - my $output = ''; - - my $template = Template->new({ - OUTPUT => \$output, - }); - -example 3 (file handle): - - open (TOUT, "> $file") || die "$file: $!\n"; - - my $template = Template->new({ - OUTPUT => \*TOUT, - }); - -example 4 (subroutine): - - sub output { my $out = shift; print "OUTPUT: $out" } - - my $template = Template->new({ - OUTPUT => \&output, - }); - -example 5 (array reference): - - my $template = Template->new({ - OUTPUT => \@output, - }) - -example 6 (Apache/mod_perl handler): - - sub handler { - my $r = shift; - - my $t = Template->new({ - OUTPUT => $r, - }); - ... - } - -The default OUTPUT location be overridden by passing a third parameter -to the Template process() method. This can be specified as any of the -above argument types. - - $t->process($file, $vars, "/tmp/foo"); - $t->process($file, $vars, "bar"); - $t->process($file, $vars, \*MYGLOB); - $t->process($file, $vars, \@output); - $t->process($file, $vars, $r); # Apache::Request - ... - - - - - - - - -=item OUTPUT_PATH - -The OUTPUT_PATH allows a directory to be specified into which output -files should be written. An output file can be specified by the -OUTPUT option, or passed by name as the third parameter to the -Template process() method. - - my $template = Template->new({ - INCLUDE_PATH => "/tmp/src", - OUTPUT_PATH => "/tmp/dest", - }); - - my $vars = { - ... - }; - - foreach my $file ('foo.html', 'bar.html') { - $template->process($file, $vars, $file) - || die $template->error(); - } - -This example will read the input files '/tmp/src/foo.html' and -'/tmp/src/bar.html' and write the processed output to '/tmp/dest/foo.html' -and '/tmp/dest/bar.html', respectively. - - - - - - - - -=item DEBUG - -The DEBUG option can be used to enable debugging within the various -different modules that comprise the Template Toolkit. The -L<Template::Constants|Template::Constants> module defines a set of -DEBUG_XXXX constants which can be combined using the logical OR -operator, '|'. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_PARSER | DEBUG_PROVIDER, - }); - -For convenience, you can also provide a string containing a list -of lower case debug options, separated by any non-word characters. - - my $template = Template->new({ - DEBUG => 'parser, provider', - }); - -The following DEBUG_XXXX flags can be used: - -=over 4 - -=item DEBUG_SERVICE - -Enables general debugging messages for the -L<Template::Service|Template::Service> module. - -=item DEBUG_CONTEXT - -Enables general debugging messages for the -L<Template::Context|Template::Context> module. - -=item DEBUG_PROVIDER - -Enables general debugging messages for the -L<Template::Provider|Template::Provider> module. - -=item DEBUG_PLUGINS - -Enables general debugging messages for the -L<Template::Plugins|Template::Plugins> module. - -=item DEBUG_FILTERS - -Enables general debugging messages for the -L<Template::Filters|Template::Filters> module. - -=item DEBUG_PARSER - -This flag causes the L<Template::Parser|Template::Parser> to generate -debugging messages that show the Perl code generated by parsing and -compiling each template. - -=item DEBUG_UNDEF - -This option causes the Template Toolkit to throw an 'undef' error -whenever it encounters an undefined variable value. - -=item DEBUG_DIRS - -This option causes the Template Toolkit to generate comments -indicating the source file, line and original text of each directive -in the template. These comments are embedded in the template output -using the format defined in the DEBUG_FORMAT configuration item, or a -simple default format if unspecified. - -For example, the following template fragment: - - - Hello World - -would generate this output: - - ## input text line 1 : ## - Hello - ## input text line 2 : World ## - World - -=item DEBUG_ALL - -Enables all debugging messages. - -=item DEBUG_CALLER - -This option causes all debug messages that aren't newline terminated -to have the file name and line number of the caller appended to them. - - -=back - -=item DEBUG_FORMAT - -The DEBUG_FORMAT option can be used to specify a format string for the -debugging messages generated via the DEBUG_DIRS option described -above. Any occurances of C<$file>, C<$line> or C<$text> will be -replaced with the current file name, line or directive text, -respectively. Notice how the format is single quoted to prevent Perl -from interpolating those tokens as variables. - - my $template = Template->new({ - DEBUG => 'dirs', - DEBUG_FORMAT => '<!-- $file line $line : [% $text %] -->', - }); - -The following template fragment: - - [% foo = 'World' %] - Hello [% foo %] - -would then generate this output: - - <!-- input text line 2 : [% foo = 'World' %] --> - Hello <!-- input text line 3 : [% foo %] -->World - -The DEBUG directive can also be used to set a debug format within -a template. - - [% DEBUG format '<!-- $file line $line : [% $text %] -->' %] - - -=back - -=head2 Caching and Compiling Options - -=over 4 - - - -=item CACHE_SIZE - -The Template::Provider module caches compiled templates to avoid the need -to re-parse template files or blocks each time they are used. The CACHE_SIZE -option is used to limit the number of compiled templates that the module -should cache. - -By default, the CACHE_SIZE is undefined and all compiled templates are -cached. When set to any positive value, the cache will be limited to -storing no more than that number of compiled templates. When a new -template is loaded and compiled and the cache is full (i.e. the number -of entries == CACHE_SIZE), the least recently used compiled template -is discarded to make room for the new one. - -The CACHE_SIZE can be set to 0 to disable caching altogether. - - my $template = Template->new({ - CACHE_SIZE => 64, # only cache 64 compiled templates - }); - - my $template = Template->new({ - CACHE_SIZE => 0, # don't cache any compiled templates - }); - - - - - - -=item COMPILE_EXT - -From version 2 onwards, the Template Toolkit has the ability to -compile templates to Perl code and save them to disk for subsequent -use (i.e. cache persistence). The COMPILE_EXT option may be -provided to specify a filename extension for compiled template files. -It is undefined by default and no attempt will be made to read or write -any compiled template files. - - my $template = Template->new({ - COMPILE_EXT => '.ttc', - }); - -If COMPILE_EXT is defined (and COMPILE_DIR isn't, see below) then compiled -template files with the COMPILE_EXT extension will be written to the same -directory from which the source template files were loaded. - -Compiling and subsequent reuse of templates happens automatically -whenever the COMPILE_EXT or COMPILE_DIR options are set. The Template -Toolkit will automatically reload and reuse compiled files when it -finds them on disk. If the corresponding source file has been modified -since the compiled version as written, then it will load and re-compile -the source and write a new compiled version to disk. - -This form of cache persistence offers significant benefits in terms of -time and resources required to reload templates. Compiled templates can -be reloaded by a simple call to Perl's require(), leaving Perl to handle -all the parsing and compilation. This is a Good Thing. - -=item COMPILE_DIR - -The COMPILE_DIR option is used to specify an alternate directory root -under which compiled template files should be saved. - - my $template = Template->new({ - COMPILE_DIR => '/tmp/ttc', - }); - -The COMPILE_EXT option may also be specified to have a consistent file -extension added to these files. - - my $template1 = Template->new({ - COMPILE_DIR => '/tmp/ttc', - COMPILE_EXT => '.ttc1', - }); - - my $template2 = Template->new({ - COMPILE_DIR => '/tmp/ttc', - COMPILE_EXT => '.ttc2', - }); - - -When COMPILE_EXT is undefined, the compiled template files have the -same name as the original template files, but reside in a different -directory tree. - -Each directory in the INCLUDE_PATH is replicated in full beneath the -COMPILE_DIR directory. This example: - - my $template = Template->new({ - COMPILE_DIR => '/tmp/ttc', - INCLUDE_PATH => '/home/abw/templates:/usr/share/templates', - }); - -would create the following directory structure: - - /tmp/ttc/home/abw/templates/ - /tmp/ttc/usr/share/templates/ - -Files loaded from different INCLUDE_PATH directories will have their -compiled forms save in the relevant COMPILE_DIR directory. - -On Win32 platforms a filename may by prefixed by a drive letter and -colon. e.g. - - C:/My Templates/header - -The colon will be silently stripped from the filename when it is added -to the COMPILE_DIR value(s) to prevent illegal filename being generated. -Any colon in COMPILE_DIR elements will be left intact. For example: - - # Win32 only - my $template = Template->new({ - DELIMITER => ';', - COMPILE_DIR => 'C:/TT2/Cache', - INCLUDE_PATH => 'C:/TT2/Templates;D:/My Templates', - }); - -This would create the following cache directories: - - C:/TT2/Cache/C/TT2/Templates - C:/TT2/Cache/D/My Templates - - -=back - -=head2 Plugins and Filters - -=over 4 - - - -=item PLUGINS - -The PLUGINS options can be used to provide a reference to a hash array -that maps plugin names to Perl module names. A number of standard -plugins are defined (e.g. 'table', 'cgi', 'dbi', etc.) which map to -their corresponding Template::Plugin::* counterparts. These can be -redefined by values in the PLUGINS hash. - - my $template = Template->new({ - PLUGINS => { - cgi => 'MyOrg::Template::Plugin::CGI', - foo => 'MyOrg::Template::Plugin::Foo', - bar => 'MyOrg::Template::Plugin::Bar', - }, - }); - -The USE directive is used to create plugin objects and does so by -calling the plugin() method on the current Template::Context object. -If the plugin name is defined in the PLUGINS hash then the -corresponding Perl module is loaded via require(). The context then -calls the load() class method which should return the class name -(default and general case) or a prototype object against which the -new() method can be called to instantiate individual plugin objects. - -If the plugin name is not defined in the PLUGINS hash then the PLUGIN_BASE -and/or LOAD_PERL options come into effect. - - - - - -=item PLUGIN_BASE - -If a plugin is not defined in the PLUGINS hash then the PLUGIN_BASE is used -to attempt to construct a correct Perl module name which can be successfully -loaded. - -The PLUGIN_BASE can be specified as a single value or as a reference -to an array of multiple values. The default PLUGIN_BASE value, -'Template::Plugin', is always added the the end of the PLUGIN_BASE -list (a single value is first converted to a list). Each value should -contain a Perl package name to which the requested plugin name is -appended. - -example 1: - - my $template = Template->new({ - PLUGIN_BASE => 'MyOrg::Template::Plugin', - }); - - [% USE Foo %] # => MyOrg::Template::Plugin::Foo - or Template::Plugin::Foo - -example 2: - - my $template = Template->new({ - PLUGIN_BASE => [ 'MyOrg::Template::Plugin', - 'YourOrg::Template::Plugin' ], - }); - - [% USE Foo %] # => MyOrg::Template::Plugin::Foo - or YourOrg::Template::Plugin::Foo - or Template::Plugin::Foo - - - - - - -=item LOAD_PERL - -If a plugin cannot be loaded using the PLUGINS or PLUGIN_BASE -approaches then the provider can make a final attempt to load the -module without prepending any prefix to the module path. This allows -regular Perl modules (i.e. those that don't reside in the -Template::Plugin or some other such namespace) to be loaded and used -as plugins. - -By default, the LOAD_PERL option is set to 0 and no attempt will be made -to load any Perl modules that aren't named explicitly in the PLUGINS -hash or reside in a package as named by one of the PLUGIN_BASE -components. - -Plugins loaded using the PLUGINS or PLUGIN_BASE receive a reference to -the current context object as the first argument to the new() -constructor. Modules loaded using LOAD_PERL are assumed to not -conform to the plugin interface. They must provide a new() class -method for instantiating objects but it will not receive a reference -to the context as the first argument. Plugin modules should provide a -load() class method (or inherit the default one from the -Template::Plugin base class) which is called the first time the plugin -is loaded. Regular Perl modules need not. In all other respects, -regular Perl objects and Template Toolkit plugins are identical. - -If a particular Perl module does not conform to the common, but not -unilateral, new() constructor convention then a simple plugin wrapper -can be written to interface to it. - - - - -=item FILTERS - -The FILTERS option can be used to specify custom filters which can -then be used with the FILTER directive like any other. These are -added to the standard filters which are available by default. Filters -specified via this option will mask any standard filters of the same -name. - -The FILTERS option should be specified as a reference to a hash array -in which each key represents the name of a filter. The corresponding -value should contain a reference to an array containing a subroutine -reference and a flag which indicates if the filter is static (0) or -dynamic (1). A filter may also be specified as a solitary subroutine -reference and is assumed to be static. - - $template = Template->new({ - FILTERS => { - 'sfilt1' => \&static_filter, # static - 'sfilt2' => [ \&static_filter, 0 ], # same as above - 'dfilt1' => [ \&dyanamic_filter_factory, 1 ], - }, - }); - -Additional filters can be specified at any time by calling the -define_filter() method on the current Template::Context object. -The method accepts a filter name, a reference to a filter -subroutine and an optional flag to indicate if the filter is -dynamic. - - my $context = $template->context(); - $context->define_filter('new_html', \&new_html); - $context->define_filter('new_repeat', \&new_repeat, 1); - -Static filters are those where a single subroutine reference is used -for all invocations of a particular filter. Filters that don't accept -any configuration parameters (e.g. 'html') can be implemented -statically. The subroutine reference is simply returned when that -particular filter is requested. The subroutine is called to filter -the output of a template block which is passed as the only argument. -The subroutine should return the modified text. - - sub static_filter { - my $text = shift; - # do something to modify $text... - return $text; - } - -The following template fragment: - - [% FILTER sfilt1 %] - Blah blah blah. - [% END %] - -is approximately equivalent to: - - &static_filter("\nBlah blah blah.\n"); - -Filters that can accept parameters (e.g. 'truncate') should be -implemented dynamically. In this case, the subroutine is taken to be -a filter 'factory' that is called to create a unique filter subroutine -each time one is requested. A reference to the current -Template::Context object is passed as the first parameter, followed by -any additional parameters specified. The subroutine should return -another subroutine reference (usually a closure) which implements the -filter. - - sub dynamic_filter_factory { - my ($context, @args) = @_; - - return sub { - my $text = shift; - # do something to modify $text... - return $text; - } - } - -The following template fragment: - - [% FILTER dfilt1(123, 456) %] - Blah blah blah - [% END %] - -is approximately equivalent to: - - my $filter = &dynamic_filter_factory($context, 123, 456); - &$filter("\nBlah blah blah.\n"); - -See the FILTER directive for further examples. - - -=back - -=head2 Compatibility, Customisation and Extension - -=over 4 - - - -=item V1DOLLAR - -In version 1 of the Template Toolkit, an optional leading '$' could be placed -on any template variable and would be silently ignored. - - # VERSION 1 - [% $foo %] === [% foo %] - [% $hash.$key %] === [% hash.key %] - -To interpolate a variable value the '${' ... '}' construct was used. -Typically, one would do this to index into a hash array when the key -value was stored in a variable. - -example: - - my $vars = { - users => { - aba => { name => 'Alan Aardvark', ... }, - abw => { name => 'Andy Wardley', ... }, - ... - }, - uid => 'aba', - ... - }; - - $template->process('user/home.html', $vars) - || die $template->error(), "\n"; - -'user/home.html': - - [% user = users.${uid} %] # users.aba - Name: [% user.name %] # Alan Aardvark - -This was inconsistent with double quoted strings and also the -INTERPOLATE mode, where a leading '$' in text was enough to indicate a -variable for interpolation, and the additional curly braces were used -to delimit variable names where necessary. Note that this use is -consistent with UNIX and Perl conventions, among others. - - # double quoted string interpolation - [% name = "$title ${user.name}" %] - - # INTERPOLATE = 1 - <img src="$images/help.gif"></a> - <img src="$images/${icon.next}.gif"> - -For version 2, these inconsistencies have been removed and the syntax -clarified. A leading '$' on a variable is now used exclusively to -indicate that the variable name should be interpolated -(e.g. subsituted for its value) before being used. The earlier example -from version 1: - - # VERSION 1 - [% user = users.${uid} %] - Name: [% user.name %] - -can now be simplified in version 2 as: - - # VERSION 2 - [% user = users.$uid %] - Name: [% user.name %] - -The leading dollar is no longer ignored and has the same effect of -interpolation as '${' ... '}' in version 1. The curly braces may -still be used to explicitly scope the interpolated variable name -where necessary. - -e.g. - - [% user = users.${me.id} %] - Name: [% user.name %] - -The rule applies for all variables, both within directives and in -plain text if processed with the INTERPOLATE option. This means that -you should no longer (if you ever did) add a leading '$' to a variable -inside a directive, unless you explicitly want it to be interpolated. - -One obvious side-effect is that any version 1 templates with variables -using a leading '$' will no longer be processed as expected. Given -the following variable definitions, - - [% foo = 'bar' - bar = 'baz' - %] - -version 1 would interpret the following as: - - # VERSION 1 - [% $foo %] => [% GET foo %] => bar - -whereas version 2 interprets it as: - - # VERSION 2 - [% $foo %] => [% GET $foo %] => [% GET bar %] => baz - -In version 1, the '$' is ignored and the value for the variable 'foo' is -retrieved and printed. In version 2, the variable '$foo' is first interpolated -to give the variable name 'bar' whose value is then retrieved and printed. - -The use of the optional '$' has never been strongly recommended, but -to assist in backwards compatibility with any version 1 templates that -may rely on this "feature", the V1DOLLAR option can be set to 1 -(default: 0) to revert the behaviour and have leading '$' characters -ignored. - - my $template = Template->new({ - V1DOLLAR => 1, - }); - - - - -=item LOAD_TEMPLATES - -The LOAD_TEMPLATE option can be used to provide a reference to a list -of Template::Provider objects or sub-classes thereof which will take -responsibility for loading and compiling templates. - - my $template = Template->new({ - LOAD_TEMPLATES => [ - MyOrg::Template::Provider->new({ ... }), - Template::Provider->new({ ... }), - ], - }); - -When a PROCESS, INCLUDE or WRAPPER directive is encountered, the named -template may refer to a locally defined BLOCK or a file relative to -the INCLUDE_PATH (or an absolute or relative path if the appropriate -ABSOLUTE or RELATIVE options are set). If a BLOCK definition can't be -found (see the Template::Context template() method for a discussion of -BLOCK locality) then each of the LOAD_TEMPLATES provider objects is -queried in turn via the fetch() method to see if it can supply the -required template. Each provider can return a compiled template, an -error, or decline to service the request in which case the -responsibility is passed to the next provider. If none of the -providers can service the request then a 'not found' error is -returned. The same basic provider mechanism is also used for the -INSERT directive but it bypasses any BLOCK definitions and doesn't -attempt is to parse or process the contents of the template file. - -This is an implementation of the 'Chain of Responsibility' -design pattern as described in -"Design Patterns", Erich Gamma, Richard Helm, Ralph Johnson, John -Vlissides), Addision-Wesley, ISBN 0-201-63361-2, page 223 -. - -If LOAD_TEMPLATES is undefined, a single default provider will be -instantiated using the current configuration parameters. For example, -the Template::Provider INCLUDE_PATH option can be specified in the Template configuration and will be correctly passed to the provider's -constructor method. - - my $template = Template->new({ - INCLUDE_PATH => '/here:/there', - }); - - - - - -=item LOAD_PLUGINS - -The LOAD_PLUGINS options can be used to specify a list of provider -objects (i.e. they implement the fetch() method) which are responsible -for loading and instantiating template plugin objects. The -Template::Content plugin() method queries each provider in turn in a -"Chain of Responsibility" as per the template() and filter() methods. - - my $template = Template->new({ - LOAD_PLUGINS => [ - MyOrg::Template::Plugins->new({ ... }), - Template::Plugins->new({ ... }), - ], - }); - -By default, a single Template::Plugins object is created using the -current configuration hash. Configuration items destined for the -Template::Plugins constructor may be added to the Template -constructor. - - my $template = Template->new({ - PLUGIN_BASE => 'MyOrg::Template::Plugins', - LOAD_PERL => 1, - }); - - - - - -=item LOAD_FILTERS - -The LOAD_FILTERS option can be used to specify a list of provider -objects (i.e. they implement the fetch() method) which are responsible -for returning and/or creating filter subroutines. The -Template::Context filter() method queries each provider in turn in a -"Chain of Responsibility" as per the template() and plugin() methods. - - my $template = Template->new({ - LOAD_FILTERS => [ - MyTemplate::Filters->new(), - Template::Filters->new(), - ], - }); - -By default, a single Template::Filters object is created for the -LOAD_FILTERS list. - - - - - -=item TOLERANT - -The TOLERANT flag is used by the various Template Toolkit provider -modules (Template::Provider, Template::Plugins, Template::Filters) to -control their behaviour when errors are encountered. By default, any -errors are reported as such, with the request for the particular -resource (template, plugin, filter) being denied and an exception -raised. When the TOLERANT flag is set to any true values, errors will -be silently ignored and the provider will instead return -STATUS_DECLINED. This allows a subsequent provider to take -responsibility for providing the resource, rather than failing the -request outright. If all providers decline to service the request, -either through tolerated failure or a genuine disinclination to -comply, then a 'E<lt>resourceE<gt> not found' exception is raised. - - - - - - -=item SERVICE - -A reference to a Template::Service object, or sub-class thereof, to which -the Template module should delegate. If unspecified, a Template::Service -object is automatically created using the current configuration hash. - - my $template = Template->new({ - SERVICE => MyOrg::Template::Service->new({ ... }), - }); - - - - - -=item CONTEXT - -A reference to a Template::Context object which is used to define a -specific environment in which template are processed. A Template::Context -object is passed as the only parameter to the Perl subroutines that -represent "compiled" template documents. Template subroutines make -callbacks into the context object to access Template Toolkit functionality, -for example, to to INCLUDE or PROCESS another template (include() and -process() methods, respectively), to USE a plugin (plugin()) or -instantiate a filter (filter()) or to access the stash (stash()) which -manages variable definitions via the get() and set() methods. - - my $template = Template->new({ - CONTEXT => MyOrg::Template::Context->new({ ... }), - }); - - - -=item STASH - -A reference to a Template::Stash object or sub-class which will take -responsibility for managing template variables. - - my $stash = MyOrg::Template::Stash->new({ ... }); - my $template = Template->new({ - STASH => $stash, - }); - -If unspecified, a default stash object is created using the VARIABLES -configuration item to initialise the stash variables. These may also -be specified as the PRE_DEFINE option for backwards compatibility with -version 1. - - my $template = Template->new({ - VARIABLES => { - id => 'abw', - name => 'Andy Wardley', - }, - }; - - - - - -=item PARSER - -The Template::Parser module implements a parser object for compiling -templates into Perl code which can then be executed. A default object -of this class is created automatically and then used by the -Template::Provider whenever a template is loaded and requires -compilation. The PARSER option can be used to provide a reference to -an alternate parser object. - - my $template = Template->new({ - PARSER => MyOrg::Template::Parser->new({ ... }), - }); - - - - - -=item GRAMMAR - -The GRAMMAR configuration item can be used to specify an alternate -grammar for the parser. This allows a modified or entirely new -template language to be constructed and used by the Template Toolkit. - -Source templates are compiled to Perl code by the Template::Parser -using the Template::Grammar (by default) to define the language -structure and semantics. Compiled templates are thus inherently -"compatible" with each other and there is nothing to prevent any -number of different template languages being compiled and used within -the same Template Toolkit processing environment (other than the usual -time and memory constraints). - -The Template::Grammar file is constructed from a YACC like grammar -(using Parse::YAPP) and a skeleton module template. These files are -provided, along with a small script to rebuild the grammar, in the -'parser' sub-directory of the distribution. You don't have to know or -worry about these unless you want to hack on the template language or -define your own variant. There is a README file in the same directory -which provides some small guidance but it is assumed that you know -what you're doing if you venture herein. If you grok LALR parsers, -then you should find it comfortably familiar. - -By default, an instance of the default Template::Grammar will be -created and used automatically if a GRAMMAR item isn't specified. - - use MyOrg::Template::Grammar; - - my $template = Template->new({ - GRAMMAR = MyOrg::Template::Grammar->new(); - }); - - - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Credits.pod b/lib/Template/Manual/Credits.pod deleted file mode 100644 index 64999ac..0000000 --- a/lib/Template/Manual/Credits.pod +++ /dev/null @@ -1,188 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Credits -# -# DESCRIPTION -# This section provides a brief history of the Template Toolkit and -# details the primary author and numerous other people who have -# contributed to it. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Credits - Author and contributor credits - -=head1 DESCRIPTION - -This section provides a brief history of the Template Toolkit and -details the primary author and numerous other people who have -contributed to it. - -=head1 HISTORY - -The Template Toolkit began its life as the Text::MetaText module, -originally released to CPAN around 1996. This itself was the public -manifestation of an earlier template processing system I developed -while working at Peritas (now Knowledge Pool - - http://www.knowledgepool.com/) - -Text::MetaText was the prototype - the one we always planned to throw -away. It did the job well, showing us what worked and what didn't, what -was good and what was bad, and gave us some ideas about what could be -done better, given the chance to start again from scratch. - -Some time late in 1998 I threw away the prototype and started work on -the Template Toolkit. By then I was working at Canon Research Centre -Europe Ltd. (http://www.cre.canon.co.uk), involved in a general -research programme related to web publishing and dynamic content -generation. The first alpha release was in June 1999, followed by -numerous more alpha and beta releases culminating in 1.00 being -released on 2nd December 1999. - -A month or so later, work had begun on version 2.00. The plan was to -get the template language relatively stable in version 1.00 and not -worry too much about performance or other internal matters. Then, -version 2.00 would follow to improve performance, clean up the -architecture and fix anything that, with the benefit of hindsight, we -thought could be improved. As it happens, me starting work on version -2.00 coincided with Doug Steinwand sending me his parser variant which -compiled templates to Perl code, giving a major performance boost. -As well as the speedups, there are a whole host of significant new -features in version 2.00, and a greatly improved internal architecture. -Apart from a few minor "fixups" the template directives and language -have remained the same as in version 1.00 - -Version 2.00 was available in beta release form in July 2000, just -in time for the 4th Perl Conference where version 1.00 was awarded -"Best New Perl Module". After another extended beta release period, -version 2.00 was released on 1st December 2000. - - - - -=head1 CONTRIBUTORS - -Many people have contributed ideas, inspiration, fixes and features to -the Template Toolkit. Their efforts continue to be very much appreciated. -Please let me know if you think anyone is missing from this list. - - Chuck Adams <scrytch@uswest.net> - Stephen Adkins <stephen.adkins@officevision.com> - Ivan Adzhubey <iadzhubey@rics.bwh.harvard.edu> - Mark Anderson <mda@discerning.com> - Bradley Baetz <bbaetz@student.usyd.edu.au> - Thierry-Michel Barral <kktos@electron-libre.com> - Craig Barratt <craig@arraycomm.com> - Stas Bekman <stas@stason.org> - Tony Bowden <tony-tt@kasei.com> - Neil Bowers <neilb@cre.canon.co.uk> - Leon Brocard <acme@astray.com> - Lyle Brooks <brooks@deseret.com> - Dave Cash <dave@gnofn.org> - Piers Cawley <pdcawley@bofh.org.uk> - Darren Chamberlain <dlc@users.sourceforge.net> - Eric Cholet <cholet@logilune.com> - Dave Cross <dave@dave.org.uk> - Chris Dean <ctdean@babycenter.com> - Francois Desarmenien <desar@club-internet.fr> - Horst Dumcke <hdumcke@cisco.com> - Mark Fowler <mark@indicosoftware.com> - Michael Fowler <michael@shoebox.net> - Axel Gerstmair <anthill@web.de> - Dylan William Hardison <dylanwh@tampabay.rr.com> - Perrin Harkins <pharkins@etoys.com> - Bryce Harrington <bryce@osdl.org> - Dave Hodgkinson <daveh@davehodgkinson.com> - Harald Joerg <Harald.Joerg@fujitsu-siemens.com> - Colin Johnson <colin@knowledgepool.com> - Vivek Khera <khera@kciLink.com> - Rafael Kitover <caelum@debian.org> - Ivan Kurmanov <http://www.ahinea.com> - Hans von Lengerke <hans@lengerke.org> - Jonas Liljegren <jonas@paranormal.se> - Simon Luff <simon@sports.com> - Paul Makepeace <Paul.Makepeace@realprogrammers.com> - Gervase Markham <gerv@mozilla.org> - Simon Matthews <sam@knowledgepool.com> - Robert McArthur <mcarthur@dstc.edu.au> - Craig McLane <mclanec@oxy.edu> - Leslie Michael Orchard <deus_x@ninjacode.com> - Eugene Miretskiy <eugene@invision.net> - Tatsuhiko Miyagawa <miyagawa@edge.co.jp> - Keith G. Murphy <keithmur@mindspring.com> - Chris Nandor <pudge@pobox.com> - Briac Pilpré <briac@pilpre.com> - Martin Portman <mrp@cre.canon.co.uk> - Slaven Rezic <slaven.rezic@berlin.de> - Christian Schaffner <schaffner@eeh.ee.ethz.ch> - Randal L. Schwartz <merlyn@stonehenge.com> - Paul Sharpe <paul@miraclefish.com> - Ville Skyttä <ville.skytta@iki.fi> - Doug Steinwand <dsteinwand@etoys.com> - Michael Stevens <michael@etla.org> - Drew Taylor <dtaylor@vialogix.com> - Swen Thuemmler <Swen.Thuemmler@paderlinx.de> - Richard Tietjen <Richard_Tietjen@mcgraw-hill.com> - Stathy G. Touloumis <stathy.touloumis@edventions.com> - Jim Vaughan <jim@mrjim.com> - Simon Wilcox <simonw@simonwilcox.co.uk> - Chris Winters <cwinters@intes.net> - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Directives.pod b/lib/Template/Manual/Directives.pod deleted file mode 100644 index 3b8af3e..0000000 --- a/lib/Template/Manual/Directives.pod +++ /dev/null @@ -1,2179 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Directives -# -# DESCRIPTION -# This section provides a reference of all Template Toolkit -# directives, complete with examples of use. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Directives - Template directives - -=head1 DESCRIPTION - -This section provides a reference of all Template Toolkit directives, -complete with examples of use. - -=head2 Accessing and Updating Template Variables - -=over 4 - - -=item GET - -The GET directive retrieves and outputs the value of the named variable. - - [% GET foo %] - -The GET keyword is optional. A variable can be specified in a directive -tag by itself. - - [% foo %] - -The variable can have an unlimited number of elements, each separated -by a dot '.'. Each element can have arguments specified within -parentheses. - - [% foo %] - [% bar.baz %] - [% biz.baz(10) %] - ...etc... - -See L<Template::Manual::Variables> for a full discussion on template -variables. - -You can also specify expressions using the logical (and, or, not, ?:) and -mathematic operators (+ - * / % mod div). - - [% template.title or default.title %] - - [% score * 100 %] - - [% order.nitems ? checkout(order.total) : 'no items' %] - -The 'div' operator returns the integer result of division. Both '%' and -'mod' return the modulus (i.e. remainder) of division. 'mod' is provided -as an alias for '%' for backwards compatibility with version 1. - - [% 15 / 6 %] # 2.5 - [% 15 div 6 %] # 2 - [% 15 mod 6 %] # 3 - - - -=item CALL - -The CALL directive is similar to GET in evaluating the variable named, -but doesn't print the result returned. This can be useful when a -variable is bound to a sub-routine or object method which you want to -call but aren't interested in the value returned. - - [% CALL dbi.disconnect %] - - [% CALL inc_page_counter(page_count) %] - - - - -=item SET - -The SET directive allows you to assign new values to existing variables -or create new temporary variables. - - [% SET title = 'Hello World' %] - -The SET keyword is also optional. - - [% title = 'Hello World' %] - -Variables may be assigned the values of other variables, unquoted -numbers (digits), literal text ('single quotes') or quoted text -("double quotes"). In the latter case, any variable references within -the text will be interpolated when the string is evaluated. Variables -should be prefixed by '$', using curly braces to explicitly scope -the variable name where necessary. - - [% foo = 'Foo' %] # literal value 'Foo' - [% bar = foo %] # value of variable 'foo' - [% cost = '$100' %] # literal value '$100' - [% item = "$bar: ${cost}.00" %] # value "Foo: $100.00" - -Multiple variables may be assigned in the same directive and are -evaluated in the order specified. Thus, the above could have been -written: - - [% foo = 'Foo' - bar = foo - cost = '$100' - item = "$bar: ${cost}.00" - %] - -Simple expressions can also be used, as per GET. - - [% ten = 10 - twenty = 20 - thirty = twenty + ten - forty = 2 * twenty - fifty = 100 div 2 - six = twenty mod 7 - %] - -You can concatenate strings together using the ' _ ' operator. In Perl 5, -the '.' is used for string concatenation, but in Perl 6, as in the Template -Toolkit, the '.' will be used as the method calling operator and ' _ ' will -be used for string concatenation. Note that the operator must be -specified with surrounding whitespace which, as Larry says, is construed as -a feature: - - [% copyright = '(C) Copyright' _ year _ ' ' _ author %] - -You can, of course, achieve a similar effect with double quoted string -interpolation. - - [% copyright = "(C) Copyright $year $author" %] - - - - - -=item DEFAULT - -The DEFAULT directive is similar to SET but only updates variables -that are currently undefined or have no "true" value (in the Perl -sense). - - [% DEFAULT - name = 'John Doe' - id = 'jdoe' - %] - -This can be particularly useful in common template components to -ensure that some sensible default are provided for otherwise -undefined variables. - - [% DEFAULT - title = 'Hello World' - bgcol = '#ffffff' - %] - <html> - <head> - <title>[% title %]</title> - </head> - - <body bgcolor="[% bgcol %]"> - - -=back - -=head2 Processing Other Template Files and Blocks - -=over 4 - - -=item INSERT - -The INSERT directive is used to insert the contents of an external file -at the current position. - - [% INSERT myfile %] - -No attempt to parse or process the file is made. The contents, -possibly including any embedded template directives, are inserted -intact. - -The filename specified should be relative to one of the INCLUDE_PATH -directories. Absolute (i.e. starting with C</>) and relative -(i.e. starting with C<.>) filenames may be used if the ABSOLUTE and -RELATIVE options are set, respectively. Both these options are -disabled by default. - - my $template = Template->new({ - INCLUDE_PATH => '/here:/there', - }); - - $template->process('myfile'); - -'myfile': - - [% INSERT foo %] # looks for /here/foo then /there/foo - [% INSERT /etc/passwd %] # file error: ABSOLUTE not set - [% INSERT ../secret %] # file error: RELATIVE not set - -For convenience, the filename does not need to be quoted as long as it -contains only alphanumeric characters, underscores, dots or forward -slashes. Names containing any other characters should be quoted. - - [% INSERT misc/legalese.txt %] - [% INSERT 'dos98/Program Files/stupid' %] - -To evaluate a variable to specify a filename, you should explicitly -prefix it with a '$' or use double-quoted string interpolation. - - [% language = 'en' - legalese = 'misc/legalese.txt' - %] - - [% INSERT $legalese %] # 'misc/legalese.txt' - [% INSERT "$language/$legalese" %] # 'en/misc/legalese.txt' - -Multiple files can be specified using '+' as a delimiter. All files -should be unquoted names or quoted strings. Any variables should be -interpolated into double-quoted strings. - - [% INSERT legalese.txt + warning.txt %] - [% INSERT "$legalese" + warning.txt %] # requires quoting - - - - - - - - - - - - - - - - - -=item INCLUDE - -The INCLUDE directive is used to process and include the output of -another template file or block. - - [% INCLUDE header %] - -If a BLOCK of the specified name is defined in the same file, or in a file -from which the current template has been called (i.e. a parent template) -then it will be used in preference to any file of the same name. - - [% INCLUDE table %] # uses BLOCK defined below - - [% BLOCK table %] - <table> - ... - </table> - [% END %] - -If a BLOCK definition is not currently visible then the template name -should be a file relative to one of the INCLUDE_PATH directories, or -an absolute or relative file name if the ABSOLUTE/RELATIVE options are -appropriately enabled. The INCLUDE directive automatically quotes the -filename specified, as per INSERT described above. When a variable -contains the name of the template for the INCLUDE directive, it should -be explicitly prefixed by '$' or double-quoted - - [% myheader = 'my/misc/header' %] - [% INCLUDE myheader %] # 'myheader' - [% INCLUDE $myheader %] # 'my/misc/header' - [% INCLUDE "$myheader" %] # 'my/misc/header' - -Any template directives embedded within the file will be processed -accordingly. All variables currently defined will be visible and -accessible from within the included template. - - [% title = 'Hello World' %] - [% INCLUDE header %] - <body> - ... - -'header': - - <html> - <title>[% title %]</title> - -output: - - <html> - <title>Hello World</title> - <body> - ... - -Local variable definitions may be specified after the template name, -temporarily masking any existing variables. Insignificant whitespace -is ignored within directives so you can add variable definitions on the -same line, the next line or split across several line with comments -interspersed, if you prefer. - - [% INCLUDE table %] - - [% INCLUDE table title="Active Projects" %] - - [% INCLUDE table - title = "Active Projects" - bgcolor = "#80ff00" # chartreuse - border = 2 - %] - -The INCLUDE directive localises (i.e. copies) all variables before -processing the template. Any changes made within the included -template will not affect variables in the including template. - - [% foo = 10 %] - - foo is originally [% foo %] - [% INCLUDE bar %] - foo is still [% foo %] - - [% BLOCK bar %] - foo was [% foo %] - [% foo = 20 %] - foo is now [% foo %] - [% END %] - -output: - foo is originally 10 - foo was 10 - foo is now 20 - foo is still 10 - -Technical Note: the localisation of the stash (that is, the process by -which variables are copied before an INCLUDE to prevent being -overwritten) is only skin deep. The top-level variable namespace -(hash) is copied, but no attempt is made to perform a deep-copy of -other structures (hashes, arrays, objects, etc.) Therefore, a 'foo' -variable referencing a hash will be copied to create a new 'foo' -variable but which points to the same hash array. Thus, if you update -compound variables (e.g. foo.bar) then you will change the original -copy, regardless of any stash localisation. If you're not worried -about preserving variable values, or you trust the templates you're -including then you might prefer to use the PROCESS directive which is -faster by virtue of not performing any localisation. - -From version 2.04 onwards, you can specify dotted variables as "local" -variables to an INCLUDE directive. However, be aware that because of -the localisation issues explained above (if you skipped the previous -Technical Note above then you might want to go back and read it or -skip this section too), the variables might not actualy be "local". -If the first element of the variable name already references a hash -array then the variable update will affect the original variable. - - [% foo = { - bar = 'Baz' - } - %] - - [% INCLUDE somefile foo.bar='Boz' %] - - [% foo.bar %] # Boz - -This behaviour can be a little unpredictable (and may well be improved -upon in a future version). If you know what you're doing with it and -you're sure that the variables in question are defined (nor not) as you -expect them to be, then you can rely on this feature to implement some -powerful "global" data sharing techniques. Otherwise, you might prefer -to steer well clear and always pass simple (undotted) variables as -parameters to INCLUDE and other similar directives. - -If you want to process several templates in one go then you can -specify each of their names (quoted or unquoted names only, no unquoted -'$variables') joined together by '+'. The INCLUDE directive -will then process them in order. - - [% INCLUDE html/header + "site/$header" + site/menu - title = "My Groovy Web Site" - %] - -The variable stash is localised once and then the templates specified -are processed in order, all within that same variable context. This -makes it slightly faster than specifying several separate INCLUDE -directives (because you only clone the variable stash once instead of -n times), but not quite as "safe" because any variable changes in the -first file will be visible in the second, third and so on. This -might be what you want, of course, but then again, it might not. - - - -=item PROCESS - -The PROCESS directive is similar to INCLUDE but does not perform any -localisation of variables before processing the template. Any changes -made to variables within the included template will be visible in the -including template. - - [% foo = 10 %] - - foo is [% foo %] - [% PROCESS bar %] - foo is [% foo %] - - [% BLOCK bar %] - [% foo = 20 %] - changed foo to [% foo %] - [% END %] - -output: - - foo is 10 - changed foo to 20 - foo is 20 - -Parameters may be specified in the PROCESS directive, but these too will -become visible changes to current variable values. - - [% foo = 10 %] - foo is [% foo %] - [% PROCESS bar - foo = 20 - %] - foo is [% foo %] - - [% BLOCK bar %] - this is bar, foo is [% foo %] - [% END %] - -output: - - foo is 10 - this is bar, foo is 20 - foo is 20 - -The PROCESS directive is slightly faster than INCLUDE because it -avoids the need to localise (i.e. copy) the variable stash before -processing the template. As with INSERT and INCLUDE, the first -parameter does not need to be quoted as long as it contains only -alphanumeric characters, underscores, periods or forward slashes. -A '$' prefix can be used to explicitly indicate a variable which -should be interpolated to provide the template name: - - [% myheader = 'my/misc/header' %] - [% PROCESS myheader %] # 'myheader' - [% PROCESS $myheader %] # 'my/misc/header' - -As with INCLUDE, multiple templates can be specified, delimited by -'+', and are processed in order. - - [% PROCESS html/header + my/header %] - - - - - -=item WRAPPER - -It's not unusual to find yourself adding common headers and footers to -pages or sub-sections within a page. Something like this: - - [% INCLUDE section/header - title = 'Quantum Mechanics' - %] - Quantum mechanics is a very interesting subject wish - should prove easy for the layman to fully comprehend. - [% INCLUDE section/footer %] - - [% INCLUDE section/header - title = 'Desktop Nuclear Fusion for under $50' - %] - This describes a simple device which generates significant - sustainable electrical power from common tap water by process - of nuclear fusion. - [% INCLUDE section/footer %] - -The individual template components being included might look like these: - -section/header: - - <p> - <h2>[% title %]</h2> - -section/footer: - - </p> - -The WRAPPER directive provides a way of simplifying this a little. It -encloses a block up to a matching END directive, which is first -processed to generate some output. This is then passed to the named -template file or BLOCK as the 'content' variable. - - [% WRAPPER section - title = 'Quantum Mechanics' - %] - Quantum mechanics is a very interesting subject wish - should prove easy for the layman to fully comprehend. - [% END %] - - [% WRAPPER section - title = 'Desktop Nuclear Fusion for under $50' - %] - This describes a simple device which generates significant - sustainable electrical power from common tap water by process - of nuclear fusion. - [% END %] - -The single 'section' template can then be defined as: - - <p> - <h2>[% title %]</h2> - [% content %] - </p> - -Like other block directives, it can be used in side-effect notation: - - [% INSERT legalese.txt WRAPPER big_bold_table %] - -It's also possible to specify multiple templates to a WRAPPER directive. -The specification order indicates outermost to innermost wrapper templates. -For example, given the following template block definitions: - - [% BLOCK bold %]<b>[% content %]</b>[% END %] - [% BLOCK italic %]<i>[% content %]</i>[% END %] - -the directive - - [% WRAPPER bold+italic %]Hello World[% END %] - -would generate the following output: - - <b><i>Hello World</i></b> - - - - - - - - - - - - - - - - - - -=item BLOCK - -The BLOCK ... END construct can be used to define template component -blocks which can be processed with the INCLUDE, PROCESS and WRAPPER -directives. - - [% BLOCK tabrow %] - <tr><td>[% name %]<td><td>[% email %]</td></tr> - [% END %] - - <table> - [% PROCESS tabrow name='Fred' email='fred@nowhere.com' %] - [% PROCESS tabrow name='Alan' email='alan@nowhere.com' %] - </table> - -A BLOCK definition can be used before it is defined, as long as the -definition resides in the same file. The block definition itself does -not generate any output. - - [% PROCESS tmpblk %] - - [% BLOCK tmpblk %] This is OK [% END %] - -You can use an anonymous BLOCK to capture the output of a template -fragment. - - [% julius = BLOCK %] - And Caesar's spirit, ranging for revenge, - With Ate by his side come hot from hell, - Shall in these confines with a monarch's voice - Cry 'Havoc', and let slip the dogs of war; - That this foul deed shall smell above the earth - With carrion men, groaning for burial. - [% END %] - -Like a named block, it can contain any other template directives which -are processed when the block is defined. The output generated by the -block is then assigned to the variable 'julius'. - -Anonymous BLOCKs can also be used to define block macros. The -enclosing block is processed each time the macro is called. - - [% MACRO locate BLOCK %] - The [% animal %] sat on the [% place %]. - [% END %] - - [% locate(animal='cat', place='mat') %] # The cat sat on the mat - [% locate(animal='dog', place='log') %] # The dog sat on the log - - - -=back - -=head2 Conditional Processing - -=over 4 - - -=item IF / UNLESS / ELSIF / ELSE - -The IF and UNLESS directives can be used to process or ignore a -block based on some run-time condition. - - [% IF frames %] - [% INCLUDE frameset %] - [% END %] - - [% UNLESS text_mode %] - [% INCLUDE biglogo %] - [% END %] - -Multiple conditions may be joined with ELSIF and/or ELSE blocks. - - [% IF age < 10 %] - Hello [% name %], does your mother know you're - using her AOL account? - [% ELSIF age < 18 %] - Sorry, you're not old enough to enter - (and too dumb to lie about your age) - [% ELSE %] - Welcome [% name %]. - [% END %] - -The following conditional and boolean operators may be used: - - == != < <= > >= && || ! and or not - -Note that C<and>, C<or> and C<not> are also provided as aliases for -C<&&>, C<||> and C<!>, respectively. - -Conditions may be arbitrarily complex and are evaluated with the same -precedence as in Perl. Parenthesis may be used to explicitly -determine evaluation order. - - # ridiculously contrived complex example - [% IF (name == 'admin' || uid <= 0) && mode == 'debug' %] - I'm confused. - [% ELSIF more > less %] - That's more or less correct. - [% END %] - - - - - - -=item SWITCH / CASE - -The SWITCH / CASE construct can be used to perform a multi-way -conditional test. The SWITCH directive expects an expression which is -first evaluated and then compared against each CASE statement in turn. -Each CASE directive should contain a single value or a list of values -which should match. CASE may also be left blank or written as [% CASE -DEFAULT %] to specify a default match. Only one CASE matches, there -is no drop-through between CASE statements. - - [% SWITCH myvar %] - [% CASE value1 %] - ... - [% CASE [ value2 value3 ] %] # multiple values - ... - [% CASE myhash.keys %] # ditto - ... - [% CASE %] # default - ... - [% END %] - - - - -=back - -=head2 Loop Processing - -=over 4 - - -=item FOREACH - -The FOREACH directive will iterate through the items in a list, processing -the enclosed block for each one. - - my $vars = { - foo => 'Foo', - items => [ 'one', 'two', 'three' ], - }; - -template: - - Things: - [% FOREACH thing = [ foo 'Bar' "$foo Baz" ] %] - * [% thing %] - [% END %] - - Items: - [% FOREACH i = items %] - * [% i %] - [% END %] - - Stuff: - [% stuff = [ foo "$foo Bar" ] %] - [% FOREACH s = stuff %] - * [% s %] - [% END %] - -output: - - Things: - * Foo - * Bar - * Foo Baz - - Items: - * one - * two - * three - - Stuff: - * Foo - * Foo Bar - -You can use also use 'IN' instead of '=' if you prefer. - - [% FOREACH crook IN government %] - -When the FOREACH directive is used without specifying a target variable, -any iterated values which are hash references will be automatically -imported. - - [% userlist = [ - { id => 'tom', name => 'Thomas' }, - { id => 'dick', name => 'Richard' }, - { id => 'larry', name => 'Lawrence' }, - ] - %] - - [% FOREACH user IN userlist %] - [% user.id %] [% user.name %] - [% END %] - -short form: - - [% FOREACH userlist %] - [% id %] [% name %] - [% END %] - -Note that this particular usage creates a localised variable context -to prevent the imported hash keys from overwriting any existing -variables. The imported definitions and any other variables defined -in such a FOREACH loop will be lost at the end of the loop, when the -previous context and variable values are restored. - -However, under normal operation, the loop variable remains in scope -after the FOREACH loop has ended (caveat: overwriting any variable -previously in scope). This is useful as the loop variable is secretly -an iterator object (see below) and can be used to analyse the last -entry processed by the loop. - -The FOREACH directive can also be used to iterate through the entries -in a hash array. Each entry in the hash is returned in sorted order -(based on the key) as a hash array containing 'key' and 'value' items. - - [% users = { - tom => 'Thomas', - dick => 'Richard', - larry => 'Lawrence', - } - %] - - [% FOREACH u IN users %] - * [% u.key %] : [% u.value %] - [% END %] - -Output: - - * dick : Richard - * larry : Lawrence - * tom : Thomas - -The NEXT directive starts the next iteration in the FOREACH loop. - - [% FOREACH user IN userlist %] - [% NEXT IF user.isguest %] - Name: [% user.name %] Email: [% user.email %] - [% END %] - -The LAST directive can be used to prematurely exit the loop. BREAK is -also provided as an alias for LAST. - - [% FOREACH match IN results.nsort('score').reverse %] - [% LAST IF match.score < 50 %] - [% match.score %] : [% match.url %] - [% END %] - -The FOREACH directive is implemented using the Template::Iterator -module. A reference to the iterator object for a FOREACH directive is -implicitly available in the 'loop' variable. The following methods -can be called on the 'loop' iterator. - - size() number of elements in the list - max() index number of last element (size - 1) - index() index of current iteration from 0 to max() - count() iteration counter from 1 to size() (i.e. index() + 1) - first() true if the current iteration is the first - last() true if the current iteration is the last - prev() return the previous item in the list - next() return the next item in the list - -See L<Template::Iterator> for further details. - -Example: - - [% FOREACH item IN [ 'foo', 'bar', 'baz' ] -%] - [%- "<ul>\n" IF loop.first %] - <li>[% loop.count %]/[% loop.size %]: [% item %] - [%- "</ul>\n" IF loop.last %] - [% END %] - -Output: - - <ul> - <li>1/3: foo - <li>2/3: bar - <li>3/3: baz - </ul> - -Note that the number() method is supported as an alias for count() for -backwards compatibility but may be deprecated in some future version. - -Nested loops will work as expected, with the 'loop' variable correctly -referencing the innermost loop and being restored to any previous -value (i.e. an outer loop) at the end of the loop. - - [% FOREACH group IN grouplist; - # loop => group iterator - "Groups:\n" IF loop.first; - - FOREACH user IN group.userlist; - # loop => user iterator - "$loop.count: $user.name\n"; - END; - - # loop => group iterator - "End of Groups\n" IF loop.last; - END - %] - -The 'iterator' plugin can also be used to explicitly create an -iterator object. This can be useful within nested loops where you -need to keep a reference to the outer iterator within the inner loop. -The iterator plugin effectively allows you to create an iterator by a -name other than 'loop'. See Template::Plugin::Iterator for further -details. - - [% USE giter = iterator(grouplist) %] - - [% FOREACH group IN giter %] - [% FOREACH user IN group.userlist %] - user #[% loop.count %] in - group [% giter.count %] is - named [% user.name %] - [% END %] - [% END %] - - - - -=item WHILE - -The WHILE directive can be used to repeatedly process a template block -while a conditional expression evaluates true. The expression may -be arbitrarily complex as per IF / UNLESS. - - [% WHILE total < 100 %] - ... - [% total = calculate_new_total %] - [% END %] - -An assignment can be enclosed in parenthesis to evaluate the assigned -value. - - [% WHILE (user = get_next_user_record) %] - [% user.name %] - [% END %] - -The NEXT directive can be used to start the next iteration of a -WHILE loop and BREAK can be used to exit the loop, both as per FOREACH. - -The Template Toolkit uses a failsafe counter to prevent runaway WHILE -loops which would otherwise never terminate. If the loop exceeds 1000 -iterations then an 'undef' exception will be thrown, reporting the -error: - - WHILE loop terminated (> 1000 iterations) - -The $Template::Directive::WHILE_MAX variable controls this behaviour -and can be set to a higher value if necessary. - - -=back - -=head2 Filters, Plugins, Macros and Perl - -=over 4 - - -=item FILTER - -The FILTER directive can be used to post-process the output of a -block. A number of standard filters are provided with the Template -Toolkit. The 'html' filter, for example, escapes the 'E<lt>', 'E<gt>' -and '&' characters to prevent them from being interpreted as HTML tags -or entity reference markers. - - [% FILTER html %] - HTML text may have < and > characters embedded - which you want converted to the correct HTML entities. - [% END %] - -output: - - HTML text may have < and > characters embedded - which you want converted to the correct HTML entities. - -The FILTER directive can also follow various other non-block directives. -For example: - - [% INCLUDE mytext FILTER html %] - -The '|' character can also be used as an alias for 'FILTER'. - - [% INCLUDE mytext | html %] - -Multiple filters can be chained together and will be called in sequence. - - [% INCLUDE mytext FILTER html FILTER html_para %] - -or - - [% INCLUDE mytext | html | html_para %] - -Filters come in two flavours, known as 'static' or 'dynamic'. A -static filter is a simple subroutine which accepts a text string as -the only argument and returns the modified text. The 'html' filter is -an example of a static filter, implemented as: - - sub html_filter { - my $text = shift; - for ($text) { - s/&/&/g; - s/</</g; - s/>/>/g; - } - return $text; - } - -Dynamic filters can accept arguments which are specified when the filter -is called from a template. The 'repeat' filter is such an example, -accepting a numerical argument which specifies the number of times -that the input text should be repeated. - - [% FILTER repeat(3) %]blah [% END %] - -output: - - blah blah blah - -These are implemented as filter 'factories'. The factory subroutine -is passed a reference to the current Template::Context object along -with any additional arguments specified. It should then return a -subroutine reference (e.g. a closure) which implements the filter. -The 'repeat' filter factory is implemented like this: - - sub repeat_filter_factory { - my ($context, $iter) = @_; - $iter = 1 unless defined $iter; - - return sub { - my $text = shift; - $text = '' unless defined $text; - return join('\n', $text) x $iter; - } - } - -The FILTERS option, described in L<Template::Manual::Config>, allows -custom filters to be defined when a Template object is instantiated. -The Template::Context define_filter() method allows further filters -to be defined at any time. - -When using a filter, it is possible to assign an alias to it for -further use. This is most useful for dynamic filters that you want -to re-use with the same configuration. - - [% FILTER echo = repeat(2) %] - Is there anybody out there? - [% END %] - - [% FILTER echo %] - Mother, should I build a wall? - [% END %] - -Output: - - Is there anybody out there? - Is there anybody out there? - - Mother, should I build a wall? - Mother, should I build a wall? - -The FILTER directive automatically quotes the name of the filter. As -with INCLUDE et al, you can use a variable to provide the name of the -filter, prefixed by '$'. - - [% myfilter = 'html' %] - [% FILTER $myfilter %] # same as [% FILTER html %] - ... - [% END %] - -A template variable can also be used to define a static filter -subroutine. However, the Template Toolkit will automatically call any -subroutine bound to a variable and use the value returned. Thus, the -above example could be implemented as: - - my $vars = { - myfilter => sub { return 'html' }, - }; - -template: - - [% FILTER $myfilter %] # same as [% FILTER html %] - ... - [% END %] - -To define a template variable that evaluates to a subroutine reference -that can be used by the FILTER directive, you should create a -subroutine that, when called automatically by the Template Toolkit, -returns another subroutine reference which can then be used to perform -the filter operation. Note that only static filters can be -implemented in this way. - - my $vars = { - myfilter => sub { \&my_filter_sub }, - }; - - sub my_filter_sub { - my $text = shift; - # do something - return $text; - } - -template: - - [% FILTER $myfilter %] - ... - [% END %] - -Alternately, you can bless a subroutine reference into a class (any -class will do) to fool the Template Toolkit into thinking it's an -object rather than a subroutine. This will then bypass the automatic -"call-a-subroutine-to-return-a-value" magic. - - my $vars = { - myfilter => bless(\&my_filter_sub, 'anything_you_like'), - }; - -template: - - [% FILTER $myfilter %] - ... - [% END %] - -Filters bound to template variables remain local to the variable -context in which they are defined. That is, if you define a filter in -a PERL block within a template that is loaded via INCLUDE, then the -filter definition will only exist until the end of that template when -the stash is delocalised, restoring the previous variable state. If -you want to define a filter which persists for the lifetime of the -processor, or define additional dynamic filter factories, then you can -call the define_filter() method on the current Template::Context -object. - -See L<Template::Manual::Filters> for a complete list of available filters, -their descriptions and examples of use. - - - - - - -=item USE - -The USE directive can be used to load and initialise "plugin" -extension modules. - - [% USE myplugin %] - -A plugin is a regular Perl module that conforms to a particular -object-oriented interface, allowing it to be loaded into and used -automatically by the Template Toolkit. For details of this interface -and information on writing plugins, consult L<Template::Plugin>. - -The plugin name is case-sensitive and will be appended to the -PLUGIN_BASE value (default: 'Template::Plugin') to construct a full -module name. Any periods, '.', in the name will be converted to '::'. - - [% USE MyPlugin %] # => Template::Plugin::MyPlugin - [% USE Foo.Bar %] # => Template::Plugin::Foo::Bar - -Various standard plugins are included with the Template Toolkit (see -below and L<Template::Manual::Plugins>). These can be specified in lower -case and are mapped to the appropriate name. - - [% USE cgi %] # => Template::Plugin::CGI - [% USE table %] # => Template::Plugin::Table - -Any additional parameters supplied in parenthesis after the plugin -name will be also be passed to the new() constructor. A reference to -the current Template::Context object is always passed as the first -parameter. - - [% USE MyPlugin('foo', 123) %] - -equivalent to: - - Template::Plugin::MyPlugin->new($context, 'foo', 123); - -Named parameters may also be specified. These are collated into a -hash which is passed by reference as the last parameter to the -constructor, as per the general code calling interface. - - [% USE url('/cgi-bin/foo', mode='submit', debug=1) %] - -equivalent to: - - Template::Plugin::URL->new($context, '/cgi-bin/foo' - { mode => 'submit', debug => 1 }); - -The plugin may represent any data type; a simple variable, hash, list or -code reference, but in the general case it will be an object reference. -Methods can be called on the object (or the relevant members of the -specific data type) in the usual way: - - [% USE table(mydata, rows=3) %] - - [% FOREACH row = table.rows %] - <tr> - [% FOREACH item = row %] - <td>[% item %]</td> - [% END %] - </tr> - [% END %] - -An alternative name may be provided for the plugin by which it can be -referenced: - - [% USE scores = table(myscores, cols=5) %] - - [% FOREACH row = scores.rows %] - ... - [% END %] - -You can use this approach to create multiple plugin objects with -different configurations. This example shows how the 'format' plugin -is used to create sub-routines bound to variables for formatting text -as per printf(). - - [% USE bold = format('<b>%s</b>') %] - [% USE ital = format('<i>%s</i>') %] - - [% bold('This is bold') %] - [% ital('This is italic') %] - -Output: - - <b>This is bold</b> - <i>This is italic</i> - -This next example shows how the URL plugin can be used to build -dynamic URLs from a base part and optional query parameters. - - [% USE mycgi = URL('/cgi-bin/foo.pl', debug=1) %] - <a href="[% mycgi %]">... - <a href="[% mycgi(mode='submit') %]"... - -Output: - - <a href="/cgi-bin/foo.pl?debug=1">... - <a href="/cgi-bin/foo.pl?mode=submit&debug=1">... - -The CGI plugin is an example of one which delegates to another Perl -module. In this this case, it is to Lincoln Stein's CGI.pm module. -All of the methods provided by CGI.pm are available via the plugin. - - [% USE CGI %] - - [% CGI.start_form %] - - [% CGI.checkbox_group(name => 'colours', - values => [ 'red' 'green' 'blue' ]) - %] - - [% CGI.popup_menu(name => 'items', - values => [ 'foo' 'bar' 'baz' ]) - %] - - [% CGI.end_form %] - -Simon Matthews has written the DBI plugin which provides an interface -to Tim Bunce's DBI module (available from CPAN). Here's a short -example: - - [% USE DBI('DBI:mSQL:mydbname') %] - - [% FOREACH user = DBI.query('SELECT * FROM users') %] - [% user.id %] [% user.name %] [% user.etc.etc %] - [% END %] - -See L<Template::Manual::Plugins> for more information on the plugins -distributed with the toolkit or available from CPAN. - -The LOAD_PERL option (disabled by default) provides a further way by -which external Perl modules may be loaded. If a regular Perl module -(i.e. not a Template::Plugin::* or other module relative to some -PLUGIN_BASE) supports an object-oriented interface and a new() -constructor then it can be loaded and instantiated automatically. The -following trivial example shows how the IO::File module might be used. - - [% USE file = IO.File('/tmp/mydata') %] - - [% WHILE (line = file.getline) %] - <!-- [% line %] --> - [% END %] - - - - - - -=item MACRO - -The MACRO directive allows you to define a directive or directive block -which is then evaluated each time the macro is called. - - [% MACRO header INCLUDE header %] - -Calling the macro as: - - [% header %] - -is then equivalent to: - - [% INCLUDE header %] - -Macros can be passed named parameters when called. These values remain -local to the macro. - - [% header(title='Hello World') %] - -equivalent to: - - [% INCLUDE header title='Hello World' %] - -A MACRO definition may include parameter names. Values passed to the -macros are then mapped to these local variables. Other named parameters -may follow these. - - [% MACRO header(title) INCLUDE header %] - - [% header('Hello World') %] - [% header('Hello World', bgcol='#123456') %] - -equivalent to: - - [% INCLUDE header title='Hello World' %] - [% INCLUDE header title='Hello World' bgcol='#123456' %] - -Here's another example, defining a macro for display numbers -in comma-delimited groups of 3, using the chunk and join virtual -method. - - [% MACRO number(n) GET n.chunk(-3).join(',') %] - - [% number(1234567) %] # 1,234,567 - -A MACRO may precede any directive and must conform to the structure -of the directive. - - [% MACRO header IF frames %] - [% INCLUDE frames/header %] - [% ELSE %] - [% INCLUDE header %] - [% END %] - - [% header %] - -A MACRO may also be defined as an anonymous BLOCK. The block will be -evaluated each time the macro is called. - - [% MACRO header BLOCK %] - ...content... - [% END %] - - [% header %] - -If you've got the EVAL_PERL option set, then you can even define a -MACRO as a PERL block (see below): - - [% MACRO triple(n) PERL %] - my $n = $stash->get('n'); - print $n * 3; - [% END -%] - - - - - - - -=item PERL - -(for the advanced reader) - -The PERL directive is used to mark the start of a block which contains -Perl code for evaluation. The EVAL_PERL option must be enabled for Perl -code to be evaluated or a 'perl' exception will be thrown with the -message 'EVAL_PERL not set'. - -Perl code is evaluated in the Template::Perl package. The $context -package variable contains a reference to the current Template::Context -object. This can be used to access the functionality of the Template -Toolkit to process other templates, load plugins, filters, etc. -See L<Template::Context> for further details. - - [% PERL %] - print $context->include('myfile'); - [% END %] - -The $stash variable contains a reference to the top-level stash object -which manages template variables. Through this, variable values can -be retrieved and updated. See L<Template::Stash> for further details. - - [% PERL %] - $stash->set(foo => 'bar'); - print "foo value: ", $stash->get('foo'); - [% END %] - -Output - foo value: bar - -Output is generated from the PERL block by calling print(). Note that -the Template::Perl::PERLOUT handle is selected (tied to an output -buffer) instead of STDOUT. - - [% PERL %] - print "foo\n"; # OK - print PERLOUT "bar\n"; # OK, same as above - print Template::Perl::PERLOUT "baz\n"; # OK, same as above - print STDOUT "qux\n"; # WRONG! - [% END %] - -The PERL block may contain other template directives. These are -processed before the Perl code is evaluated. - - [% name = 'Fred Smith' %] - - [% PERL %] - print "[% name %]\n"; - [% END %] - -Thus, the Perl code in the above example is evaluated as: - - print "Fred Smith\n"; - -Exceptions may be thrown from within PERL blocks via die() and will be -correctly caught by enclosing TRY blocks. - - [% TRY %] - [% PERL %] - die "nothing to live for\n"; - [% END %] - [% CATCH %] - error: [% error.info %] - [% END %] - -output: - error: nothing to live for - - - - -=item RAWPERL - -(for the very advanced reader) - -The Template Toolkit parser reads a source template and generates the -text of a Perl subroutine as output. It then uses eval() to evaluate -it into a subroutine reference. This subroutine is then called to -process the template, passing a reference to the current -Template::Context object through which the functionality of the -Template Toolkit can be accessed. The subroutine reference can be -cached, allowing the template to be processed repeatedly without -requiring any further parsing. - -For example, a template such as: - - [% PROCESS header %] - The [% animal %] sat on the [% location %] - [% PROCESS footer %] - -is converted into the following Perl subroutine definition: - - sub { - my $context = shift; - my $stash = $context->stash; - my $output = ''; - my $error; - - eval { BLOCK: { - $output .= $context->process('header'); - $output .= "The "; - $output .= $stash->get('animal'); - $output .= " sat on the "; - $output .= $stash->get('location'); - $output .= $context->process('footer'); - $output .= "\n"; - } }; - if ($@) { - $error = $context->catch($@, \$output); - die $error unless $error->type eq 'return'; - } - - return $output; - } - -To examine the Perl code generated, such as in the above example, set -the $Template::Parser::DEBUG package variable to any true value. You -can also set the $Template::Directive::PRETTY variable true to have -the code formatted in a readable manner for human consumption. The -source code for each generated template subroutine will be printed to -STDERR on compilation (i.e. the first time a template is used). - - $Template::Parser::DEBUG = 1; - $Template::Directive::PRETTY = 1; - - ... - - $template->process($file, $vars) - || die $template->error(), "\n"; - -The PERL ... END construct allows Perl code to be embedded into a -template (when the EVAL_PERL option is set), but it is evaluated at -"runtime" using eval() each time the template subroutine is called. -This is inherently flexible, but not as efficient as it could be, -especially in a persistent server environment where a template may be -processed many times. - -The RAWPERL directive allows you to write Perl code that is integrated -directly into the generated Perl subroutine text. It is evaluated -once at compile time and is stored in cached form as part of the -compiled template subroutine. This makes RAWPERL blocks more -efficient than PERL blocks. - -The downside is that you must code much closer to the metal. Within -PERL blocks, you can call print() to generate some output. RAWPERL -blocks don't afford such luxury. The code is inserted directly into -the generated subroutine text and should conform to the convention of -appending to the '$output' variable. - - [% PROCESS header %] - - [% RAWPERL %] - $output .= "Some output\n"; - ... - $output .= "Some more output\n"; - [% END %] - -The critical section of the generated subroutine for this example would -then look something like: - - ... - eval { BLOCK: { - $output .= $context->process('header'); - $output .= "\n"; - $output .= "Some output\n"; - ... - $output .= "Some more output\n"; - $output .= "\n"; - } }; - ... - -As with PERL blocks, the $context and $stash references are pre-defined -and available for use within RAWPERL code. - - -=back - -=head2 Exception Handling and Flow Control - -=over 4 - - -=item TRY / THROW / CATCH / FINAL - -(more advanced material) - -The Template Toolkit supports fully functional, nested exception -handling. The TRY directive introduces an exception handling scope -which continues until the matching END directive. Any errors that -occur within that block will be caught and can be handled by one -of the CATCH blocks defined. - - [% TRY %] - ...blah...blah... - [% CALL somecode %] - ...etc... - [% INCLUDE someblock %] - ...and so on... - [% CATCH %] - An error occurred! - [% END %] - -Errors are raised as exceptions (objects of the Template::Exception -class) and contain two fields, 'type' and 'info'. The exception -'type' can be any string containing letters, numbers, '_' or '.', and -is used to indicate the kind of error that occurred. The 'info' field -contains an error message indicating what actually went wrong. Within -a catch block, the exception object is aliased to the 'error' variable. -You can access the 'type' and 'info' fields directly. - - [% mydsn = 'dbi:MySQL:foobar' %] - ... - - [% TRY %] - [% USE DBI(mydsn) %] - [% CATCH %] - ERROR! Type: [% error.type %] - Info: [% error.info %] - [% END %] - -output (assuming a non-existant database called 'foobar'): - - ERROR! Type: DBI - Info: Unknown database "foobar" - -The 'error' variable can also be specified by itself and will return a -string of the form "$type error - $info". - - ... - [% CATCH %] - ERROR: [% error %] - [% END %] - -output: - - ERROR: DBI error - Unknown database "foobar" - -Each CATCH block may be specified with a particular exception type -denoting the kind of error that it should catch. Multiple CATCH -blocks can be provided to handle different types of exception that may -be thrown in the TRY block. A CATCH block specified without any type, -as in the previous example, is a default handler which will catch any -otherwise uncaught exceptions. This can also be specified as -[% CATCH DEFAULT %]. - - [% TRY %] - [% INCLUDE myfile %] - [% USE DBI(mydsn) %] - [% CALL somecode %] - ... - [% CATCH file %] - File Error! [% error.info %] - [% CATCH DBI %] - [% INCLUDE database/error.html %] - [% CATCH %] - [% error %] - [% END %] - -Remember that you can specify multiple directives within a single tag, -each delimited by ';'. Thus, you might prefer to write your simple -CATCH blocks more succinctly as: - - [% TRY %] - ... - [% CATCH file; "File Error! $error.info" %] - [% CATCH DBI; INCLUDE database/error.html %] - [% CATCH; error %] - [% END %] - -or even: - - [% TRY %] - ... - [% CATCH file ; - "File Error! $error.info" ; - CATCH DBI ; - INCLUDE database/error.html ; - CATCH ; - error ; - END - %] - -The DBI plugin throws exceptions of the 'DBI' type (in case that -wasn't already obvious). The other specific exception caught here is -of the 'file' type. - -A 'file' error is automatically thrown by the Template Toolkit when it -can't find a file, or fails to load, parse or process a file that has -been requested by an INCLUDE, PROCESS, INSERT or WRAPPER directive. -If 'myfile' can't be found in the example above, the [% INCLUDE myfile -%] directive will raise a 'file' exception which is then caught by the -[% CATCH file %] block, generating the output: - - File Error! myfile: not found - -Note that the DEFAULT option (disabled by default) allows you to -specify a default file to be used any time a template file can't be -found. This will prevent file exceptions from ever being raised when -a non-existant file is requested (unless, of course, the DEFAULT file -doesn't exist). Errors encountered once the file has been found -(i.e. read error, parse error) will be raised as file exceptions as per -usual. - -Uncaught exceptions (i.e. the TRY block doesn't have a type specific -or default CATCH handler) may be caught by enclosing TRY blocks which -can be nested indefinitely across multiple templates. If the error -isn't caught at any level then processing will stop and the Template -process() method will return a false value to the caller. The -relevant Template::Exception object can be retrieved by calling the -error() method. - - [% TRY %] - ... - [% TRY %] - [% INCLUDE $user.header %] - [% CATCH file %] - [% INCLUDE header %] - [% END %] - ... - [% CATCH DBI %] - [% INCLUDE database/error.html %] - [% END %] - -In this example, the inner TRY block is used to ensure that the first -INCLUDE directive works as expected. We're using a variable to -provide the name of the template we want to include, user.header, and -it's possible this contains the name of a non-existant template, or -perhaps one containing invalid template directives. If the INCLUDE fails - with a 'file' error then we CATCH it in the inner block and INCLUDE -the default 'header' file instead. Any DBI errors that occur within -the scope of the outer TRY block will be caught in the relevant CATCH -block, causing the 'database/error.html' template to be processed. -Note that included templates inherit all currently defined template -variable so these error files can quite happily access the 'error' -variable to retrieve information about the currently caught exception. -e.g. - -'database/error.html': - - <h2>Database Error</h2> - A database error has occurred: [% error.info %] - -You can also specify a FINAL block. This is always processed -regardless of the outcome of the TRY and/or CATCH block. If an -exception is uncaught then the FINAL block is processed before jumping -to the enclosing block or returning to the caller. - - [% TRY %] - ... - [% CATCH this %] - ... - [% CATCH that %] - ... - [% FINAL %] - All done! - [% END %] - -The output from the TRY block is left intact up to the point where an -exception occurs. For example, this template: - - [% TRY %] - This gets printed - [% THROW food 'carrots' %] - This doesn't - [% CATCH food %] - culinary delights: [% error.info %] - [% END %] - -generates the following output: - - This gets printed - culinary delights: carrots - -The CLEAR directive can be used in a CATCH or FINAL block to clear -any output created in the TRY block. - - [% TRY %] - This gets printed - [% THROW food 'carrots' %] - This doesn't - [% CATCH food %] - [% CLEAR %] - culinary delights: [% error.info %] - [% END %] - -output: - - culinary delights: carrots - -Exception types are hierarchical, with each level being separated by -the familiar dot operator. A 'DBI.connect' exception is a more -specific kind of 'DBI' error. Similarly, a 'myown.error.barf' is a -more specific kind of 'myown.error' type which itself is also a -'myown' error. A CATCH handler that specifies a general exception -type (such as 'DBI' or 'myown.error') will also catch more specific -types that have the same prefix as long as a more specific handler -isn't defined. Note that the order in which CATCH handlers are -defined is irrelevant; a more specific handler will always catch an -exception in preference to a more generic or default one. - - [% TRY %] - ... - [% CATCH DBI ; - INCLUDE database/error.html ; - CATCH DBI.connect ; - INCLUDE database/connect.html ; - CATCH ; - INCLUDE error.html ; - END - %] - -In this example, a 'DBI.connect' error has it's own handler, a more -general 'DBI' block is used for all other DBI or DBI.* errors and a -default handler catches everything else. - -Exceptions can be raised in a template using the THROW directive. The -first parameter is the exception type which doesn't need to be quoted -(but can be, it's the same as INCLUDE) followed by the relevant error -message which can be any regular value such as a quoted string, -variable, etc. - - [% THROW food "Missing ingredients: $recipe.error" %] - - [% THROW user.login 'no user id: please login' %] - - [% THROW $myerror.type "My Error: $myerror.info" %] - -It's also possible to specify additional positional or named -parameters to the THROW directive if you want to pass more than -just a simple message back as the error info field. - - [% THROW food 'eggs' 'flour' msg='Missing Ingredients' %] - -In this case, the error 'info' field will be a hash array containing -the named arguments, in this case 'msg' =E<gt> 'Missing Ingredients', -and an 'args' item which contains a list of the positional arguments, -in this case 'eggs' and 'flour'. The error 'type' field remains -unchanged, here set to 'food'. - - [% CATCH food %] - [% error.info.msg %] - [% FOREACH item = error.info.args %] - * [% item %] - [% END %] - [% END %] - -This produces the output: - - Missing Ingredients - * eggs - * flour - -In addition to specifying individual positional arguments as -[% error.info.args.n %], the 'info' hash contains keys directly -pointing to the positional arguments, as a convenient shortcut. - - [% error.info.0 %] # same as [% error.info.args.0 %] - -Exceptions can also be thrown from Perl code which you've bound to -template variables, or defined as a plugin or other extension. To -raise an exception, call die() passing a reference to a -Template::Exception object as the argument. This will then be caught -by any enclosing TRY blocks from where the code was called. - - use Template::Exception; - ... - - my $vars = { - foo => sub { - # ... do something ... - die Template::Exception->new('myerr.naughty', - 'Bad, bad error'); - }, - }; - -template: - - [% TRY %] - ... - [% foo %] - ... - [% CATCH myerr ; - "Error: $error" ; - END - %] - -output: - - Error: myerr.naughty error - Bad, bad error - -The 'info' field can also be a reference to another object or data -structure, if required. - - die Template::Exception->new('myerror', { - module => 'foo.pl', - errors => [ 'bad permissions', 'naughty boy' ], - }); - -Later, in a template: - - [% TRY %] - ... - [% CATCH myerror %] - [% error.info.errors.size or 'no'; - error.info.errors.size == 1 ? ' error' : ' errors' %] - in [% error.info.module %]: - [% error.info.errors.join(', ') %]. - [% END %] - -Generating the output: - - 2 errors in foo.pl: - bad permissions, naughty boy. - -You can also call die() with a single string, as is common in much -existing Perl code. This will automatically be converted to an -exception of the 'undef' type (that's the literal string 'undef', -not the undefined value). If the string isn't terminated with a -newline then Perl will append the familiar " at $file line $line" -message. - - sub foo { - # ... do something ... - die "I'm sorry, Dave, I can't do that\n"; - } - -If you're writing a plugin, or some extension code that has the -current Template::Context in scope (you can safely skip this section -if this means nothing to you) then you can also raise an exception by -calling the context throw() method. You can pass it an -Template::Exception object reference, a pair of ($type, $info) parameters -or just an $info string to create an exception of 'undef' type. - - $context->throw($e); # exception object - $context->throw('Denied'); # 'undef' type - $context->throw('user.passwd', 'Bad Password'); - - - - - - - -=item NEXT - -The NEXT directive can be used to start the next iteration of a FOREACH -or WHILE loop. - - [% FOREACH user = userlist %] - [% NEXT IF user.isguest %] - Name: [% user.name %] Email: [% user.email %] - [% END %] - - - - - -=item LAST - -The LAST directive can be used to prematurely exit a FOREACH or WHILE -loop. - - [% FOREACH user = userlist %] - Name: [% user.name %] Email: [% user.email %] - [% LAST IF some.condition %] - [% END %] - -BREAK can also be used as an alias for LAST. - - - - -=item RETURN - -The RETURN directive can be used to stop processing the current -template and return to the template from which it was called, resuming -processing at the point immediately after the INCLUDE, PROCESS or -WRAPPER directive. If there is no enclosing template then the -Template process() method will return to the calling code with a -true value. - - Before - [% INCLUDE half_wit %] - After - - [% BLOCK half_wit %] - This is just half... - [% RETURN %] - ...a complete block - [% END %] - -output: - - Before - This is just half... - After - - - - -=item STOP - -The STOP directive can be used to indicate that the processor should -stop gracefully without processing any more of the template document. -This is a planned stop and the Template process() method will return a -B<true> value to the caller. This indicates that the template was -processed successfully according to the directives within it. - - [% IF something.terrible.happened %] - [% INCLUDE fatal/error.html %] - [% STOP %] - [% END %] - - [% TRY %] - [% USE DBI(mydsn) %] - ... - [% CATCH DBI.connect %] - <p>Cannot connect to the database: [% error.info %]</p> - <br> - We apologise for the inconvenience. The cleaning lady - has removed the server power to plug in her vacuum cleaner. - Please try again later. - </p> - [% INCLUDE footer %] - [% STOP %] - [% END %] - - - - -=item CLEAR - -The CLEAR directive can be used to clear the output buffer for the current -enclosing block. It is most commonly used to clear the output generated -from a TRY block up to the point where the error occurred. - - [% TRY %] - blah blah blah # this is normally left intact - [% THROW some 'error' %] # up to the point of error - ... - [% CATCH %] - [% CLEAR %] # clear the TRY output - [% error %] # print error string - [% END %] - - - - -=back - -=head2 Miscellaneous - -=over 4 - - -=item META - -The META directive allows simple metadata items to be defined within a -template. These are evaluated when the template is parsed and as such -may only contain simple values (e.g. it's not possible to interpolate -other variables values into META variables). - - [% META - title = 'The Cat in the Hat' - author = 'Dr. Seuss' - version = 1.23 - %] - -The 'template' variable contains a reference to the main template -being processed. These metadata items may be retrieved as attributes -of the template. - - <h1>[% template.title %]</h1> - <h2>[% template.author %]</h2> - -The 'name' and 'modtime' metadata items are automatically defined for -each template to contain its name and modification time in seconds -since the epoch. - - [% USE date %] # use Date plugin to format time - ... - [% template.name %] last modified - at [% date.format(template.modtime) %] - -The PRE_PROCESS and POST_PROCESS options allow common headers and -footers to be added to all templates. The 'template' reference is -correctly defined when these templates are processed, allowing headers -and footers to reference metadata items from the main template. - - $template = Template->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - }); - - $template->process('cat_in_hat'); - -header: - - <html> - <head> - <title>[% template.title %]</title> - </head> - <body> - -cat_in_hat: - - [% META - title = 'The Cat in the Hat' - author = 'Dr. Seuss' - version = 1.23 - year = 2000 - %] - - The cat in the hat sat on the mat. - -footer: - - <hr> - © [% template.year %] [% template.author %] - </body> - </html> - -The output generated from the above example is: - - <html> - <head> - <title>The Cat in the Hat</title> - </head> - <body> - - The cat in the hat sat on the mat. - - <hr> - © 2000 Dr. Seuss - </body> - </html> - - - -=item TAGS - -The TAGS directive can be used to set the START_TAG and END_TAG values -on a per-template file basis. - - [% TAGS <+ +> %] - - <+ INCLUDE header +> - -The TAGS directive may also be used to set a named TAG_STYLE - - [% TAGS html %] - <!-- INCLUDE header --> - -See the TAGS and TAG_STYLE configuration options for further details. - - - - - - - - -=item DEBUG - -The DEBUG directive can be used to enable or disable directive debug -messages within a template. The DEBUG configuration option must be -set to include DEBUG_DIRS for the DEBUG directives to have any effect. -If DEBUG_DIRS is not set then the parser will automatically ignore and -remove any DEBUG directives. - -The DEBUG directive can be used with an 'on' or 'off' parameter to -enable or disable directive debugging messages from that point -forward. When enabled, the output of each directive in the generated -output will be prefixed by a comment indicate the file, line and -original directive text. - - [% DEBUG on %] - directive debugging is on (assuming DEBUG option is set true) - [% DEBUG off %] - directive debugging is off - -The 'format' parameter can be used to change the format of the debugging -message. - - [% DEBUG format '<!-- $file line $line : [% $text %] -->' %] - - - - - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Filters.pod b/lib/Template/Manual/Filters.pod deleted file mode 100644 index c42f2ef..0000000 --- a/lib/Template/Manual/Filters.pod +++ /dev/null @@ -1,529 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Filters -# -# DESCRIPTION -# This section lists all the standard filters distributed with the -# Template Toolkit for post-processing output. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Filters - Standard filters - -=head1 DESCRIPTION - -This section lists all the standard filters distributed with the -Template Toolkit for post-processing output. - -=head1 STANDARD FILTERS - - - -=head2 format(format) - -The 'format' filter takes a format string as a parameter (as per -printf()) and formats each line of text accordingly. - - [% FILTER format('<!-- %-40s -->') %] - This is a block of text filtered - through the above format. - [% END %] - -output: - - <!-- This is a block of text filtered --> - <!-- through the above format. --> - -=head2 upper - -Folds the input to UPPER CASE. - - [% "hello world" FILTER upper %] - -output: - - HELLO WORLD - -=head2 lower - -Folds the input to lower case. - - [% "Hello World" FILTER lower %] - -output: - - hello world - -=head2 ucfirst - -Folds the first character of the input to UPPER CASE. - - [% "hello" FILTER ucfirst %] - -output: - - Hello - -=head2 lcfirst - -Folds the first character of the input to lower case. - - [% "HELLO" FILTER lcfirst %] - -output: - - hELLO - -=head2 trim - -Trims any leading or trailing whitespace from the input text. Particularly -useful in conjunction with INCLUDE, PROCESS, etc., having the same effect -as the TRIM configuration option. - - [% INCLUDE myfile | trim %] - -=head2 collapse - -Collapse any whitespace sequences in the input text into a single space. -Leading and trailing whitespace (which would be reduced to a single space) -is removed, as per trim. - - [% FILTER collapse %] - - The cat - - sat on - - the mat - - [% END %] - -output: - - The cat sat on the mat - -=head2 html - -Converts the characters 'E<lt>', 'E<gt>' and '&' to '<', '>' and -'&', respectively, protecting them from being interpreted as -representing HTML tags or entities. - - [% FILTER html %] - Binary "<=>" returns -1, 0, or 1 depending on... - [% END %] - -output: - - Binary "<=>" returns -1, 0, or 1 depending on... - -=head2 html_entity - -The html filter is fast and simple but it doesn't encode the full -range of HTML entities that your text may contain. The html_entity -filter uses either the Apache::Util module (which is written in C and -is therefore faster) or the HTML::Entities module (written in Perl but -equally as comprehensive) to perform the encoding. If one or other of -these modules are installed on your system then the text will be -encoded (via the escape_html() or encode_entities() subroutines -respectively) to convert all extended characters into their -appropriate HTML entities (e.g. converting 'é' to 'é'). If -neither module is available on your system then an 'html_entity' exception -will be thrown reporting an appropriate message. - -For further information on HTML entity encoding, see -http://www.w3.org/TR/REC-html40/sgml/entities.html. - -=head2 html_para - -This filter formats a block of text into HTML paragraphs. A sequence of -two or more newlines is used as the delimiter for paragraphs which are -then wrapped in HTML E<lt>pE<gt>...E<lt>/pE<gt> tags. - - [% FILTER html_para %] - The cat sat on the mat. - - Mary had a little lamb. - [% END %] - -output: - - <p> - The cat sat on the mat. - </p> - - <p> - Mary had a little lamb. - </p> - -=head2 html_break / html_para_break - -Similar to the html_para filter described above, but uses the HTML tag -sequence E<lt>brE<gt>E<lt>brE<gt> to join paragraphs. - - [% FILTER html_break %] - The cat sat on the mat. - - Mary had a little lamb. - [% END %] - -output: - - The cat sat on the mat. - <br> - <br> - Mary had a little lamb. - -=head2 html_line_break - -This filter replaces any newlines with E<lt>brE<gt> HTML tags, -thus preserving the line breaks of the original text in the -HTML output. - - [% FILTER html_line_break %] - The cat sat on the mat. - Mary had a little lamb. - [% END %] - -output: - - The cat sat on the mat.<br> - Mary had a little lamb.<br> - -=head2 uri - -This filter URI escapes the input text, converting any characters -outside of the permitted URI character set (as defined by RFC 2396) -into a C<%nn> hex escape. - - [% 'my file.html' | uri %] - -output: - - my%20file.html - -Note that URI escaping isn't always enough when generating hyperlinks in -an HTML document. The C<&> character, for example, is valid in a URI and -will not be escaped by the URI filter. In this case you should also filter -the text through the 'html' filter. - - <a href="[% filename | uri | html %]">click here</a> - -=head2 indent(pad) - -Indents the text block by a fixed pad string or width. The 'pad' argument -can be specified as a string, or as a numerical value to indicate a pad -width (spaces). Defaults to 4 spaces if unspecified. - - [% FILTER indent('ME> ') %] - blah blah blah - cabbages, rhubard, onions - [% END %] - -output: - - ME> blah blah blah - ME> cabbages, rhubard, onions - -=head2 truncate(length) - -Truncates the text block to the length specified, or a default length of -32. Truncated text will be terminated with '...' (i.e. the '...' falls -inside the required length, rather than appending to it). - - [% FILTER truncate(21) %] - I have much to say on this matter that has previously - been said on more than one occasion. - [% END %] - -output: - - I have much to say... - -=head2 repeat(iterations) - -Repeats the text block for as many iterations as are specified (default: 1). - - [% FILTER repeat(3) %] - We want more beer and we want more beer, - [% END %] - We are the more beer wanters! - -output: - - We want more beer and we want more beer, - We want more beer and we want more beer, - We want more beer and we want more beer, - We are the more beer wanters! - -=head2 remove(string) - -Searches the input text for any occurrences of the specified string and -removes them. A Perl regular expression may be specified as the search -string. - - [% "The cat sat on the mat" FILTER remove('\s+') %] - -output: - - Thecatsatonthemat - -=head2 replace(search, replace) - -Similar to the remove filter described above, but taking a second parameter -which is used as a replacement string for instances of the search string. - - [% "The cat sat on the mat" | replace('\s+', '_') %] - -output: - - The_cat_sat_on_the_mat - -=head2 redirect(file, options) - -The 'redirect' filter redirects the output of the block into a separate -file, specified relative to the OUTPUT_PATH configuration item. - - [% FOREACH user = myorg.userlist %] - [% FILTER redirect("users/${user.id}.html") %] - [% INCLUDE userinfo %] - [% END %] - [% END %] - -or more succinctly, using side-effect notation: - - [% INCLUDE userinfo - FILTER redirect("users/${user.id}.html") - FOREACH user = myorg.userlist - %] - -A 'file' exception will be thrown if the OUTPUT_PATH option is undefined. - -An optional 'binmode' argument can follow the filename to explicitly set -the output file to binary mode. - - [% PROCESS my/png/generator - FILTER redirect("images/logo.png", binmode=1) %] - -For backwards compatibility with earlier versions, a single true/false -value can be used to set binary mode. - - [% PROCESS my/png/generator - FILTER redirect("images/logo.png", 1) %] - -For the sake of future compatibility and clarity, if nothing else, we -would strongly recommend you explicitly use the named 'binmode' option -as shown in the first example. - -=head2 eval / evaltt - -The 'eval' filter evaluates the block as template text, processing -any directives embedded within it. This allows template variables to -contain template fragments, or for some method to be provided for -returning template fragments from an external source such as a -database, which can then be processed in the template as required. - - my $vars = { - fragment => "The cat sat on the [% place %]", - }; - $template->process($file, $vars); - -The following example: - - [% fragment | eval %] - -is therefore equivalent to - - The cat sat on the [% place %] - -The 'evaltt' filter is provided as an alias for 'eval'. - -=head2 perl / evalperl - -The 'perl' filter evaluates the block as Perl code. The EVAL_PERL -option must be set to a true value or a 'perl' exception will be -thrown. - - [% my_perl_code | perl %] - -In most cases, the [% PERL %] ... [% END %] block should suffice for -evaluating Perl code, given that template directives are processed -before being evaluate as Perl. Thus, the previous example could have -been written in the more verbose form: - - [% PERL %] - [% my_perl_code %] - [% END %] - -as well as - - [% FILTER perl %] - [% my_perl_code %] - [% END %] - -The 'evalperl' filter is provided as an alias for 'perl' for backwards -compatibility. - -=head2 stdout(options) - -The stdout filter prints the output generated by the enclosing block to -STDOUT. The 'binmode' option can be passed as either a named parameter -or a single argument to set STDOUT to binary mode (see the -binmode perl function). - - [% PROCESS something/cool - FILTER stdout(binmode=1) # recommended %] - - [% PROCESS something/cool - FILTER stdout(1) # alternate %] - -The stdout filter can be used to force binmode on STDOUT, or also inside -redirect, null or stderr blocks to make sure that particular output goes -to stdout. See the null filter below for an example. - -=head2 stderr - -The stderr filter prints the output generated by the enclosing block to -STDERR. - -=head2 null - -The null filter prints nothing. This is useful for plugins whose -methods return values that you don't want to appear in the output. -Rather than assigning every plugin method call to a dummy variable -to silence it, you can wrap the block in a null filter: - - [% FILTER null; - USE im = GD.Image(100,100); - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0, 255); - im.arc(50,50,95,75,0,360,blue); - im.fill(50,50,red); - im.png | stdout(1); - END; - -%] - -Notice the use of the stdout filter to ensure that a particular expression -generates output to stdout (in this case in binary mode). - -=head2 latex(outputType) - -Passes the text block to LaTeX and produces either PDF, DVI or -PostScript output. The 'outputType' argument determines the output -format and it should be set to one of the strings: "pdf" (default), -"dvi", or "ps". - -The text block should be a complete LaTeX source file. - - [% FILTER latex("pdf") -%] - \documentclass{article} - - \begin{document} - - \title{A Sample TT2 \LaTeX\ Source File} - \author{Craig Barratt} - \maketitle - - \section{Introduction} - This is some text. - - \end{document} - [% END -%] - -The output will be a PDF file. You should be careful not to prepend or -append any extraneous characters or text outside the FILTER block, -since this text will wrap the (binary) output of the latex filter. -Notice the END directive uses '-%]' for the END_TAG to remove the -trailing new line. - -One example where you might prepend text is in a CGI script where -you might include the Content-Type before the latex output, eg: - - Content-Type: application/pdf - - [% FILTER latex("pdf") -%] - \documentclass{article} - \begin{document} - ... - \end{document} - [% END -%] - -In other cases you might use the redirect filter to put the output -into a file, rather than delivering it to stdout. This might be -suitable for batch scripts: - - [% output = FILTER latex("pdf") -%] - \documentclass{article} - \begin{document} - ... - \end{document} - [% END; output | redirect("document.pdf", 1) -%] - -(Notice the second argument to redirect to force binary mode.) - -Note that the latex filter runs one or two external programs, so it -isn't very fast. But for modest documents the performance is adequate, -even for interactive applications. - -A error of type 'latex' will be thrown if there is an error reported -by latex, pdflatex or dvips. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Internals.pod b/lib/Template/Manual/Internals.pod deleted file mode 100644 index b8cf80b..0000000 --- a/lib/Template/Manual/Internals.pod +++ /dev/null @@ -1,556 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Internals -# -# DESCRIPTION -# This document provides an overview of the internal architecture of -# the Template Toolkit. It is a work in progress and is far from -# complete, currently providing little more than an overview of how -# the major components fit together. Nevertheless, it's a good -# starting point for anyone wishing to delve into the source code to -# find out how it all works. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Internals - Template Toolkit internals - -=head1 DESCRIPTION - -This document provides an overview of the internal architecture of the -Template Toolkit. It is a work in progress and is far from complete, -currently providing little more than an overview of how the major -components fit together. Nevertheless, it's a good starting point for -anyone wishing to delve into the source code to find out how it all -works. - -=head2 Outside Looking In - -The B<Template> module is simply a front end module which creates and -uses a Template::Service and pipes the output wherever you want it to -go (STDOUT by default, or maybe a file, scalar, etc). The -Apache::Template module (available separately from CPAN) is another -front end. That creates a Template::Service::Apache object, calls on -it as required and sends the output back to the relevant -Apache::Request object. - -These front-end modules are really only there to handle any specifics -of the environment in which they're being used. The Apache::Template -front end, for example, handles Apache::Request specifics and -configuration via the httpd.conf. The regular Template front-end -deals with STDOUT, variable refs, etc. Otherwise it is -Template::Service (or subclass) which does all the work. - -The B<Template::Service> module provides a high-quality template -delivery service, with bells, whistles, signed up service level -agreement and a 30-day no quibble money back guarantee. "Have -a good time, all the time", that's our motto. - -Within the lower levels of the Template Toolkit, there are lots of -messy details that we generally don't want to have to worry about most -of the time. Things like templates not being found, or failing to -parse correctly, uncaught exceptions being thrown, missing plugin -modules or dependencies, and so on. Template::Service hides that all -away and makes everything look simple to the outsider. It provides -extra features, like PRE_PROCESS, PROCESS and POST_PROCESS, and also -provides the error recovery mechanism via ERROR. You ask it to -process a template and it takes care of everything for you. The -Template::Service::Apache module goes a little bit further, adding -some extra headers to the Apache::Request, setting a few extra template -variables, and so on. - -For the most part, the job of a service is really just one of -scheduling and dispatching. It receives a request in the form of a -call to its process() method and schedules the named template -specified as an argument, and possibly several other templates -(PRE_PROCESS, etc) to be processed in order. It doesn't actually -process the templates itself, but instead makes a process() call -against a Template::Context object. - -B<Template::Context> is the runtime engine for the Template Toolkit - -the module that hangs everything together in the lower levels of the -Template Toolkit and that one that does most of the real work, albeit -by crafty delegation to various other friendly helper modules. - -Given a template name (or perhaps a reference to a scalar or file -handle) the context process() method must load and compile, or fetch a -cached copy of a previously compiled template, corresponding to that -name. It does this by calling on a list of one or more -Template::Provider objects (the LOAD_TEMPLATES posse) who themselves -might get involved with a Template::Parser to help turn source -templates into executable Perl code (but more on that later). Thankfully, -all of this complexity is hidden away behind a simple template() -method. You call it passing a template name as an argument, and it -returns a compiled template in the form of a Template::Document -object, or otherwise raises an exception. - -A B<Template::Document> is a thin object wrapper around a compiled -template subroutine. The object implements a process() method which -performs a little bit of housekeeping and then calls the template -subroutine. The object also defines template metadata (defined in -C<[% META ... %]> directives) and has a block() method which returns -a hash of any additional C<[% BLOCK xxxx %]> definitions found in the -template source. - -So the context fetches a compiled document via its own template() -method and then gets ready to process it. It first updates the stash -(the place where template variables get defined - more on that -shortly) to set any template variable definitions specified as the -second argument by reference to hash array. Then, it calls the -document process() method, passing a reference to itself, the context -object, as an argument. In doing this, it provides itself as an -object against which template code can make callbacks to access -runtime resources and Template Toolkit functionality. - -What we're trying to say here is this: not only does the Template::Context -object receive calls from the I<outside>, i.e. those originating in user -code calling the process() method on a Template object, but it also -receives calls from the I<inside>, i.e. those originating in template -directives of the form C<[% PROCESS template %]>. - -Before we move on to that, here's a simple structure diagram showing -the outer layers of the Template Toolkit heading inwards, with pseudo -code annotations showing a typical invocation sequence. - - ,--------. - | Caller | use Template; - `--------' my $tt = Template->new( ... ); - | $tt->process($template, \%vars); - | Outside - - - - - | - - - - - - - - - - - - - - - - - - - - - - - - - - - - T T - | package Template; Inside - V - +----------+ sub process($template, \%vars) { - | Template | $out = $self->SERVICE->process($template, $vars); - +----------+ print $out or send it to $self->OUTPUT; - | } - | - | package Template::Service; - | - | sub process($template, \%vars) { - | try { - +----------+ foreach $p in @self->PRE_PROCESS - | Service | $self->CONTEXT->process($p, $vars); - +----------+ - | $self->CONTEXT->process($template, $vars); - | - | foreach $p @self->POST_PROCESS - | $self->CONTEXT->process($p, $vars); - | } - | catch { - | $self->CONTEXT->process($self->ERROR); - | } - | } - | - V package Template::Context; - +----------+ - | Context | sub process($template, \%vars) { - +----------+ # fetch compiled template - | $template = $self->template($template) - | # update stash - | $self->STASH->update($vars); - | # process template - | $template->process($self) - | } - V - +----------+ package Template::Document; - | Document | - +----------+ sub process($context) { - $output = &{ $self->BLOCK }($context); - } - - -=head2 Inside Looking Out - -To understand more about what's going on in these lower levels, we -need to look at what a compiled template looks like. In fact, a -compiled template is just a regular Perl sub-routine. Here's a very -simple one. - - sub my_compiled_template { - return "This is a compiled template.\n"; - } - -You're unlikely to see a compiled template this simple unless you -wrote it yourself but it is entirely valid. All a template subroutine -is obliged to do is return some output (which may be an empty of -course). If it can't for some reason, then it should raise an error -via die(). - - sub my_todo_template { - die "This template not yet implemented\n"; - } - -If it wants to get fancy, it can raise an error as a -Template::Exception object. An exception object is really just a -convenient wrapper for the 'type' and 'info' fields. - - sub my_solilique_template { - die (Template::Exception->new('yorrick', 'Fellow of infinite jest')); - } - -Templates generally need to do a lot more than just generate static -output or raise errors. They may want to inspect variable values, -process another template, load a plugin, run a filter, and so on. -Whenever a template subroutine is called, it gets passed a reference -to a Template::Context object. It is through this context object that -template code can access the features of the Template Toolkit. - -We described earlier how the Template::Service object calls on -Template::Context to handle a process() request from the I<outside>. -We can make a similar request on a context to process a template, but -from within the code of another template. This is a call from the -I<inside>. - - sub my_process_template { - my $context = shift; - - my $output = $context->process('header', { title => 'Hello World' }) - . "\nsome content\n" - . $context->process('footer'); - } - -This is then roughly equivalent to a source template something -like this: - - [% PROCESS header - title = 'Hello World' - %] - some content - [% PROCESS footer %] - -Template variables are stored in, and managed by a B<Template::Stash> -object. This is a blessed hash array in which template variables are -defined. The object wrapper provides get() and set() method which -implement all the magical.variable.features of the Template Toolkit. - -Each context object has its own stash, a reference to which can be -returned by the appropriately named stash() method. So to print the -value of some template variable, or for example, to represent the -following source template: - - <title>[% title %]</title> - -we might have a subroutine definition something like this: - - sub { - my $context = shift; - my $stash = $context->stash(); - return '<title>' . $stash->get('title') . '</title>'; - } - -The stash get() method hides the details of the underlying variable -types, automatically calling code references, checking return values, -and performing other such tricks. If 'title' happens to be bound to a -subroutine then we can specify additional parameters as a list -reference passed as the second argument to get(). - - [% title('The Cat Sat on the Mat') %] - -This translates to the stash get() call: - - $stash->get([ 'title', ['The Cat Sat on the Mat'] ]); - -Dotted compound variables can be requested by passing a single -list reference to the get() method in place of the variable -name. Each pair of elements in the list should correspond to the -variable name and reference to a list of arguments for each -dot-delimited element of the variable. - - [% foo(1, 2).bar(3, 4).baz(5) %] - -is thus equivalent to - - $stash->get([ foo => [1,2], bar => [3,4], baz => [5] ]); - -If there aren't any arguments for an element, you can specify an -empty, zero or null argument list. - - [% foo.bar %] - $stash->get([ 'foo', 0, 'bar', 0 ]); - -The set() method works in a similar way. It takes a variable -name and a variable value which should be assigned to it. - - [% x = 10 %] - $stash->set('x', 10); - - [% x.y = 10 %] - $stash->set([ 'x', 0, 'y', 0 ], 10); - -So the stash gives us access to template variables and the context -provides the higher level functionality. Alongside the process() -method lies the include() method. Just as with the PROCESS / INCLUDE -directives, the key difference is in variable localisation. Before -processing a template, the process() method simply updates the stash -to set any new variable definitions, overwriting any existing values. -In contrast, the include() method creates a copy of the existing -stash, in a process known as I<cloning> the stash, and then uses that -as a temporary variable store. Any previously existing variables are -still defined, but any changes made to variables, including setting -the new variable values passed aas arguments will affect only the -local copy of the stash (although note that it's only a shallow copy, -so it's not foolproof). When the template has been processed, the include() -method restores the previous variable state by I<decloning> the stash. - -The context also provides an insert() method to implement the INSERT -directive, but no wrapper() method. This functionality can be implemented -by rewriting the Perl code and calling include(). - - [% WRAPPER foo -%] - blah blah [% x %] - [%- END %] - - $context->include('foo', { - content => 'blah blah ' . $stash->get('x'), - }); - -Other than the template processing methods process(), include() and insert(), -the context defines methods for fetching plugin objects, plugin(), and -filters, filter(). - - [% USE foo = Bar(10) %] - - $stash->set('foo', $context->plugin('Bar', [10])); - - [% FILTER bar(20) %] - blah blah blah - [% END %] - - my $filter = $context->filter('bar', [20]); - &$filter('blah blah blah'); - -Pretty much everything else you might want to do in a template can be done -in Perl code. Things like IF, UNLESS, FOREACH and so on all have direct -counterparts in Perl. - - [% IF msg %] - Message: [% msg %] - [% END %]; - - if ($stash->get('msg')) { - $output .= 'Message: '; - $output .= $stash->get('msg'); - } - -The best way to get a better understanding of what's going on underneath -the hood is to set the C<$Template::Parser::DEBUG> flag to a true value -and start processing templates. This will cause the parser to print the -generated Perl code for each template it compiles to STDERR. You'll -probably also want to set the C<$Template::Directive::PRETTY> option to -have the Perl pretty-printed for human consumption. - - use Template; - use Template::Parser; - use Template::Directive; - - $Template::Parser::DEBUG = 1; - $Template::Directive::PRETTY = 1; - - my $template = Template->new(); - $template->process(\*DATA, { cat => 'dog', mat => 'log' }); - - __DATA__ - The [% cat %] sat on the [% mat %] - -The output sent to STDOUT remains as you would expect: - - The dog sat on the log - -The output sent to STDERR would look something like this: - - compiled main template document block: - sub { - my $context = shift || die "template sub called without context\n"; - my $stash = $context->stash; - my $output = ''; - my $error; - - eval { BLOCK: { - $output .= "The "; - $output .= $stash->get('cat'); - $output .= " sat on the "; - $output .= $stash->get('mat'); - $output .= "\n"; - } }; - if ($@) { - $error = $context->catch($@, \$output); - die $error unless $error->type eq 'return'; - } - - return $output; - } - - -=head1 HACKING ON THE TEMPLATE TOOLKIT - -Please feel free to hack on the Template Toolkit. If you find a bug -that needs fixing, if you have an idea for something that's missing, -or you feel inclined to tackle something on the TODO list, then by all -means go ahead and do it! - -If you're contemplating something non-trivial then you'll probably -want to bring it up on the mailing list first to get an idea about the -current state of play, find out if anyone's already working on it, and -so on. - -When you start to hack on the Template Toolkit, please make sure you -start from the latest developer release. Stable releases are uploaded -to CPAN and have all-numerical version numbers, e.g. 2.04, 2.05. -Developer releases are available from the Template Toolkit web site -and have a character suffix on the version, e.g. 2.04a, 2.04b, etc. - -Once you've made your changes, please remember to update the test -suite by adding extra tests to one of the existing test scripts in -the 't' sub-directory, or by adding a new test script of your own. -And of course, run C<make test> to ensure that all the tests pass -with your new code. - -Don't forget that any files you do add will need to be added to the -MANIFEST. Running 'make manifest' will do this for you, but you need -to make sure you haven't got any other temporary files lying around -that might also get added to it. - -Documentation is often something that gets overlooked but it's just -as important as the code. If you're updating existing documentation -then you should download the 'docsrc' bundle from which all the -Template Toolkit documentation is built and make your changes in there. -It's also available from the Template Toolkit web site. See the -README distributed in the archive for further information. - -If you're adding a new module, a plugin module, for example, then it's -OK to include the POD documentation in with the module, but I<please> -write it all in one piece at the end of the file, I<after> the code -(just look at any other Template::* module for an example). It's a -religious issue, I know, but I have a strong distaste for POD documentation -interspersed throughout the code. In my not-so-humble opinion, it makes -both the code and the documentation harder to read (same kinda problem -as embedding Perl in HTML). - -Aesthetics aside, if I do want to extract the documentation into the -docsrc bundle then it's easy for me to do it if it's all written in -one chunk and extremely tedious if not. So for practical reasons -alone, please keep Perl and POD sections separate. Comment blocks -within the code are of course welcome. - -To share your changes with the rest of the world, you'll need to -prepare a patch file. To do this you should have 2 directories -side-by-side, one which is the original, unmodified distribution -directory for the latest developer release, and the other is a -copy of that same directory which includes your changes. - -The following example shows a typical hacking session. First we -unpack the latest developer release. - - $ tar zxf Template-Toolkit-2.05c.tar.gz - -At this point, it's a good idea to rename the directory to give -some indicate of what it contains. - - $ mv Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack - -Then go hack! - - $ cd Template-Toolkit-2.05c-abw-xyz-hack - - [ hacking ] - - $ cd .. - -When you're all done and ready to prepare a patch, unpack the -distribution archive again so that you've got the original to -diff against your new code. - - $ tar zxf Template-Toolkit-2.05c.tar.gz - -You should now have an original distribution directory and a modified -version of that same directory, side-by-side. - - $ ls - Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack - -Now run diff and save the output into an appropriately named patch -file. - - $ diff -Naur Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack > patch-TT205c-abw-xyz-hack - -You can then post the generated patch file to the mailing list, -describing what it does, why it does it, how it does it and any -other relevant information. - -If you want to apply someone else's patch then you should start with the -same original distribution source on which the patch is based. From within -the root of the distribution, run 'patch' feeding in the patch file as -standard input. The 'p1' option is required to strip the first element -of the path name (e.g. Template-Toolkit-2.05c/README becomes README which -is then the correct path). - - $ tar zxf Template-Toolkit-2.05c.tar.gz - $ cd Template-Toolkit-2.05c - $ patch -p1 < ../patch-TT205c-abw-xyz-hack - -The output generated by 'patch' should be something like the following: - - patching file README - patching file lib/Template.pm - patching file lib/Template/Provider.pm - patching file t/provider.t - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Intro.pod b/lib/Template/Manual/Intro.pod deleted file mode 100644 index c50c9e8..0000000 --- a/lib/Template/Manual/Intro.pod +++ /dev/null @@ -1,295 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Intro -# -# DESCRIPTION -# This section provides a general introduction to the Template -# Toolkit, giving a quick overview of features, examples of template -# directives and use of the Template.pm module. It also described the -# basic concept underlying the toolkit: the separation of -# presentation elements from application logic and data. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Intro - Introduction to the Template Toolkit - -=head1 DESCRIPTION - -This section provides a general introduction to the Template Toolkit, -giving a quick overview of features, examples of template directives -and use of the Template.pm module. It also described the basic concept -underlying the toolkit: the separation of presentation elements from -application logic and data. - -The Template Toolkit is a collection of modules which implement a -fast, flexible, powerful and extensible template processing system. -It was originally designed and remains primarily useful for generating -dynamic web content, but it can be used equally well for processing -any kind of text documents. This POD documentation is all generated -using the Template Toolkit batch mode utility F<ttree>, for example. - -At the simplest level it provides an easy way to process template -files, filling in embedded variable references with their equivalent -values. - - Dear [% name %], - - It has come to our attention that your account is in - arrears to the sum of [% debt %]. - - Please settle your account before [% deadline %] or we - will be forced to revoke your Licence to Thrill. - - The Management. - -By default, template directives are embedded within the character -sequences '[%' ... '%]' but you can change these and various other -options to configure how the Template Toolkit looks, feels and works. -You can set the INTERPOLATE option, for example, if you prefer to -embed your variables in Perl style: - - Dear $name, - - It has come to our attention that your account is in - arrears to the sum of $debt. - ... - -=head2 Template.pm - -The Template.pm module is the front end to the Template Toolkit, -providing access to the full range of functionality through a single -module with a simple interface. It loads the other modules as -required and instantiates a default set of objects to handle -subsequent template processing requests. Configuration parameters may -be passed to the Template.pm constructor, new(), which are then used -to configure the underlying objects. - - use Template; - - my $tt = Template->new({ - INCLUDE_PATH => '/usr/local/templates', - INTERPOLATE => 1, - }) || die "$Template::ERROR\n"; - -The Template object implements a process() method for processing template -files or text. The name of the input template (or various other sources) -is passed as the first argument, followed by a reference to a hash array -of variable definitions for substitution in the template. - - my $vars = { - name => 'Count Edward van Halen', - debt => '3 riffs and a solo', - deadline => 'the next chorus', - }; - - $tt->process('letters/overdrawn', $vars) - || die $tt->error(), "\n"; - - -The process() method returns true (1) on success and prints the -template output to STDOUT, by default. On error, the process() method -returns false (undef). The error() method can then be called to -retrieve details of the error. - -=head2 Component Based Content Construction - -A number of special directives are provided, such as INSERT, INCLUDE -and PROCESS, which allow content to be built up from smaller template -components. This permits a modular approach to building a web site or -other content repository, promoting reusability, cross-site -consistency, ease of construction and subsequent maintenance. Common -elements such as headers, footers, menu bars, tables, and so on, can -be created as separate template files which can then be processed into -other documents as required. All defined variables are inherited by -these templates along with any additional "local" values specified. - - [% PROCESS header - title = "The Cat Sat on the Mat" - %] - - [% PROCESS menu %] - - The location of the missing feline has now been established. - Thank you for your assistance. - - [% INSERT legal/disclaimer %] - - [% PROCESS footer %] - -You can also define a template as a BLOCK within the same file and -PROCESS it just like any other template file. This can be invaluable -for building up repetitive elements such as tables, menus, etc. - - [% BLOCK tabrow %] - <tr><td>[% name %]</td><td>[% email %]</td></tr> - [% END %] - - <table> - [% PROCESS tabrow name="tom" email="tom@here.org" %] - [% PROCESS tabrow name="dick" email="disk@there.org" %] - [% PROCESS tabrow name="larry" email="larry@where.org" %] - </table> - -=head2 Data and Code Binding - -One of the key features that sets the Template Toolkit apart from -other template processors is the ability to bind template variables to -any kind of Perl data: scalars, lists, hash arrays, sub-routines and -objects. - - my $vars = { - root => 'http://here.com/there', - menu => [ 'modules', 'authors', 'scripts' ], - client => { - name => 'Doctor Joseph von Satriani', - id => 'JVSAT', - }, - checkout => sub { my $total = shift; ...; return $something }, - shopcart => My::Cool::Shopping::Cart->new(), - }; - -The Template Toolkit will automatically Do The Right Thing to access -the data in an appropriate manner to return some value which can then -be output. The dot operator '.' is used to access into lists and -hashes or to call object methods. The FOREACH directive is provided for -iterating through lists, and various logical tests are available using -directives such as IF, UNLESS, ELSIF, ELSE, SWITCH, CASE, etc. - - [% FOREACH section = menu %] - <a href="[% root %]/[% section %]/index.html">[% section %]</a> - [% END %] - - <b>Client</a>: [% client.name %] (id: [% client.id %]) - - [% IF shopcart.nitems %] - Your shopping cart contains the following items: - <ul> - [% FOREACH item = shopcart.contents %] - <li>[% item.name %] : [% item.qty %] @ [% item.price %] - [% END %] - </ul> - - [% checkout(shopcart.total) %] - - [% ELSE %] - No items currently in shopping cart. - [% END %] - -=head2 Advanced Features: Filters, Macros, Exceptions, Plugins - -The Template Toolkit also provides a number of additional directives -for advanced processing and programmatical functionality. It supports -output filters (FILTER), allows custom macros to be defined (MACRO), -has a fully-featured exception handling system (TRY, THROW, CATCH, -FINAL) and supports a plugin architecture (USE) which allows special -plugin modules and even regular Perl modules to be loaded and used -with the minimum of fuss. The Template Toolkit is "just" a template -processor but you can trivially extend it to incorporate the -functionality of any Perl module you can get your hands on. Thus, it -is also a scalable and extensible template framework, ideally suited -for managing the presentation layer for application servers, content -management systems and other web applications. - -=head2 Separating Presentation and Application Logic - -Rather than embedding Perl code or some other scripting language -directly into template documents, it encourages you to keep functional -components (i.e. Perl code) separate from presentation components -(e.g. HTML templates). The template variables provide the interface -between the two layers, allowing data to be generated in code and then -passed to a template component for displaying (pipeline model) or for -sub-routine or object references to be bound to variables which can -then be called from the template as and when required (callback -model). - -The directives that the Template Toolkit provide implement their own -mini programming language, but they're not really designed for -serious, general purpose programming. Perl is a far more appropriate -language for that. If you embed application logic (e.g. Perl or other -scripting language fragments) in HTML templates then you risk losing -the clear separation of concerns between functionality and -presentation. It becomes harder to maintain the two elements in -isolation and more difficult, if not impossible, to reuse code or -presentation elements by themselves. It is far better to write your -application code in separate Perl modules, libraries or scripts and -then use templates to control how the resulting data is presented as -output. Thus you should think of the Template Toolkit language as a -set of layout directives for displaying data, not calculating it. - -Having said that, the Template Toolkit doesn't force you into one -approach or the other. It attempts to be pragmatic rather than -dogmatic in allowing you to do whatever best gets the job done. -Thus, if you enable the EVAL_PERL option then you can happily embed -real Perl code in your templates within PERL ... END directives. - -=head2 Performance - -The Template Toolkit uses a fast YACC-like parser which compiles -templates into Perl code for maximum runtime efficiency. It also has -an advanced caching mechanism which manages in-memory and on-disk -(i.e. persistent) versions of compiled templates. The modules that -comprise the toolkit are highly configurable and the architecture -around which they're built is designed to be extensible. The Template -Toolkit provides a powerful framework around which content creation -and delivery systems can be built while also providing a simple -interface through the Template front-end module for general use. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Plugins.pod b/lib/Template/Manual/Plugins.pod deleted file mode 100644 index 7955640..0000000 --- a/lib/Template/Manual/Plugins.pod +++ /dev/null @@ -1,552 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Plugins -# -# DESCRIPTION -# This section lists the standard plugins which can be used to extend -# the runtime functionality of the Template Toolkit. The plugins are -# distributed with the Template Toolkit but may required additional -# modules from CPAN. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Plugins - Standard plugins - -=head1 DESCRIPTION - -This section lists the standard plugins which can be used to extend the -runtime functionality of the Template Toolkit. The plugins are -distributed with the Template Toolkit but may required additional -modules from CPAN. - - - -=head1 TEMPLATE TOOLKIT PLUGINS - -The following plugin modules are distributed with the Template -Toolkit. Some of the plugins interface to external modules (detailed -below) which should be downloaded from any CPAN site and installed -before using the plugin. - -=head2 Autoformat - -The Autoformat plugin is an interface to Damian Conway's Text::Autoformat -Perl module which provides advanced text wrapping and formatting. See -L<Template::Plugin::Autoformat> and L<Text::Autoformat> for further -details. - - [% USE autoformat(left=10, right=20) %] - [% autoformat(mytext) %] # call autoformat sub - [% mytext FILTER autoformat %] # or use autoformat filter - -The Text::Autoformat module is available from CPAN: - - http://www.cpan.org/modules/by-module/Text/ - -=head2 CGI - -The CGI plugin is a wrapper around Lincoln Stein's -E<lt>lstein@genome.wi.mit.eduE<gt> CGI.pm module. The plugin is -distributed with the Template Toolkit (see L<Template::Plugin::CGI>) -and the CGI module itself is distributed with recent versions Perl, -or is available from CPAN. - - [% USE CGI %] - [% CGI.param('param_name') %] - [% CGI.start_form %] - [% CGI.popup_menu( Name => 'color', - Values => [ 'Green', 'Brown' ] ) %] - [% CGI.end_form %] - -=head2 Datafile - -Provides an interface to data stored in a plain text file in a simple -delimited format. The first line in the file specifies field names -which should be delimiter by any non-word character sequence. -Subsequent lines define data using the same delimiter as int he first -line. Blank lines and comments (lines starting '#') are ignored. See -L<Template::Plugin::Datafile> for further details. - -/tmp/mydata: - - # define names for each field - id : email : name : tel - # here's the data - fred : fred@here.com : Fred Smith : 555-1234 - bill : bill@here.com : Bill White : 555-5678 - -example: - - [% USE userlist = datafile('/tmp/mydata') %] - - [% FOREACH user = userlist %] - [% user.name %] ([% user.id %]) - [% END %] - -=head2 Date - -The Date plugin provides an easy way to generate formatted time and date -strings by delegating to the POSIX strftime() routine. See -L<Template::Plugin::Date> and L<POSIX> for further details. - - [% USE date %] - [% date.format %] # current time/date - - File last modified: [% date.format(template.modtime) %] - -=head2 Directory - -The Directory plugin provides a simple interface to a directory and -the files within it. See L<Template::Plugin::Directory> for further -details. - - [% USE dir = Directory('/tmp') %] - [% FOREACH file = dir.files %] - # all the plain files in the directory - [% END %] - [% FOREACH file = dir.dirs %] - # all the sub-directories - [% END %] - -=head2 DBI - -The DBI plugin, developed by Simon Matthews -E<lt>sam@knowledgepool.comE<gt>, brings the full power of Tim Bunce's -E<lt>Tim.Bunce@ig.co.ukE<gt> database interface module (DBI) to your -templates. See L<Template::Plugin::DBI> and L<DBI> for further details. - - [% USE DBI('dbi:driver:database', 'user', 'pass') %] - - [% FOREACH user = DBI.query( 'SELECT * FROM users' ) %] - [% user.id %] [% user.name %] - [% END %] - -The DBI and relevant DBD modules are available from CPAN: - - http://www.cpan.org/modules/by-module/DBI/ - -=head2 Dumper - -The Dumper plugin provides an interface to the Data::Dumper module. See -L<Template::Plugin::Dumper> and L<Data::Dumper> for futher details. - - [% USE dumper(indent=0, pad="<br>") %] - [% dumper.dump(myvar, yourvar) %] - -=head2 File - -The File plugin provides a general abstraction for files and can be -used to fetch information about specific files within a filesystem. -See L<Template::Plugin::File> for further details. - - [% USE File('/tmp/foo.html') %] - [% File.name %] # foo.html - [% File.dir %] # /tmp - [% File.mtime %] # modification time - -=head2 Filter - -This module implements a base class plugin which can be subclassed -to easily create your own modules that define and install new filters. - - 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 %] - -See L<Template::Plugin::Filter> for further details. - -=head2 Format - -The Format plugin provides a simple way to format text according to a -printf()-like format. See L<Template::Plugin::Format> for further -details. - - [% USE bold = format('<b>%s</b>') %] - [% bold('Hello') %] - -=head2 GD::Image, GD::Polygon, GD::Constants - -These plugins provide access to the GD graphics library via Lincoln -D. Stein's GD.pm interface. These plugins allow PNG, JPEG and other -graphical formats to be generated. - - [% FILTER null; - USE im = GD.Image(100,100); - # allocate some colors - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0, 255); - # Draw a blue oval - im.arc(50,50,95,75,0,360,blue); - # And fill it with red - im.fill(50,50,red); - # Output image in PNG format - im.png | stdout(1); - END; - -%] - -See L<Template::Plugin::GD::Image> for further details. - -=head2 GD::Text, GD::Text::Align, GD::Text::Wrap - -These plugins provide access to Martien Verbruggen's GD::Text, -GD::Text::Align and GD::Text::Wrap modules. These plugins allow the -layout, alignment and wrapping of text when drawing text in GD images. - - [% FILTER null; - USE gd = GD.Image(200,400); - USE gdc = GD.Constants; - black = gd.colorAllocate(0, 0, 0); - green = gd.colorAllocate(0, 255, 0); - txt = "This is some long text. " | repeat(10); - USE wrapbox = GD.Text.Wrap(gd, - line_space => 4, - color => green, - text => txt, - ); - wrapbox.set_font(gdc.gdMediumBoldFont); - wrapbox.set(align => 'center', width => 160); - wrapbox.draw(20, 20); - gd.png | stdout(1); - END; - -%] - -See L<Template::Plugin::GD::Text>, L<Template::Plugin::GD::Text::Align> -and L<Template::Plugin::GD::Text::Wrap> for further details. - -=head2 GD::Graph::lines, GD::Graph::bars, GD::Graph::points, GD::Graph::linespoin -ts, GD::Graph::area, GD::Graph::mixed, GD::Graph::pie - -These plugins provide access to Martien Verbruggen's GD::Graph module -that allows graphs, plots and charts to be created. These plugins allow -graphs, plots and charts to be generated in PNG, JPEG and other -graphical formats. - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th"], - [ 4, 2, 3, 4, 3, 3.5] - ]; - USE my_graph = GD.Graph.pie(250, 200); - my_graph.set( - title => 'A Pie Chart', - label => 'Label', - axislabelclr => 'black', - pie_height => 36, - transparent => 0, - ); - my_graph.plot(data).png | stdout(1); - END; - -%] - -See -L<Template::Plugin::GD::Graph::lines>, -L<Template::Plugin::GD::Graph::bars>, -L<Template::Plugin::GD::Graph::points>, -L<Template::Plugin::GD::Graph::linespoints>, -L<Template::Plugin::GD::Graph::area>, -L<Template::Plugin::GD::Graph::mixed>, -L<Template::Plugin::GD::Graph::pie>, and -L<GD::Graph>, -for more details. - -=head2 GD::Graph::bars3d, GD::Graph::lines3d, GD::Graph::pie3d - -These plugins provide access to Jeremy Wadsack's GD::Graph3d -module. This allows 3D bar charts and 3D lines plots to -be generated. - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 1, 2, 5, 6, 3, 1.5, 1, 3, 4], - ]; - USE my_graph = GD.Graph.bars3d(); - my_graph.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'A 3d Bar Chart', - y_max_value => 8, - y_tick_number => 8, - y_label_skip => 2, - # shadows - bar_spacing => 8, - shadow_depth => 4, - shadowclr => 'dred', - transparent => 0, - my_graph.plot(data).png | stdout(1); - END; - -%] - -See -L<Template::Plugin::GD::Graph::lines3d>, -L<Template::Plugin::GD::Graph::bars3d>, and -L<Template::Plugin::GD::Graph::pie3d> -for more details. - -=head2 HTML - -The HTML plugin is very new and very basic, implementing a few useful -methods for generating HTML. It is likely to be extended in the future -or integrated with a larger project to generate HTML elements in a generic -way (as discussed recently on the mod_perl mailing list). - - [% USE HTML %] - [% HTML.escape("if (a < b && c > d) ..." %] - [% HTML.attributes(border => 1, cellpadding => 2) %] - [% HTML.element(table => { border => 1, cellpadding => 2 }) %] - -See L<Template::Plugin::HTML> for further details. - -=head2 Iterator - -The Iterator plugin provides a way to create a Template::Iterator -object to iterate over a data set. An iterator is created -automatically by the FOREACH directive and is aliased to the 'loop' -variable. This plugin allows an iterator to be explicitly created -with a given name, or the default plugin name, 'iterator'. See -L<Template::Plugin::Iterator> for further details. - - [% USE iterator(list, args) %] - - [% FOREACH item = iterator %] - [% '<ul>' IF iterator.first %] - <li>[% item %] - [% '</ul>' IF iterator.last %] - [% END %] - -=head2 Pod - -This plugin provides an interface to the L<Pod::POM|Pod::POM> module -which parses POD documents into an internal object model which can -then be traversed and presented through the Template Toolkit. - - [% USE Pod(podfile) %] - - [% FOREACH head1 = Pod.head1; - FOREACH head2 = head1/head2; - ... - END; - END - %] - -=head2 String - -The String plugin implements an object-oriented interface for -manipulating strings. See L<Template::Plugin::String> for further -details. - - [% USE String 'Hello' %] - [% String.append(' World') %] - - [% msg = String.new('Another string') %] - [% msg.replace('string', 'text') %] - - The string "[% msg %]" is [% msg.length %] characters long. - -=head2 Table - -The Table plugin allows you to format a list of data items into a -virtual table by specifying a fixed number of rows or columns, with -an optional overlap. See L<Template::Plugin::Table> for further -details. - - [% USE table(list, rows=10, overlap=1) %] - - [% FOREACH item = table.col(3) %] - [% item %] - [% END %] - -=head2 URL - -The URL plugin provides a simple way of contructing URLs from a base -part and a variable set of parameters. See L<Template::Plugin::URL> -for further details. - - [% USE mycgi = url('/cgi-bin/bar.pl', debug=1) %] - - [% mycgi %] - # ==> /cgi/bin/bar.pl?debug=1 - - [% mycgi(mode='submit') %] - # ==> /cgi/bin/bar.pl?mode=submit&debug=1 - -=head2 Wrap - -The Wrap plugin uses the Text::Wrap module by David Muir Sharnoff -E<lt>muir@idiom.comE<gt> (with help from Tim Pierce and many many others) -to provide simple paragraph formatting. See L<Template::Plugin::Wrap> -and L<Text::Wrap> for further details. - - [% USE wrap %] - [% wrap(mytext, 40, '* ', ' ') %] # use wrap sub - [% mytext FILTER wrap(40) -%] # or wrap FILTER - -The Text::Wrap module is available from CPAN: - - http://www.cpan.org/modules/by-module/Text/ - -=head2 XML::DOM - -The XML::DOM plugin gives access to the XML Document Object Module via -Clark Cooper E<lt>cooper@sch.ge.comE<gt> and Enno Derksen's -E<lt>enno@att.comE<gt> XML::DOM module. See L<Template::Plugin::XML::DOM> -and L<XML::DOM> for further details. - - [% USE dom = XML.DOM %] - [% doc = dom.parse(filename) %] - - [% FOREACH node = doc.getElementsByTagName('CODEBASE') %] - * [% node.getAttribute('href') %] - [% END %] - -The plugin requires the XML::DOM module, available from CPAN: - - http://www.cpan.org/modules/by-module/XML/ - -=head2 XML::RSS - -The XML::RSS plugin is a simple interface to Jonathan Eisenzopf's -E<lt>eisen@pobox.comE<gt> XML::RSS module. A RSS (Rich Site Summary) -file is typically used to store short news 'headlines' describing -different links within a site. This plugin allows you to parse RSS -files and format the contents accordingly using templates. -See L<Template::Plugin::XML::RSS> and L<XML::RSS> for further details. - - [% USE news = XML.RSS(filename) %] - - [% FOREACH item = news.items %] - <a href="[% item.link %]">[% item.title %]</a> - [% END %] - -The XML::RSS module is available from CPAN: - - http://www.cpan.org/modules/by-module/XML/ - -=head2 XML::Simple - -This plugin implements an interface to the L<XML::Simple|XML::Simple> -module. - - [% USE xml = XML.Simple(xml_file_or_text) %] - - [% xml.head.title %] - -See L<Template::Plugin::XML::Simple> for further details. - -=head2 XML::Style - -This plugin defines a filter for performing simple stylesheet based -transformations of XML text. - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - cellspacing = 1 - } - } - %] - - [% FILTER xmlstyle %] - <table> - <tr> - <td>Foo</td> <td>Bar</td> <td>Baz</td> - </tr> - </table> - [% END %] - -See L<Template::Plugin::XML::Style> for further details. - -=head2 XML::XPath - -The XML::XPath plugin provides an interface to Matt Sergeant's -E<lt>matt@sergeant.orgE<gt> XML::XPath module. See -L<Template::Plugin::XML::XPath> and L<XML::XPath> for further details. - - [% USE xpath = XML.XPath(xmlfile) %] - [% FOREACH page = xpath.findnodes('/html/body/page') %] - [% page.getAttribute('title') %] - [% END %] - -The plugin requires the XML::XPath module, available from CPAN: - - http://www.cpan.org/modules/by-module/XML/ - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Refs.pod b/lib/Template/Manual/Refs.pod deleted file mode 100644 index b0c9719..0000000 --- a/lib/Template/Manual/Refs.pod +++ /dev/null @@ -1,171 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Refs -# -# DESCRIPTION -# This section provides references to external modules, projects and -# other resources related to the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Refs - Related modules, projects and other resources - -=head1 DESCRIPTION - -This section provides references to external modules, projects and -other resources related to the Template Toolkit. - -=head2 Resources - -The Template Toolkit web site contains the latest information, news and -other resources. - - http://www.template-toolkit.org/ - -A mailing list exists for up-to-date information on the Template Toolkit -and for following and contributing to the development process. To -subscribe, send an email to - - templates-request@template-toolkit.org - -with the message 'subscribe' in the body. You can also use the web -interface to subscribe or browse the archives: - - http://www.template-toolkit.org/mailman/listinfo/templates - -The F<tpage> and F<ttree> scripts are distributed and installed along -with the Template Toolkit. The F<tpage> script simply processes named -files or STDIN if unspecified, using a default Template object. The -F<ttree> script can be used to process entire directory trees of templates, -allowing large content systems such as web sites to be rebuilt from a -single command or configuration file. - - perldoc tpage - perldoc ttree - -The F<Template::Tutorial> document provides an introduction to the Template -Toolkit and shows some typical examples of usage. - - perldoc Template::Tutorial - -You may also like to consult the paper 'Building and Managing Web Systems -with the Template Toolkit' and accompanying slides from the presentation -at the 4th Perl Conference. These are available from the Template -Toolkit web site: - - http://www.template-toolkit.org/docs.html - - - -=head2 Projects - -There are a number of other projects related to the Template Toolkit. - -=over 4 - -=item OpenInteract - -OpenInteract is a robust web application framework built to run under -Apache and mod_perl using the Template Toolkit as a foundation. - - http://www.openinteract.org/ - -=item Apache::Template - -This is an Apache/mod_perl interface to the Template Toolkit. Available -from CPAN in the directory: - - http://www.cpan.org/modules/by-module/Apache/ - -=item AxKit::Template - -AxKit is Matt Sergeant's Apache XML Delivery Toolkit. AxKit::Template -provides an interface between AxKit and the Template Toolkit. Available -from CPAN in the directory: - - http://www.cpan.org/modules/by-module/Apache/ - -=item Slashcode - -Slashcode is the code which runs Slashdot. Version 2 uses the -Template Toolkit for generating the user interface from database -driven template. - - http://slashcode.org/ - -=item OpenFrame - -OpenFrame is an open source application framework for distributed -media applications. It ships with a generator for the Template -Toolkit. - - http://openframe.fotango.com/ - -=item PCMT - -PCMT is the Personal Content Management Toolkit. It uses the Template -Toolkit as the presentation engine. - - http://pcmt.sf.net/ - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Syntax.pod b/lib/Template/Manual/Syntax.pod deleted file mode 100644 index cc1b6c8..0000000 --- a/lib/Template/Manual/Syntax.pod +++ /dev/null @@ -1,306 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Syntax -# -# DESCRIPTION -# This section describes the syntax, structure and semantics of the -# Template Toolkit directives and general presentation language. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Syntax - Directive syntax, structure and semantics - -=head1 DESCRIPTION - -This section describes the syntax, structure and semantics of the -Template Toolkit directives and general presentation language. - -=head2 Tag Styles - -By default, template directives are embedded within the character sequences -'[%' and '%]'. e.g. - - [% PROCESS header %] - - <h1>Hello World!</h1> - <a href="[% page.next %]"><img src="[% icon.next %].gif"></a> - - [% PROCESS footer %] - -You can change the tag characters using the START_TAG, END_TAG and -TAG_STYLE configuration options. You can also use the TAGS directive -to define a new tag style for the current template file. - -You can also set the INTERPOLATE option to allow simple variable -references to be embedded directly in templates, prefixed by a '$'. - - # INTERPOLATE => 0 - <td>[% name %]</td> <td>[% email %]</td> - - # INTERPOLATE => 1 - <td>$name</td> <td>$email</td> - -Directives may be embedded anywhere in a line of text and can be split -across several lines. Insignificant whitespace is generally ignored -within the directive. - - [% INCLUDE header - title = 'Hello World' - bgcol = '#ffffff' - %] - - [%INCLUDE menu align='right'%] - - Name: [% name %] ([%id%]) - -=head2 Comments - -The '#' character is used to indicate comments within a directive. -When placed immediately inside the opening directive tag, it causes -the entire directive to be ignored. - - [%# this entire directive is ignored no - matter how many lines it wraps onto - %] - -In any other position, it causes the remainder of the current line to -be treated as a comment. - - [% # this is a comment - theta = 20 # so is this - rho = 30 # <aol>me too!</aol> - %] - -=head2 Chomping Whitespace - -You can add '-' or '+' to the immediate start or end of a directive -tag to control the whitespace chomping options. See the PRE_CHOMP and -POST_CHOMP options for further details. - - [% BLOCK foo -%] # remove trailing newline - This is block foo - [%- END %] # remove leading newline - -=head2 Implicit Directives: GET and SET - -The simplest directives are GET and SET which retrieve and update -variable values respectively. The GET and SET keywords are actually -optional as the parser is smart enough to see them for what they -really are (but note the caveat below on using side-effect notation). -Thus, you'll generally see: - - [% SET foo = 10 %] - [% GET foo %] - -written as: - - [% foo = 10 %] - [% foo %] - -You can also express simple logical statements as implicit GET directives: - - [% title or template.title or 'Default Title' %] - - [% mode == 'graphics' ? "Graphics Mode Enabled" : "Text Mode" %] - -All other directives should start with a keyword specified in UPPER -CASE (but see the ANYCASE option). All directives keywords are in -UPPER CASE to make them visually distinctive and to distinguish them -from variables of the same name but different case. It is perfectly -valid, for example, to define a variable called 'stop' which is -entirely separate from the STOP directive. - - [% stop = 'Clackett Lane Bus Depot' %] - - The bus will next stop at [% stop %] # variable - - [% STOP %] # directive - -=head2 Block Directives - -Directives such as FOREACH, WHILE, BLOCK, FILTER, etc., mark the start -of a block which may contain text or other directives up to the -matching END directive. Blocks may be nested indefinitely. The -IF, UNLESS, ELSIF and ELSE directives also define blocks and may be -grouped together in the usual manner. - - [% FOREACH item = [ 'foo' 'bar' 'baz' ] %] - * Item: [% item %] - [% END %] - - [% BLOCK footer %] - Copyright 2000 [% me %] - [% INCLUDE company/logo %] - [% END %] - - [% IF foo %] - [% FOREACH thing = foo.things %] - [% thing %] - [% END %] - [% ELSIF bar %] - [% INCLUDE barinfo %] - [% ELSE %] - do nothing... - [% END %] - -Block directives can also be used in a convenient side-effect notation. - - [% INCLUDE userinfo FOREACH user = userlist %] - - [% INCLUDE debugtxt msg="file: $error.info" - IF debugging %] - - [% "Danger Will Robinson" IF atrisk %] - -versus: - - [% FOREACH user = userlist %] - [% INCLUDE userinfo %] - [% END %] - - [% IF debugging %] - [% INCLUDE debugtxt msg="file: $error.info" %] - [% END %] - - [% IF atrisk %] - Danger Will Robinson - [% END %] - -=head2 Capturing Block Output - -The output of a directive can be captured by simply assigning the directive -to a variable. - - [% headtext = PROCESS header title="Hello World" %] - - [% people = PROCESS userinfo FOREACH user = userlist %] - -This can be used in conjunction with the BLOCK directive for defining large -blocks of text or other content. - - [% poem = BLOCK %] - The boy stood on the burning deck, - His fleece was white as snow. - A rolling stone gathers no moss, - And Keith is sure to follow. - [% END %] - -Note one important caveat of using this syntax in conjunction with side-effect -notation. The following directive does not behave as might be expected: - - [% var = 'value' IF some_condition %] - -In this case, the directive is interpreted as (spacing added for clarity) - - [% var = IF some_condition %] - value - [% END %] - -rather than - - [% IF some_condition %] - [% var = 'value' %] - [% END %] - -The variable is assigned the output of the IF block which returns -'value' if true, but nothing if false. In other words, the following -directive will always cause 'var' to be cleared. - - [% var = 'value' IF 0 %] - -To achieve the expected behaviour, the directive should be written as: - - [% SET var = 'value' IF some_condition %] - -=head2 Chaining Filters - -Multiple FILTER directives can be chained together in sequence. They -are called in the order defined, piping the output of one into the -input of the next. - - [% PROCESS somefile FILTER truncate(100) FILTER html %] - -The pipe character, '|', can also be used as an alias for FILTER. - - [% PROCESS somefile | truncate(100) | html %] - -=head2 Multiple Directive Blocks - -Multiple directives can be included within a single tag when delimited -by semi-colons, ';'. Note however that the TAGS directive must always -be specified in a tag by itself. - - [% IF title; - INCLUDE header; - ELSE; - INCLUDE other/header title="Some Other Title"; - END - %] - -versus - - [% IF title %] - [% INCLUDE header %] - [% ELSE %] - [% INCLUDE other/header title="Some Other Title" %] - [% END %] - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/VMethods.pod b/lib/Template/Manual/VMethods.pod deleted file mode 100644 index 7e380fa..0000000 --- a/lib/Template/Manual/VMethods.pod +++ /dev/null @@ -1,529 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::VMethods -# -# DESCRIPTION -# The Template Toolkit provides virtual methods for manipulating -# variable values. Most of them are analogous to regular Perl -# functions of the same names. This section describes the different -# virtual methods that can be applied to scalar, list and hash -# values. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::VMethods - Virtual Methods - -=head1 DESCRIPTION - -The Template Toolkit provides virtual methods for manipulating variable -values. Most of them are analogous to regular Perl functions of the -same names. This section describes the different virtual methods that -can be applied to scalar, list and hash values. - -=head2 Scalar Virtual Methods - -=over 4 - -=item defined - -Returns true if the value is defined. - - [% user = get_user(uid) IF uid.defined %] - -=item length - -Returns the length of the string representation of the item: - - [% IF password.length < 8 %] - Password too short, dumbass! - [% END %] - -=item repeat(n) - -Repeat the string a specified number of times. - - [% name = 'foo' %] - [% name.repeat(3) %] # foofoofoo - -=item replace(search, replace) - -Outputs the string with all instances of the first argument (specified -as a Perl regular expression) with the second. - - [% name = 'foo, bar & baz' %] - [% name.replace('\W+', '_') %] # foo_bar_baz - -=item match(pattern) - -Performs a regular expression match on the string using the pattern -passed as an argument. If the pattern matches the string then the -method returns a reference to a list of any strings captured within -parenthesis in the pattern. - - [% name = 'Larry Wall' %] - [% matches = name.match('(\w+) (\w+)') %] - [% matches.1 %], [% matches.0 %] # Wall, Larry - -If the pattern does not match then the method returns false, rather -than returning an empty list which Perl and the Template Toolkit both -consider to be a true value. This allows you to write expression like -this. - - [% "We're not worthy!" IF name.match('Larry Wall') %] - - [% IF (matches = name.match('(\w+) (\w+)')) %] - pattern matches: [% matches.join(', ') %] - [% ELSE %] - pattern does not match - [% END %] - -Any regex modifiers, like C</s>, should be added in the regex using -the C<(?s)> syntax. For example, to modify the regex to disregard -whitespace (the C</x> switch), use: - - [% re = '(?x) - (\w+) - [ ] - (\w+) - '; - matches = name.match(re); - %] - -=item search(pattern) - -Performs a similar function to 'match' but simply returns true if the -string matches the regular expression pattern passed as an argument. - - [% name = 'foo bar baz' %] - [% name.search('bar') ? 'bar' : 'no bar' %] # bar - -This virtual method is now deprecated in favour of 'match'. Move along -now, there's nothing more to see here. - -=item split(pattern) - -Calls Perl's split() function to split a string into a list of -strings. - - [% FOREACH dir = mypath.split(':') %] - [% dir %] - [% END %] - -=item chunk(size) - -Splits the value into a list of chunks of a certain size. - - [% ccard_no = "1234567824683579"; - ccard_no.chunk(4).join - %] - -Output: - - 1234 5678 2468 3579 - -If the size is specified as a negative number then the text will -be chunked from right-to-left. This gives the correct grouping -for numbers, for example. - - [% number = 1234567; - number.chunk(-3).join(',') - %] - -Output: - - 1,234,567 - -=item list - -Return the value as a single element list. This can be useful if you -have a variable which may contain a single item or a list and you want -to treat them equally. The 'list' method can be called against a list -reference and will simply return the original reference, effectively -a no-op. - - [% thing.list.size %] # thing can be a scalar or a list - -=item hash - -Return the value as a hash reference containing a single entry with -the key 'value' indicating the original scalar value. As with the -'list' virtual method, this is generally used to help massage data -into different formats. - -=item size - -Always returns 1 for scalar values. This method is provided for -consistency with the hash and list size methods. - -=back - - -=head2 Hash Virtual Methods - -=over 4 - -=item keys, values, each - -The regular hash operators returning lists of keys, values or both. -Note how we use a '$' prefix on the 'key' variable in this example to -have it interpolated (i.e. replaced with its value) before use. - - [% FOREACH key = product.keys %] - [% key %] => [% product.$key %] - [% END %] - -=item sort, nsort - -Return a list of the keys, sorted alphabetically (sort) or numerically -(nsort) according to the corresponding values in the hash. - - [% FOREACH n = phones.sort %] - [% phones.$n %] is [% n %], - [% END %] - -=item import - -The import method can be called on a hash array to import the contents -of another hash array. - - [% hash1 = { - foo => 'Foo', - bar => 'Bar', - } - hash2 = { - wiz => 'Wiz', - woz => 'Woz', - } - %] - - [% hash1.import(hash2) %] - [% hash1.wiz %] # Wiz - -You can also call the import() method by itself to import a hash array -into the current namespace hash. - - [% user = { id => 'lwall', name => 'Larry Wall' } %] - [% import(user) %] - [% id %]: [% name %] # lwall: Larry Wall - -=item defined, exists - -Returns a true or false value if an item in the hash denoted by the key -passed as an argument is defined or exists, respectively. - - [% hash.defined('somekey') ? 'yes' : 'no' %] - [% hash.exists('somekey') ? 'yes' : 'no' %] - -=item size - -Returns the number of key =E<gt> value pairs in the hash. - -=item item - -Returns an item from the hash using a key passed as an argument. - - [% hash.item('foo') %] # same as hash.foo - -=item list - -Returns the contents of the hash in list form. An argument can be -passed to indicate the desired items required in the list: 'keys' to -return a list of the keys (same as hash.keys), 'values' to return a -list of the values (same as hash.values), or 'each' to return as list -of (key, value) pairs (same as hash.each). When called without an -argument it returns a list of hash references, each of which contains -a 'key' and 'value' item representing a single key =E<gt> value pair -in the hash. - -=back - - -=head2 List Virtual Methods - -=over 4 - -=item first, last - -Returns the first/last item in the list. The item is not removed from the -list. - - [% results.first %] to [% results.last %] - -If either is given a numeric argument C<n>, they return the first or -last C<n> elements: - - The first 5 results are [% results.first(5).join(", ") %]. - -=item size, max - -Returns the size of a list (number of elements) and the maximum -index number (size - 1), respectively. - - [% results.size %] search results matched your query - -=item reverse - -Returns the items of the list in reverse order. - - [% FOREACH s = scores.reverse %] - ... - [% END %] - -=item join - -Joins the items in the list into a single string, using Perl's join -function. - - [% items.join(', ') %] - -=item grep - -Returns a list of the items in the list that match a regular expression -pattern. - - [% FOREACH directory.files.grep('\.txt$') %] - ... - [% END %] - -=item sort, nsort - -Returns the items in alpha (sort) or numerical (nsort) order. - - [% library = books.sort %] - -An argument can be provided to specify a search key. Where an item in -the list is a hash reference, the search key will be used to retrieve a -value from the hash which will then be used as the comparison value. -Where an item is an object which implements a method of that name, the -method will be called to return a comparison value. - - [% library = books.sort('author') %] - -In the example, the 'books' list can contains hash references with -an 'author' key or objects with an 'author' method. - -=item unshift(item), push(item) - -Adds an item to the start/end of a list. - - [% mylist.unshift('prev item') %] - [% mylist.push('next item') %] - -=item shift, pop - -Removes the first/last item from the list and returns it. - - [% first = mylist.shift %] - [% last = mylist.pop %] - -=item unique - -Returns a list of the unique elements in a list, in the same order -as in the list itself. - - [% mylist = [ 1, 2, 3, 2, 3, 4, 1, 4, 3, 4, 5 ] %] - [% numbers = mylist.unique %] - -While this can be explicitly sorted, it is not required that the list -be sorted before the unique elements are pulled out (unlike the Unix -command line utility). - - [% numbers = mylist.unique.sort %] - -=item merge - -Returns a list composed of zero or more other lists: - - [% list_one = [ 1 2 3 ]; - list_two = [ 4 5 6 ]; - list_three = [ 7 8 9 ]; - list_four = list_one.merge(list_two, list_three); - %] - -The original lists are not modified. - -=item slice(from, to) - -Returns a slice of items in the list between the bounds passed as -arguments. If the second argument, 'to', isn't specified, then it -defaults to the last item in the list. The original list is not -modified. - - [% first_three = list.slice(0,2) %] - - [% last_three = list.slice(-3, -1) %] - -=item splice(offset, length, list) - -Behaves just like Perl's splice() function allowing you to selectively -remove and/or replace elements in a list. It removes 'length' items -from the list, starting at 'offset' and replaces them with the items -in 'list'. - - [% play_game = [ 'play', 'scrabble' ]; - ping_pong = [ 'ping', 'pong' ]; - redundant = play_game.splice(1, 1, ping_pong); - - redundant.join; # scrabble - play_game.join; # play ping pong - %] - -The method returns a list of the items removed by the splice. -You can use the CALL directive to ignore the output if you're -not planning to do anything with it. - - [% CALL play_game.splice(1, 1, ping_pong) %] - -As well as providing a reference to a list of replacement values, -you can pass in a list of items. - - [% CALL list.splice(-1, 0, 'foo', 'bar') %] - -Be careful about passing just one item in as a replacement value. -If it is a reference to a list then the contents of the list will -be used. If it's not a list, then it will be treated as a single -value. You can use square brackets around a single item if you -need to be explicit: - - [% # push a single item, an_item - CALL list.splice(-1, 0, an_item); - - # push the items from another_list - CALL list.splice(-1, 0, another_list); - - # push a reference to another_list - CALL list.splice(-1, 0, [ another_list ]); - %] - -=back - -=head2 Automagic Promotion of Scalar to List for Virtual Methods - -In addition to the scalar virtual methods listed in the previous -section, you can also call any list virtual method against a scalar. -The item will be automagically promoted to a single element list and -the appropriate list virtual method will be called. - -One particular benefit of this comes when calling subroutines or -object methods that return a list of items, rather than the -preferred reference to a list of items. In this case, the -Template Toolkit automatically folds the items returned into -a list. - -The upshot is that you can continue to use existing Perl modules or -code that returns lists of items, without having to refactor it -just to keep the Template Toolkit happy (by returning references -to list). Class::DBI module is just one example of a particularly -useful module which returns values this way. - -If only a single item is returned from a subroutine then the -Template Toolkit assumes it meant to return a single item (rather -than a list of 1 item) and leaves it well alone, returning the -single value as it is. If you're executing a database query, -for example, you might get 1 item returned, or perhaps many -items which are then folded into a list. - -The FOREACH directive will happily accept either a list or a single -item which it will treat as a list. So it's safe to write directives -like this, where we assume that 'something' is bound to a subroutine -which might return 1 or more items: - - [% FOREACH item = something %] - ... - [% END %] - -The automagic promotion of scalars to single item lists means -that you can also use list virtual methods safely, even if you -only get one item returned. For example: - - [% something.first %] - [% something.join %] - [% something.reverse.join(', ') %] - -Note that this is very much a last-ditch behaviour. If the single -item return is an object with a 'first' method, for example, then that -will be called, as expected, in preference to the list virtual method. - -=head2 Defining Custom Virtual Methods - -You can define your own virtual methods for scalars, lists and hash -arrays. The Template::Stash package variables $SCALAR_OPS, $LIST_OPS -and $HASH_OPS are references to hash arrays that define these virtual -methods. HASH_OPS and LIST_OPS methods are subroutines that accept a -hash/list reference as the first item. SCALAR_OPS are subroutines -that accept a scalar value as the first item. Any other arguments -specified when the method is called will be passed to the subroutine. - - # load Template::Stash to make method tables visible - use Template::Stash; - - # define list method to return new list of odd numbers only - $Template::Stash::LIST_OPS->{ odd } = sub { - my $list = shift; - return [ grep { $_ % 2 } @$list ]; - }; - -template: - - [% primes = [ 2, 3, 5, 7, 9 ] %] - [% primes.odd.join(', ') %] # 3, 5, 7, 9 - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Variables.pod b/lib/Template/Manual/Variables.pod deleted file mode 100644 index e8d998c..0000000 --- a/lib/Template/Manual/Variables.pod +++ /dev/null @@ -1,868 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Variables -# -# DESCRIPTION -# This section describes the different ways in which Perl data can be -# bound to template variables and accessed via Template Toolkit -# directives. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Variables - Template variables and code bindings - -=head1 DESCRIPTION - -This section describes the different ways in which Perl data can be -bound to template variables and accessed via Template Toolkit -directives. - -=head2 Template Variables - -A reference to a hash array may be passed as the second argument to -the process() method, containing definitions of template variables. -The VARIABLES (a.k.a. PRE_DEFINE) option can also be used to pre-define -variables for all templates processed by the object. - - my $tt = Template->new({ - VARIABLES => { - version => 3.14, - release => 'Sahara', - }, - }); - - my $vars = { - serial_no => 271828, - }; - - $tt->process('myfile', $vars); - -'myfile': - - This is version [% version %] ([% release %]). - Serial number: [% serial_no %] - -output: - - This is version 3.14 (Sahara) - Serial number: 271828 - -Variable names may contain any alphanumeric characters or underscores. -They may be lower, upper or mixed case although the usual convention -is to use lower case. The case I<is> significant however, and 'foo', -'Foo' and 'FOO' are all different variables. Upper case variable -names are permitted, but not recommended due to a possible conflict -with an existing or future reserved word. As of version 2.00, these -are: - - GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER - IF UNLESS ELSE ELSIF FOR FOREACH WHILE SWITCH CASE - USE PLUGIN FILTER MACRO PERL RAWPERL BLOCK META - TRY THROW CATCH FINAL NEXT LAST BREAK RETURN STOP - CLEAR TO STEP AND OR NOT MOD DIV END - - -The variable values may be of virtually any Perl type, including -simple scalars, references to lists, hash arrays, subroutines or -objects. The Template Toolkit will automatically apply the correct -procedure to accessing these values as they are used in the template. - -Example: - - my $vars = { - article => 'The Third Shoe', - person => { - id => 314, - name => 'Mr. Blue', - email => 'blue@nowhere.org', - }, - primes => [ 2, 3, 5, 7, 11, 13 ], - wizard => sub { return join(' ', 'Abracadabra!', @_) }, - cgi => CGI->new('mode=submit&debug=1'), - }; - -template: - - [% article %] - - [% person.id %]: [% person.name %] <[% person.email %]> - - [% primes.first %] - [% primes.last %], including [% primes.3 %] - [% primes.size %] prime numbers: [% primes.join(', ') %] - - [% wizard %] - [% wizard('Hocus Pocus!') %] - - [% cgi.param('mode') %] - -output: - - The Third Shoe - - 314: Mr. Blue <blue@nowhere.org> - - 2 - 13, including 7 - 6 prime numbers: 2, 3, 5, 7, 11, 13 - - Abracadabra! - Abracadabra! Hocus Pocus! - - submit - -=head2 Scalar Values - -Regular scalar variables are accessed by simply specifying their name. -As these are just entries in the top-level variable hash they can be -considered special cases of hash array referencing as described below, -with the main namespace hash automatically implied. - - [% article %] - -=head2 Hash Array References - -Members of hash arrays are accessed by specifying the hash reference -and key separated by the dot '.' operator. - - my $vars = { - 'home' => 'http://www.myserver.com/homepage.html', - 'page' => { - 'this' => 'mypage.html', - 'next' => 'nextpage.html', - 'prev' => 'prevpage.html', - }, - }; - -template: - - <a href="[% home %]">Home</a> - <a href="[% page.prev %]">Previous Page</a> - <a href="[% page.next %]">Next Page</a> - -output: - - <a href="http://www.myserver.com/homepage.html">Home</a> - <a href="prevpage.html">Previous Page</a> - <a href="nextpage.html">Next Page</a> - -Any key in a hash which starts with a '_' or '.' character will be -considered private and cannot be evaluated or updated from within a -template. The undefined value will be returned for any such variable -accessed which the Template Toolkit will silently ignore (unless the -DEBUG option is enabled). - - my $vars = { - message => 'Hello World!', - _secret => "On the Internet, no-one knows you're a dog", - thing => { - public => 123, - _private => 456, - '.hidden' => 789, - }, - }; - -template: - - [% message %] # outputs "Hello World!" - [% _secret %] # no output - [% thing.public %] # outputs "123" - [% thing._private %] # no output - [% thing..hidden %] # ERROR: unexpected token (..) - -To access a hash entry using a key stored in another variable, prefix -the key variable with '$' to have it interpolated before use (see -L<Variable Interpolation>). - - [% pagename = 'next' %] - [% page.$pagename %] # same as [% page.next %] - -When you assign to a variable that contains multiple namespace -elements (i.e. it has one or more '.' characters in the name), -any hashes required to represent intermediate namespaces will be -created automatically. In this following example, the 'product' -variable automatically springs into life as a hash array unless -otherwise defined. - - [% product.id = 'XYZ-2000' - product.desc = 'Bogon Generator' - product.price = 666 - %] - - The [% product.id %] [% product.desc %] - costs $[% product.price %].00 - -output: - - The XYZ-2000 Bogon Generator - costs $666.00 - -You can use Perl's familiar '{' ... '}' construct to explicitly create -a hash and assign it to a variable. Note that commas are optional -between key/value pairs and '=' can be used in place of '=E<gt>'. - - [% product = { - id => 'XYZ-2000', - desc => 'Bogon Generator', - price => 666, - } - %] - -=head2 List References - -Items in lists are also accessed by use of the dot operator. - - my $vars = { - 'people' => [ 'Tom', 'Dick', 'Larry' ], - }; - -template: - - [% people.0 %] # Tom - [% people.1 %] # Dick - [% people.2 %] # Larry - -The FOREACH directive can be used to iterate through items in a list. - - [% FOREACH person = people %] - Hello [% person %] - [% END %] - -output: - - Hello Tom - Hello Dick - Hello Larry - -Lists can be constructed in-situ using the regular anonymous list -'[' ... ']' construct. Commas between items are optional. - - [% cols = [ 'red', 'green', 'blue' ] %] - - [% FOREACH c = cols %] - ... - -or: - - [% FOREACH c = [ 'red', 'green', 'blue' ] %] - ... - -You can also create simple numerical sequences using the familiar '..' -operator: - - [% n = [ 1 .. 4 ] %] # n is [ 1, 2, 3, 4 ] - - [% x = 4 - y = 8 - z = [x..y] # z is [ 4, 5, 6, 7, 8 ] - %] - -=head2 Subroutines - -Template variables can contain references to Perl subroutines. When -the variable is used, the Template Toolkit will automatically call the -subroutine, passing any additional arguments specified. The return -value from the subroutine is used as the variable value and inserted -into the document output. - - my $vars = { - wizard => sub { return join(' ', 'Abracadabra!', @_) }, - }; - -template: - - [% wizard %] # Abracadabra! - [% wizard('Hocus Pocus!') %] # Abracadabra! Hocus Pocus! - - -=head2 Objects - -Template variables can also contain references to Perl objects. -Methods are called using the dot operator to specify the method -against the object variable. Additional arguments can be specified -as with subroutines. - - use CGI; - - ... - - my $vars = { - # hard coded CGI params for purpose of example - cgi => CGI->new('mode=submit&debug=1'), - }; - -template: - - [% FOREACH p = cgi.param %] # returns list of param keys - [% p %] => [% cgi.param(p) %] # fetch each param value - [% END %] - -output: - - mode => submit - debug => 1 - -Object methods can also be called as lvalues. That is, they can appear on -the left side of an assignment. The method will be called passing the -assigning value as an argument. - - [% myobj.method = 10 %] - -equivalent to: - - [% myobj.method(10) %] - -=head2 Parameters and Return Values - -Subroutines and methods will be passed any arguments specified in the -template. Any template variables in the argument list will first be -evaluated and their resultant values passed to the code. - - my $vars = { - mycode => sub { return 'received ' . join(', ', @_) }, - }; - -template: - - [% foo = 10 %] - [% mycode(foo, 20) %] # received 10, 20 - -Named parameters may also be specified. These are automatically collected -into a single hash array which is passed by reference as the B<last> -parameter to the sub-routine. Named parameters can be specified using -either '=E<gt>' or '=' and can appear anywhere in the argument list. - - my $vars = { - myjoin => \&myjoin, - }; - - sub myjoin { - # look for hash ref as last argument - my $params = ref $_[-1] eq 'HASH' ? pop : { }; - return join($params->{ joint } || ' + ', @_); - } - -template: - - [% myjoin(10, 20, 30) %] - [% myjoin(10, 20, 30, joint = ' - ' %] - [% myjoin(joint => ' * ', 10, 20, 30 %] - -output: - - 10 + 20 + 30 - 10 - 20 - 30 - 10 * 20 * 30 - -Parenthesised parameters may be added to any element of a variable, -not just those that are bound to code or object methods. At present, -parameters will be ignored if the variable isn't "callable" but are -supported for future extensions. Think of them as "hints" to that -variable, rather than just arguments passed to a function. - - [% r = 'Romeo' %] - [% r(100, 99, s, t, v) %] # outputs "Romeo" - -User code should return a value for the variable it represents. This -can be any of the Perl data types described above: a scalar, or -reference to a list, hash, subroutine or object. Where code returns a -list of multiple values the items will automatically be folded into a -list reference which can be accessed as per normal. - - my $vars = { - # either is OK, first is recommended - items1 => sub { return [ 'foo', 'bar', 'baz' ] }, - items2 => sub { return ( 'foo', 'bar', 'baz' ) }, - }; - -template: - - [% FOREACH i = items1 %] - ... - [% END %] - - [% FOREACH i = items2 %] - ... - [% END %] - -=head2 Error Handling - -Errors can be reported from user code by calling die(). Errors raised -in this way are caught by the Template Toolkit and converted to -structured exceptions which can be handled from within the template. -A reference to the exception object is then available as the 'error' -variable. - - my $vars = { - barf => sub { - die "a sick error has occurred\n"; - }, - }; - -template: - - [% TRY %] - [% barf %] # calls sub which throws error via die() - [% CATCH %] - [% error.info %] # outputs "a sick error has occurred\n" - [% END %] - -Error messages thrown via die() are converted to exceptions of type -'undef'. Exceptions of user-defined types can be thrown by calling -die() with a reference to a Template::Exception object. - - use Template::Exception; - - ... - - my $vars = { - login => sub { - ... - die Template::Exception->new('badpwd', - 'password too silly'); - }, - }; - -template: - - [% TRY %] - [% login %] - [% CATCH badpwd %] - Bad password: [% error.info %] - [% CATCH %] - Some other '[% error.type %]' error: [% error.info %] - [% END %] - -The exception types 'stop' and 'return' are used to implement the -STOP and RETURN directives. Throwing an exception as: - - die (Template::Exception->new('stop')); - -has the same effect as the directive: - - [% STOP %] - -Subroutines and methods can also raise errors by returning a list or -reference to a list containing the undefined value (undef) followed by -an exception object or error message. This is supported for backwards -compatibility with version 1 but may be deprecated in some future -version. - - my $vars = { - # currently equivalent - barf => sub { - die "I'm sorry Dave, I can't do that"; - }, - yack => sub { - return (undef, "I'm sorry Dave, I can't do that"); - }, - }; - -=head2 Virtual Methods - -The Template Toolkit implements a number of "virtual methods" which -can be applied to scalars, hashes or lists. For example: - - [% mylist = [ 'foo', 'bar', 'baz' ] %] - [% newlist = mylist.sort %] - -Here 'mylist' is a regular reference to a list, and 'sort' is -a virtual method that returns a new list of the items in sorted -order. You can chain multiple virtual methods together. For -example: - - [% mylist.sort.join(', ') %] - -Here the 'join' virtual method is called to join the sorted list into -a single string, generating the following output: - - bar, baz, foo - -See L<Template::Manual::VMethods> for details of all the virtual -methods available. - -=head2 Variable Interpolation - -The Template Toolkit uses '$' consistently to indicate that a variable -should be interpolated in position. Most frequently, you see this in -double-quoted strings: - - [% fullname = "$honorific $firstname $surname" %] - -Or embedded in plain text when the INTERPOLATE option is set: - - Dear $honorific $firstname $surname, - -The same rules apply within directives. If a variable is prefixed -with a '$' then it is replaced with its value before being used. The -most common use is to retrieve an element from a hash where the key is -stored in a variable. - - [% uid = 'abw' %] - [% userlist.$uid %] # same as 'userlist.abw' - -Curly braces can be used to delimit interpolated variable names where -necessary. - - [% userlist.${me.id}.name %] - -Directives such as INCLUDE, PROCESS, etc., that accept a template name -as the first argument, will automatically quote it for convenience. - - [% INCLUDE foo/bar.txt %] - -equivalent to: - - [% INCLUDE "foo/bar.txt" %] - -To INCLUDE a template whose name is stored in a variable, simply -prefix the variable name with '$' to have it interpolated. - - [% myfile = 'header' %] - [% INCLUDE $myfile %] - -equivalent to: - - [% INCLUDE header %] - -Note also that a variable containing a reference to a Template::Document -object can also be processed in this way. - - my $vars = { - header => Template::Document->new({ ... }), - }; - -template: - - [% INCLUDE $header %] - -=head2 Local and Global Variables - -Any simple variables that you create, or any changes you make to -existing variables, will only persist while the template is being -processed. The top-level variable hash is copied before processing -begins and any changes to variables are made in this copy, leaving the -original intact. The same thing happens when you INCLUDE another -template. The current namespace hash is cloned to prevent any -variable changes made in the included template from interfering with -existing variables. The PROCESS option bypasses the localisation step -altogether making it slightly faster, but requiring greater attention -to the possibility of side effects caused by creating or changing any -variables within the processed template. - - [% BLOCK change_name %] - [% name = 'bar' %] - [% END %] - - [% name = 'foo' %] - [% INCLUDE change_name %] - [% name %] # foo - [% PROCESS change_name %] - [% name %] # bar - -Dotted compound variables behave slightly differently because the -localisation process is only skin deep. The current variable -namespace hash is copied, but no attempt is made to perform a -deep-copy of other structures within it (hashes, arrays, objects, -etc). A variable referencing a hash, for example, will be copied to -create a new reference but which points to the same hash. Thus, the -general rule is that simple variables (undotted variables) are -localised, but existing complex structures (dotted variables) are not. - - [% BLOCK all_change %] - [% x = 20 %] # changes copy - [% y.z = 'zulu' %] # changes original - [% END %] - - [% x = 10 - y = { z => 'zebra' } - %] - [% INCLUDE all_change %] - [% x %] # still '10' - [% y.z %] # now 'zulu' - - -If you create a complex structure such as a hash or list reference -within a local template context then it will cease to exist when -the template is finished processing. - - [% BLOCK new_stuff %] - [% # define a new 'y' hash array in local context - y = { z => 'zulu' } - %] - [% END %] - - [% x = 10 %] - [% INCLUDE new_stuff %] - [% x %] # outputs '10' - [% y %] # nothing, y is undefined - -Similarly, if you update an element of a compound variable which -I<doesn't> already exists then a hash will be created automatically -and deleted again at the end of the block. - - [% BLOCK new_stuff %] - [% y.z = 'zulu' %] - [% END %] - -However, if the hash I<does> already exist then you will modify the -original with permanent effect. To avoid potential confusion, it is -recommended that you don't update elements of complex variables from -within blocks or templates included by another. - -If you want to create or update truly global variables then you can -use the 'global' namespace. This is a hash array automatically created -in the top-level namespace which all templates, localised or otherwise -see the same reference to. Changes made to variables within this -hash are visible across all templates. - - [% global.version = 123 %] - -=head2 Compile Time Constant Folding - -In addition to variables that get resolved each time a template is -processed, you can also define variables that get resolved just once -when the template is compiled. This generally results in templates -processing faster because there is less work to be done. - -To define compile-time constants, specify a CONSTANTS hash as a -constructor item as per VARIABLES. The CONSTANTS hash can contain any -kind of complex, nested, or dynamic data structures, just like regular -variables. - - my $tt = Template->new({ - CONSTANTS => { - version => 3.14, - release => 'skyrocket', - col => { - back => '#ffffff', - fore => '#000000', - }, - myobj => My::Object->new(), - mysub => sub { ... }, - joint => ', ', - }, - }); - -Within a template, you access these variables using the 'constants' -namespace prefix. - - Version [% constants.version %] ([% constants.release %]) - - Background: [% constants.col.back %] - -When the template is compiled, these variable references are replaced -with the corresponding value. No further variable lookup is then -required when the template is processed. - -You can call subroutines, object methods, and even virtual methods on -constant variables. - - [% constants.mysub(10, 20) %] - [% constants.myobj(30, 40) %] - [% constants.col.keys.sort.join(', ') %] - -One important proviso is that any arguments you pass to subroutines -or methods must also be literal values or compile time constants. - -For example, these are both fine: - - # literal argument - [% constants.col.keys.sort.join(', ') %] - - # constant argument - [% constants.col.keys.sort.join(constants.joint) %] - -But this next example will raise an error at parse time because -'joint' is a runtime variable and cannot be determined at compile -time. - - # ERROR: runtime variable argument! - [% constants.col.keys.sort.join(joint) %] - -The CONSTANTS_NAMESPACE option can be used to provide a different -namespace prefix for constant variables. For example: - - my $tt = Template->new({ - CONSTANTS => { - version => 3.14, - # ...etc... - }, - CONSTANTS_NAMESPACE => 'const', - }); - -Constants would then be referenced in templates as: - - [% const.version %] - -=head2 Special Variables - -A number of special variables are automatically defined by the Template -Toolkit. - -=over 4 - -=item template - -The 'template' variable contains a reference to the main template -being processed, in the form of a Template::Document object. This -variable is correctly defined within PRE_PROCESS, PROCESS and -POST_PROCESS templates, allowing standard headers, footers, etc., to -access metadata items from the main template. The 'name' and -'modtime' metadata items are automatically provided, giving the -template name and modification time in seconds since the epoch. - -Note that the 'template' variable always references the top-level -template, even when processing other template components via INCLUDE, -PROCESS, etc. - -=item component - -The 'component' variable is like 'template' but always contains a -reference to the current, innermost template component being processed. -In the main template, the 'template' and 'component' variable will -reference the same Template::Document object. In any other template -component called from the main template, the 'template' variable -will remain unchanged, but 'component' will contain a new reference -to the current component. - -This example should demonstrate the difference: - - $template->process('foo') - || die $template->error(), "\n"; - -'foo': - - [% template.name %] # foo - [% component.name %] # foo - [% PROCESS footer %] - -'footer': - - [% template.name %] # foo - [% component.name %] # footer - -=item loop - -Within a FOREACH loop, the 'loop' variable references the Template::Iterator -object responsible for controlling the loop. - - [% FOREACH item = [ 'foo', 'bar', 'baz' ] -%] - [% "Items:\n" IF loop.first -%] - [% loop.count %]/[% loop.size %]: [% item %] - [% END %] - -=item error - -Within a CATCH block, the 'error' variable contains a reference to the -Template::Exception object thrown from within the TRY block. The -'type' and 'info' methods can be called or the variable itself can -be printed for automatic stringification into a message of the form -"$type error - $info". See L<Template::Exception> for further details. - - [% TRY %] - ... - [% CATCH %] - [% error %] - [% END %] - -=item content - -The WRAPPER method captures the output from a template block and then -includes a named template, passing the captured output as the 'content' -variable. - - [% WRAPPER box %] - Be not afeard; the isle is full of noises, - Sounds and sweet airs, that give delight and hurt not. - [% END %] - - [% BLOCK box %] - <table border=1> - <tr> - <td> - [% content %] - </td> - </tr> - </table> - [% END %] - -=back - -=head2 Compound Variables - -Compound 'dotted' variables may contain any number of separate -elements. Each element may evaluate to any of the permitted variable -types and the processor will then correctly use this value to evaluate -the rest of the variable. Arguments may be passed to any of the -intermediate elements. - - [% myorg.people.sort('surname').first.fullname %] - -Intermediate variables may be used and will behave entirely as expected. - - [% sorted = myorg.people.sort('surname') %] - [% sorted.first.fullname %] - -This simplified dotted notation has the benefit of hiding the -implementation details of your data. For example, you could implement -a data structure as a hash array one day and then change it to an -object the next without requiring any change to the templates. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Manual/Views.pod b/lib/Template/Manual/Views.pod deleted file mode 100644 index 7bc53b0..0000000 --- a/lib/Template/Manual/Views.pod +++ /dev/null @@ -1,642 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Manual::Views -# -# DESCRIPTION -# This section describes dynamic views: a powerful but experimental -# new feature in version 2.01 of the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Manual::Views - Template Toolkit views (experimental) - -=head1 DESCRIPTION - -This section describes dynamic views: a powerful but experimental new -feature in version 2.01 of the Template Toolkit. - -A view is effectively a collection of templates and/or variable -definitions which can be passed around as a self-contained unit. This -then represents a particular interface or presentation style for other -objects or items of data. - -You can use views to implement custom "skins" for an application or -content set. You can use them to help simplify the presentation of -common objects or data types. You can even use then to automate the -presentation of complex data structures such as that generated in an -XML::DOM tree or similar. You let an iterator do the walking, and the -view does the talking (or in this case, the presenting). Voila - you -have view independant, structure shy traversal using templates. - -In general, views can be used in a number of different ways to achieve -several different things. They elegantly solve some problems which -were otherwise difficult or complicated, and make easy some things -that were previously hard. - -At the moment, they're still very experimental. The directive syntax -and underlying API are likely to change quite considerably over the -next version or two. Please be very wary about building your -multi-million dollar e-commerce solutions based around this feature. - -=head2 Views as Template Collectors/Providers - -The VIEW directive starts a view definition and includes a name by -which the view can be referenced. The view definition continues up to -the matching END directive. - - [% VIEW myview %] - ... - [% END %] - -The first role of a view is to act as a collector and provider of templates. -The include() method can be called on a view to effectively do the same -thing as the INCLUDE directive. The template name is passed as the first -argument, followed by any local variable definitions for the template. - - [% myview.include('header', title='The Title') %] - - # equivalent to - [% INCLUDE header title='The Title' %] - -Views accept a number of configuration options which can be used to control -different aspects of their behaviour. The 'prefix' and 'suffix' options -can be specified to add a fixed prefix and/or suffix to the name of each template. - - [% VIEW myview - prefix = 'my/' - suffix = '.tt2' ; - END - %] - -Now the call - - [% myview.include('header', title='The Title') %] - -is equivalent to - - [% INCLUDE my/header.tt2 title='The Title' %] - -Views provide an AUTOLOAD method which maps method names to the -include() method. Thus, the following are all equivalent: - - [% myview.include('header', title='Hello World') %] - [% myview.include_header(title='Hello World') %] - [% myview.header(title='Hello World') %] - -=head2 Local BLOCK Definitions - -A VIEW definition can include BLOCK definitions which remain local to -the view. A request for a particular template will return a BLOCK, -if defined, in preference to any other template of the same name. - - [% BLOCK foo %] - public foo block - [% END %] - - [% VIEW plain %] - [% BLOCK foo %] - plain foo block - [% END %] - [% END %] - - [% VIEW fancy %] - [% BLOCK foo %] - fancy foo block - [% END %] - [% END %] - - [% INCLUDE foo %] # public foo block - [% plain.foo %] # plain foo block - [% fancy.foo %] # fancy foo block - -In addition to BLOCK definitions, a VIEW can contain any other -template directives. The entire VIEW definition block is processed to -initialise the view but no output is generated (this may change RSN - -and get stored as 'output' item, subsequently accessible as [% -view.output %]). However, directives that have side-effects, such as -those that update a variable, will have noticable consequences. - -=head2 Preserving Variable State within Views - -Views can also be used to save the values of any existing variables, -or to create new ones at the point at which the view is defined. -Unlike simple template metadata (META) which can only contain static -string values, the view initialisation block can contain any template -directives and generate any kind of dynamic output and/or data items. - - [% VIEW my_web_site %] - [% view.title = title or 'My Cool Web Site' %] - [% view.author = "$abw.name, $abw.email" %] - [% view.sidebar = INCLUDE my/sidebar.tt2 %] - [% END %] - -Note that additional data items can be specified as arguments to the VIEW -directive. Anything that doesn't look like a configuration parameter is -assumed to be a data item. This can be a little hazardous, of course, because -you never know when a new configuration item might get added which interferes -with your data. - - [% VIEW my_web_site - # config options - prefix = 'my/' - # misc data - title = title or 'My Cool Web Site' - author = "$abw.name, $abw.email" - sidebar = INCLUDE my/sidebar.tt2 - %] - ... - [% END %] - -Outside of the view definition you can access the view variables as, for -example: - - [% my_web_site.title %] - -One important feature is the equivalence of simple variables and templates. -You can implement the view item 'title' as a simple variable, a template -defined in an external file, possibly with a prefix/suffix automatically -appended, or as a local BLOCK definition within the [% VIEW %] ... [% END %] -definition. If you use the syntax above then the view will Do The Right -Thing to return the appropriate output. - -At the END of the VIEW definition the view is "sealed" to prevent you -from accidentally updating any variable values. If you attempt to change -the value of a variable after the END of the VIEW definition block then -an 'view' error will be thrown. - - [% TRY; - my_web_site.title = 'New Title'; - CATCH; - error; - END - %] - -The error above will be reported as: - - view error - cannot update item in sealed view: title - -The same is true if you pass a parameter to a view variable. This is -interpreted as an attempt to update the variable and will raise the same -warning. - - [% my_web_site.title('New Title') %] # view error! - -You can set the 'silent' parameter to have the view ignore these -parameters and simply return the variable value. - - [% VIEW my_web_site - silent = 1 - title = title or 'My Cool Web Site' - # ... ; - END - %] - - [% my_web_site.title('Blah Blah') %] # My Cool Web Site - -Alternately, you can specify that a view is unsealed allowing existing -variables to be updated and new variables defined. - - [% VIEW my_web_site - sealed = 0 - title = title or 'My Cool Web Site' - # ... ; - END - %] - - [% my_web_site.title('Blah Blah') %] # Blah Blah - [% my_web_site.title %] # Blah Blah - -=head2 Inheritance, Delegation and Reuse - -Views can be inherited from previously defined views by use of the 'base' -parameter. This example shows how a base class view is defined which -applies a 'view/default/' prefix to all template names. - - [% VIEW my.view.default - prefix = 'view/default/'; - END - %] - -Thus the directive: - - [% my.view.default.header(title='Hello World') %] - -is now equivalent to: - - [% INCLUDE view/default/header title='Hello World' %] - -A second view can be defined which specifies the default view as a -base. - - [% VIEW my.view.fancy - base = my.view.default - prefix = 'view/fancy/'; - END - %] - -Now the directive: - - [% my.view.fancy.header(title='Hello World') %] - -will resolve to: - - [% INCLUDE view/fancy/header title='Hello World' %] - -or if that doesn't exist, it will be handled by the base view as: - - [% INCLUDE view/default/header title='Hello World' %] - -When a parent view is specified via the 'base' parameter, the -delegation of a view to its parent for fetching templates and accessing -user defined variables is automatic. You can also implement your own -inheritance, delegation or other reuse patterns by explicitly -delegating to other views. - - [% BLOCK foo %] - public foo block - [% END %] - - [% VIEW plain %] - [% BLOCK foo %] - <plain>[% PROCESS foo %]</plain> - [% END %] - [% END %] - - [% VIEW fancy %] - [% BLOCK foo %] - [% plain.foo | replace('plain', 'fancy') %] - [% END %] - [% END %] - - [% plain.foo %] # <plain>public foo block</plain> - [% fancy.foo %] # <fancy>public foo block</fancy> - -Note that the regular INCLUDE/PROCESS/WRAPPER directives work entirely -independantly of views and will always get the original, unaltered -template name rather than any local per-view definition. - -=head2 Self-Reference - -A reference to the view object under definition is available with the -VIEW ... END block by its specified name and also by the special name -'view' (similar to the C<my $self = shift;> in a Perl method or the -'this' pointer in C++, etc). The view is initially unsealed allowing -any data items to be defined and updated within the VIEW ... END -block. The view is automatically sealed at the end of the definition -block, preventing any view data from being subsequently changed. - -(NOTE: sealing should be optional. As well as sealing a view to prevent -updates (SEALED), it should be possible to set an option in the view to -allow external contexts to update existing variables (UPDATE) or even -create totally new view variables (CREATE)). - - [% VIEW fancy %] - [% fancy.title = 'My Fancy Title' %] - [% fancy.author = 'Frank Open' %] - [% fancy.col = { bg => '#ffffff', bar => '#a0a0ff' } %] - [% END %] - -or - - [% VIEW fancy %] - [% view.title = 'My Fancy Title' %] - [% view.author = 'Frank Open' %] - [% view.col = { bg => '#ffffff', bar => '#a0a0ff' } %] - [% END %] - -It makes no real difference in this case if you refer to the view by -its name, 'fancy', or by the general name, 'view'. Outside of the -view block, however, you should always use the given name, 'fancy': - - [% fancy.title %] - [% fancy.author %] - [% fancy.col.bg %] - -The choice of given name or 'view' is much more important when it -comes to BLOCK definitions within a VIEW. It is generally recommended -that you use 'view' inside a VIEW definition because this is guaranteed -to be correctly defined at any point in the future when the block gets -called. The original name of the view might have long since been changed -or reused but the self-reference via 'view' should always be intact and -valid. - -Take the following VIEW as an example: - - [% VIEW foo %] - [% view.title = 'Hello World' %] - [% BLOCK header %] - Title: [% view.title %] - [% END %] - [% END %] - -Even if we rename the view, or create a new 'foo' variable, the header -block still correctly accesses the 'title' attribute of the view to -which it belongs. Whenever a view BLOCK is processed, the 'view' -variable is always updated to contain the correct reference to the -view object to which it belongs. - - [% bar = foo %] - [% foo = { title => "New Foo" } %] # no problem - [% bar.header %] # => Title: Hello World - -=head2 Saving References to External Views - -When it comes to view inheritance, it's always a good idea to take a -local copy of a parent or delegate view and store it as an attribute -within the view for later use. This ensures that the correct view -reference is always available, even if the external name of a view -has been changed. - - [% VIEW plain %] - ... - [% END %] - - [% VIEW fancy %] - [% view.plain = plain %] - [% BLOCK foo %] - [% view.plain.foo | replace('plain', 'fancy') %] - [% END %] - [% END %] - - [% plain.foo %] # => <plain>public foo block</plain> - [% plain = 'blah' %] # no problem - [% fancy.foo %] # => <fancy>public foo block</fancy> - - -=head2 Views as Data Presenters - -Another key role of a view is to act as a dispatcher to automatically -apply the correct template to present a particular object or data -item. This is handled via the print() method. - -Here's an example: - - [% VIEW foo %] - - [% BLOCK text %] - Some text: [% item %] - [% END %] - - [% BLOCK hash %] - a hash: - [% FOREACH key = item.keys.sort -%] - [% key %] => [% item.$key %] - [% END -%] - [% END %] - - [% BLOCK list %] - a list: [% item.sort.join(', ') %] - [% END %] - - [% END %] - -We can now use the view to print text, hashes or lists. The print() -method includes the right template depending on the typing of the -argument (or arguments) passed. - - [% some_text = 'I read the news today, oh boy.' %] - [% a_hash = { house => 'Lords', hall => 'Albert' } %] - [% a_list = [ 'sure', 'Nobody', 'really' ] %] - - [% view.print(some_text) %] - # Some text: I read the news today, oh boy. - - [% view.print(a_hash) %] - # a hash: - hall => Albert - house => Lords - [% view.print(a_list) %] - # a list: Nobody, really, sure - - -You can also provide templates to print objects of any other class. -The class name is mapped to a template name with all non-word -character sequences such as '::' converted to a single '_'. - - [% VIEW foo %] - [% BLOCK Foo_Bar %] - a Foo::Bar object: - thingies: [% view.print(item.thingies) %] - doodahs: [% view.print(item.doodahs) %] - [% END %] - [% END %] - - [% USE fubar = Foo::Bar(...) %] - - [% foo.print(fubar) %] - -Note how we use the view object to display various items within the -objects ('thingies' and 'doodahs'). We don't need to worry what -kind of data these represent (text, list, hash, etc) because we can -let the view worry about it, automatically mapping the data type to -the correct template. - -Views may define their own type =E<gt> template map. - - [% VIEW foo - map = { TEXT => 'plain_text', - ARRAY => 'show_list', - HASH => 'show_hash', - My::Module => 'template_name' - default => 'any_old_data' - } - %] - [% BLOCK plain_text %] - ... - [% END %] - - ... - - [% END %] - -They can also provide a 'default' map entry, specified as part of the 'map' -hash or as a parameter by itself. - - - [% VIEW foo - map = { ... }, - default = 'whatever' - %] - ... - [% END %] - -or - - [% VIEW foo %] - [% view.map = { ... } - view.default = 'whatever' - %] - ... - [% END %] - -The print() method provides one more piece of magic. If you pass it a -reference to an object which provides a present() method, then the -method will be called passing the view as an argument. This then gives -any object a chance to determine how it should be presented via the -view. - - package Foo::Bar; - - ... - - sub present { - my ($self, $view) = @_; - return "a Foo::Bar object:\n" - . "thingies: " . $view.print($self->{ _THINGIES }) . "\n" - . "doodahs: " . $view.print($self->{ _DOODAHS }) . "\n"; - } - -The object is free to delve deeply into its innards and mess around with -its own private data, before presenting the relevant data via the view. -In a more complex example, a present() method might walk part of a tree -making calls back against the view to present different nodes within the -tree. We may not want to expose the internal structure of the tree -(because that would break encapsulation and make our presentation code -dependant on it) but we want to have some way of walking the tree and -presenting items found in a particular manner. - -This is known as Structure Shy Traversal. Our view object doesn't require -prior knowledge about the internal structure of any data set to be able -to traverse it and present the data contained therein. The data items -themselves, via the present() method, can implement the internal iterators -to guide the view along the right path to presentation happiness. - -The upshot is that you can use views to greatly simplify the display -of data structures like XML::DOM trees. The documentation for the -Template::Plugins::XML::DOM module contains an example of this. In -essence, it looks something like this: - -XML source: - - <user name="Andy Wardley"> - <project id="iCan" title="iCan, but theyCan't"/> - <project id="p45" title="iDid, but theyDidn't"/> - </user> - -TT View: - - [% VIEW fancy %] - [% BLOCK user %] - User: [% item.name %] - [% item.content(myview) %] - [% END %] - - [% BLOCK project %] - Project: [% project.id %] - [% project.name %] - [% END %] - [% END %] - -Generate view: - - [% USE dom = XML.DOM %] - [% fancy.print(dom.parse(xml_source)) %] - -Output: - - User: Andy Wardley - Project: iCan - iCan, but theyCan't - Project: p45 - iDid, but theyDidn't - -The same approach can be applied to many other areas. Here's an example from -the File/Directory plugins. - - [% VIEW myview %] - [% BLOCK file %] - - [% item.name %] - [% END %] - - [% BLOCK directory %] - * [% item.name %] - [% item.content(myview) FILTER indent %] - [% END %] - [% END %] - - [% USE dir = Directory(dirpath) %] - [% myview.print(dir) %] - -And here's the same approach use to convert Pod documentation to any -other format via template. - - [% # load Pod plugin and parse source file into Pod Object Model - USE Pod; - pom = Pod.parse_file(my_pod_file); - - # define view to map all Pod elements to "pod/html/xxx" templates - VIEW pod2html - prefix='pod/html'; - END; - - # now print document via view (i.e. as HTML) - pod2html.print(pom) - %] - -Here we simply define a template prefix for the view which causes the -view to look for 'pod/html/head1', 'pod/html/head2', 'pod/html/over' -as templates to present the different sections of the parsed Pod document. - -There are some examples in the Template Toolkit test suite: t/pod.t and -t/view.t which may shed some more light on this. See the distribution -sub-directory 'examples/pod/html' for examples of Pod -E<gt> HTML templates. - -(This documentation is incomplete but I'm not going to get it 100% pefect -until the syntax and API stabilise). - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Modules.pod b/lib/Template/Modules.pod deleted file mode 100644 index 78dadb8..0000000 --- a/lib/Template/Modules.pod +++ /dev/null @@ -1,448 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Modules -# -# DESCRIPTION -# This section contains the documentation for the modules that -# comprise the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Modules - Core modules comprising the Template Toolkit - -=head1 DESCRIPTION - -This section contains the documentation for the modules that comprise -the Template Toolkit. - -=over 4 - -=item L<Template|Template> - -Front-end module to the Template Toolkit - - - -=item L<Template::Base|Template::Base> - -Base class module implementing common functionality - - - -=item L<Template::Config|Template::Config> - -Factory module for instantiating other TT2 modules - - - -=item L<Template::Constants|Template::Constants> - -Defines constants for the Template Toolkit - - - -=item L<Template::Context|Template::Context> - -Runtime context in which templates are processed - - - -=item L<Template::Document|Template::Document> - -Compiled template document object - - - -=item L<Template::Exception|Template::Exception> - -Exception handling class module - - - -=item L<Template::Filters|Template::Filters> - -Post-processing filters for template blocks - - - -=item L<Template::Iterator|Template::Iterator> - -Data iterator used by the FOREACH directive - - - -=item L<Template::Namespace::Constants|Template::Namespace::Constants> - -Compile time constant folding - - - -=item L<Template::Parser|Template::Parser> - -LALR(1) parser for compiling template documents - - - -=item L<Template::Plugin|Template::Plugin> - -Base class for Template Toolkit plugins - - - -=item L<Template::Plugins|Template::Plugins> - -Plugin provider module - - - -=item L<Template::Provider|Template::Provider> - -Provider module for loading/compiling templates - - - -=item L<Template::Service|Template::Service> - -General purpose template processing service - - - -=item L<Template::Stash|Template::Stash> - -Magical storage for template variables - - - -=item L<Template::Stash::Context|Template::Stash::Context> - -Experimetal stash allowing list/scalar context definition - - - -=item L<Template::Stash::XS|Template::Stash::XS> - -Experimetal high-speed stash written in XS - - - -=item L<Template::Test|Template::Test> - -Module for automating TT2 test scripts - - - -=item L<Template::Plugin::Autoformat|Template::Plugin::Autoformat> - -Interface to Text::Autoformat module - - - -=item L<Template::Plugin::CGI|Template::Plugin::CGI> - -Interface to the CGI module - - - -=item L<Template::Plugin::DBI|Template::Plugin::DBI> - -Template interface to the DBI module - - - -=item L<Template::Plugin::Datafile|Template::Plugin::Datafile> - -Plugin to construct records from a simple data file - - - -=item L<Template::Plugin::Date|Template::Plugin::Date> - -Plugin to generate formatted date strings - - - -=item L<Template::Plugin::Directory|Template::Plugin::Directory> - -Plugin for generating directory listings - - - -=item L<Template::Plugin::Dumper|Template::Plugin::Dumper> - -Plugin interface to Data::Dumper - - - -=item L<Template::Plugin::File|Template::Plugin::File> - -Plugin providing information about files - - - -=item L<Template::Plugin::Filter|Template::Plugin::Filter> - -Base class for plugin filters - - - -=item L<Template::Plugin::Format|Template::Plugin::Format> - -Plugin to create formatting functions - - - -=item L<Template::Plugin::GD::Image|Template::Plugin::GD::Image> - -Interface to GD Graphics Library - - - -=item L<Template::Plugin::GD::Polygon|Template::Plugin::GD::Polygon> - -Interface to GD module Polygon class - - - -=item L<Template::Plugin::GD::Constants|Template::Plugin::GD::Constants> - -Interface to GD module constants - - - -=item L<Template::Plugin::GD::Text|Template::Plugin::GD::Text> - -Text utilities for use with GD - - - -=item L<Template::Plugin::GD::Text::Align|Template::Plugin::GD::Text::Align> - -Draw aligned strings in GD images - - - -=item L<Template::Plugin::GD::Text::Wrap|Template::Plugin::GD::Text::Wrap> - -Break and wrap strings in GD images - - - -=item L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines> - -Create line graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d> - -Create 3D line graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars> - -Create bar graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d> - -Create 3D bar graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points> - -Create point graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints> - -Create line/point graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area> - -Create area graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed> - -Create mixed graphs with axes and legends - - - -=item L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie> - -Create pie charts with legends - - - -=item L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d> - -Create 3D pie charts with legends - - - -=item L<Template::Plugin::HTML|Template::Plugin::HTML> - -Plugin to create HTML elements - - - -=item L<Template::Plugin::Image|Template::Plugin::Image> - -Plugin access to image sizes - - - -=item L<Template::Plugin::Iterator|Template::Plugin::Iterator> - -Plugin to create iterators (Template::Iterator) - - - -=item L<Template::Plugin::Math|Template::Plugin::Math> - -Plugin interface to mathematical functions - - - -=item L<Template::Plugin::Pod|Template::Plugin::Pod> - -Plugin interface to Pod::POM (Pod Object Model) - - - -=item L<Template::Plugin::Procedural|Template::Plugin::Procedural> - -Base class for procedural plugins - - - -=item L<Template::Plugin::String|Template::Plugin::String> - -Object oriented interface for string manipulation - - - -=item L<Template::Plugin::Table|Template::Plugin::Table> - -Plugin to present data in a table - - - -=item L<Template::Plugin::URL|Template::Plugin::URL> - -Plugin to construct complex URLs - - - -=item L<Template::Plugin::View|Template::Plugin::View> - -Plugin to create views (Template::View) - - - -=item L<Template::Plugin::Wrap|Template::Plugin::Wrap> - -Plugin interface to Text::Wrap - - - -=item L<Template::Plugin::XML::DOM|Template::Plugin::XML::DOM> - -Plugin interface to XML::DOM - - - -=item L<Template::Plugin::XML::RSS|Template::Plugin::XML::RSS> - -Plugin interface to XML::RSS - - - -=item L<Template::Plugin::XML::Simple|Template::Plugin::XML::Simple> - -Plugin interface to XML::Simple - - - -=item L<Template::Plugin::XML::Style|Template::Plugin::XML::Style> - -Simple XML stylesheet transfomations - - - -=item L<Template::Plugin::XML::XPath|Template::Plugin::XML::XPath> - -Plugin interface to XML::XPath - - - - - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Namespace/Constants.pm b/lib/Template/Namespace/Constants.pm deleted file mode 100644 index e1b5114..0000000 --- a/lib/Template/Namespace/Constants.pm +++ /dev/null @@ -1,205 +0,0 @@ -#================================================================= -*-Perl-*- -# -# Template::Namespace::Constants -# -# DESCRIPTION -# Plugin compiler module for performing constant folding at compile time -# on variables in a particular namespace. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2002 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2002 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. -# -# REVISION -# $Id: Constants.pm,v 1.22 2004/01/13 16:20:36 abw Exp $ -# -#============================================================================ - -package Template::Namespace::Constants; - -use strict; -use Template::Base; -use Template::Config; -use Template::Directive; -use Template::Exception; - -use base qw( Template::Base ); -use vars qw( $VERSION $DEBUG ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.22 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; - - -sub _init { - my ($self, $config) = @_; - $self->{ STASH } = Template::Config->stash($config) - || return $self->error(Template::Config->error()); - return $self; -} - - - -#------------------------------------------------------------------------ -# ident(\@ident) foo.bar(baz) -#------------------------------------------------------------------------ - -sub ident { - my ($self, $ident) = @_; - my @save = @$ident; - - # discard first node indicating constants namespace - splice(@$ident, 0, 2); - - my $nelems = @$ident / 2; - my ($e, $result); - local $" = ', '; - - print STDERR "constant ident [ @$ident ] " if $DEBUG; - - foreach $e (0..$nelems-1) { - # node name must be a constant - unless ($ident->[$e * 2] =~ s/^'(.+)'$/$1/s) { - $self->DEBUG(" * deferred (non-constant item: ", $ident->[$e * 2], ")\n") - if $DEBUG; - return Template::Directive->ident(\@save); - } - - # if args is non-zero then it must be eval'ed - if ($ident->[$e * 2 + 1]) { - my $args = $ident->[$e * 2 + 1]; - my $comp = eval "$args"; - if ($@) { - $self->DEBUG(" * deferred (non-constant args: $args)\n") if $DEBUG; - return Template::Directive->ident(\@save); - } - $self->DEBUG("($args) ") if $comp && $DEBUG; - $ident->[$e * 2 + 1] = $comp; - } - } - - - $result = $self->{ STASH }->get($ident); - - if (! length $result || ref $result) { - my $reason = length $result ? 'reference' : 'no result'; - $self->DEBUG(" * deferred ($reason)\n") if $DEBUG; - return Template::Directive->ident(\@save); - } - - $result =~ s/'/\\'/g; - - $self->DEBUG(" * resolved => '$result'\n") if $DEBUG; - - return "'$result'"; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Namespace::Constants - Compile time constant folding - -=head1 SYNOPSIS - - # easy way to define constants - use Template; - - my $tt = Template->new({ - CONSTANTS => { - pi => 3.14, - e => 2.718, - }, - }); - - # nitty-gritty, hands-dirty way - use Template::Namespace::Constants; - - my $tt = Template->new({ - NAMESPACE => { - constants => Template::Namespace::Constants->new({ - pi => 3.14, - e => 2.718, - }, - }, - }); - -=head1 DESCRIPTION - -The Template::Namespace::Constants module implements a namespace handler -which is plugged into the Template::Directive compiler module. This then -performs compile time constant folding of variables in a particular namespace. - -=head1 PUBLIC METHODS - -=head2 new(\%constants) - -The new() constructor method creates and returns a reference to a new -Template::Namespace::Constants object. This creates an internal stash -to store the constant variable definitions passed as arguments. - - my $handler = Template::Namespace::Constants->new({ - pi => 3.14, - e => 2.718, - }); - -=head2 ident(\@ident) - -Method called to resolve a variable identifier into a compiled form. In this -case, the method fetches the corresponding constant value from its internal -stash and returns it. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -1.22, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Directive|Template::Directive> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Parser.pm b/lib/Template/Parser.pm deleted file mode 100644 index 68bf9e0..0000000 --- a/lib/Template/Parser.pm +++ /dev/null @@ -1,1446 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Parser -# -# DESCRIPTION -# This module implements a LALR(1) parser and assocated support -# methods to parse template documents into the appropriate "compiled" -# format. Much of the parser DFA code (see _parse() method) is based -# on Francois Desarmenien's Parse::Yapp module. Kudos to him. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -# The following copyright notice appears in the Parse::Yapp -# documentation. -# -# The Parse::Yapp module and its related modules and shell -# scripts are copyright (c) 1998 Francois Desarmenien, -# France. All rights reserved. -# -# You may use and distribute them under the terms of either -# the GNU General Public License or the Artistic License, as -# specified in the Perl README file. -# -#---------------------------------------------------------------------------- -# -# $Id: Parser.pm,v 2.81 2004/01/13 16:19:15 abw Exp $ -# -#============================================================================ - -package Template::Parser; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $ERROR ); -use base qw( Template::Base ); -use vars qw( $TAG_STYLE $DEFAULT_STYLE $QUOTED_ESCAPES ); - -use Template::Constants qw( :status :chomp ); -use Template::Directive; -use Template::Grammar; - -# parser state constants -use constant CONTINUE => 0; -use constant ACCEPT => 1; -use constant ERROR => 2; -use constant ABORT => 3; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.81 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; -$ERROR = ''; - - -#======================================================================== -# -- COMMON TAG STYLES -- -#======================================================================== - -$TAG_STYLE = { - 'default' => [ '\[%', '%\]' ], - 'template1' => [ '[\[%]%', '%[\]%]' ], - 'metatext' => [ '%%', '%%' ], - 'html' => [ '<!--', '-->' ], - 'mason' => [ '<%', '>' ], - 'asp' => [ '<%', '%>' ], - 'php' => [ '<\?', '\?>' ], - 'star' => [ '\[\*', '\*\]' ], -}; -$TAG_STYLE->{ template } = $TAG_STYLE->{ tt2 } = $TAG_STYLE->{ default }; - - -$DEFAULT_STYLE = { - START_TAG => $TAG_STYLE->{ default }->[0], - END_TAG => $TAG_STYLE->{ default }->[1], -# TAG_STYLE => 'default', - ANYCASE => 0, - INTERPOLATE => 0, - PRE_CHOMP => 0, - POST_CHOMP => 0, - V1DOLLAR => 0, - EVAL_PERL => 0, -}; - -$QUOTED_ESCAPES = { - n => "\n", - r => "\r", - t => "\t", -}; - - -#======================================================================== -# ----- PUBLIC METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# new(\%config) -# -# Constructor method. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $config = $_[0] && UNIVERSAL::isa($_[0], 'HASH') ? shift(@_) : { @_ }; - my ($tagstyle, $debug, $start, $end, $defaults, $grammar, $hash, $key, $udef); - - my $self = bless { - START_TAG => undef, - END_TAG => undef, - TAG_STYLE => 'default', - ANYCASE => 0, - INTERPOLATE => 0, - PRE_CHOMP => 0, - POST_CHOMP => 0, - V1DOLLAR => 0, - EVAL_PERL => 0, - FILE_INFO => 1, - GRAMMAR => undef, - _ERROR => '', - FACTORY => 'Template::Directive', - }, $class; - - # update self with any relevant keys in config - foreach $key (keys %$self) { - $self->{ $key } = $config->{ $key } if defined $config->{ $key }; - } - $self->{ FILEINFO } = [ ]; - - # DEBUG config item can be a bitmask - if (defined ($debug = $config->{ DEBUG })) { - $self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PARSER - | Template::Constants::DEBUG_FLAGS ); - $self->{ DEBUG_DIRS } = $debug & Template::Constants::DEBUG_DIRS; - } - # package variable can be set to 1 to support previous behaviour - elsif ($DEBUG == 1) { - $self->{ DEBUG } = Template::Constants::DEBUG_PARSER; - $self->{ DEBUG_DIRS } = 0; - } - # otherwise let $DEBUG be a bitmask - else { - $self->{ DEBUG } = $DEBUG & ( Template::Constants::DEBUG_PARSER - | Template::Constants::DEBUG_FLAGS ); - $self->{ DEBUG_DIRS } = $DEBUG & Template::Constants::DEBUG_DIRS; - } - - $grammar = $self->{ GRAMMAR } ||= do { - require Template::Grammar; - Template::Grammar->new(); - }; - - # build a FACTORY object to include any NAMESPACE definitions, - # but only if FACTORY isn't already an object - if ($config->{ NAMESPACE } && ! ref $self->{ FACTORY }) { - my $fclass = $self->{ FACTORY }; - $self->{ FACTORY } = $fclass->new( NAMESPACE => $config->{ NAMESPACE } ) - || return $class->error($fclass->error()); - } - - # load grammar rules, states and lex table - @$self{ qw( LEXTABLE STATES RULES ) } - = @$grammar{ qw( LEXTABLE STATES RULES ) }; - - $self->new_style($config) - || return $class->error($self->error()); - - return $self; -} - - -#------------------------------------------------------------------------ -# new_style(\%config) -# -# Install a new (stacked) parser style. This feature is currently -# experimental but should mimic the previous behaviour with regard to -# TAG_STYLE, START_TAG, END_TAG, etc. -#------------------------------------------------------------------------ - -sub new_style { - my ($self, $config) = @_; - my $styles = $self->{ STYLE } ||= [ ]; - my ($tagstyle, $tags, $start, $end, $key); - - # clone new style from previous or default style - my $style = { %{ $styles->[-1] || $DEFAULT_STYLE } }; - - # expand START_TAG and END_TAG from specified TAG_STYLE - if ($tagstyle = $config->{ TAG_STYLE }) { - return $self->error("Invalid tag style: $tagstyle") - unless defined ($tags = $TAG_STYLE->{ $tagstyle }); - ($start, $end) = @$tags; - $config->{ START_TAG } ||= $start; - $config->{ END_TAG } ||= $end; - } - - foreach $key (keys %$DEFAULT_STYLE) { - $style->{ $key } = $config->{ $key } if defined $config->{ $key }; - } - push(@$styles, $style); - return $style; -} - - -#------------------------------------------------------------------------ -# old_style() -# -# Pop the current parser style and revert to the previous one. See -# new_style(). ** experimental ** -#------------------------------------------------------------------------ - -sub old_style { - my $self = shift; - my $styles = $self->{ STYLE }; - return $self->error('only 1 parser style remaining') - unless (@$styles > 1); - pop @$styles; - return $styles->[-1]; -} - - -#------------------------------------------------------------------------ -# parse($text, $data) -# -# Parses the text string, $text and returns a hash array representing -# the compiled template block(s) as Perl code, in the format expected -# by Template::Document. -#------------------------------------------------------------------------ - -sub parse { - my ($self, $text, $info) = @_; - my ($tokens, $block); - - $info->{ DEBUG } = $self->{ DEBUG_DIRS } - unless defined $info->{ DEBUG }; - -# print "info: { ", join(', ', map { "$_ => $info->{ $_ }" } keys %$info), " }\n"; - - # store for blocks defined in the template (see define_block()) - my $defblock = $self->{ DEFBLOCK } = { }; - my $metadata = $self->{ METADATA } = [ ]; - - $self->{ _ERROR } = ''; - - # split file into TEXT/DIRECTIVE chunks - $tokens = $self->split_text($text) - || return undef; ## RETURN ## - - push(@{ $self->{ FILEINFO } }, $info); - - # parse chunks - $block = $self->_parse($tokens, $info); - - pop(@{ $self->{ FILEINFO } }); - - return undef unless $block; ## RETURN ## - - $self->debug("compiled main template document block:\n$block") - if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER; - - return { - BLOCK => $block, - DEFBLOCKS => $defblock, - METADATA => { @$metadata }, - }; -} - - - -#------------------------------------------------------------------------ -# split_text($text) -# -# Split input template text into directives and raw text chunks. -#------------------------------------------------------------------------ - -sub split_text { - my ($self, $text) = @_; - my ($pre, $dir, $prelines, $dirlines, $postlines, $chomp, $tags, @tags); - my $style = $self->{ STYLE }->[-1]; - my ($start, $end, $prechomp, $postchomp, $interp ) = - @$style{ qw( START_TAG END_TAG PRE_CHOMP POST_CHOMP INTERPOLATE ) }; - - my @tokens = (); - my $line = 1; - - return \@tokens ## RETURN ## - unless defined $text && length $text; - - # extract all directives from the text - while ($text =~ s/ - ^(.*?) # $1 - start of line up to directive - (?: - $start # start of tag - (.*?) # $2 - tag contents - $end # end of tag - ) - //sx) { - - ($pre, $dir) = ($1, $2); - $pre = '' unless defined $pre; - $dir = '' unless defined $dir; - - $postlines = 0; # denotes lines chomped - $prelines = ($pre =~ tr/\n//); # NULL - count only - $dirlines = ($dir =~ tr/\n//); # ditto - - # the directive CHOMP options may modify the preceding text - for ($dir) { - # remove leading whitespace and check for a '-' chomp flag - s/^([-+\#])?\s*//s; - if ($1 && $1 eq '#') { - # comment out entire directive except for any chomp flag - $dir = ($dir =~ /([-+])$/) ? $1 : ''; - } - else { - $chomp = ($1 && $1 eq '+') ? 0 : ($1 || $prechomp); -# my $space = $prechomp == &Template::Constants::CHOMP_COLLAPSE - my $space = $prechomp == CHOMP_COLLAPSE - ? ' ' : ''; - - # chomp off whitespace and newline preceding directive - $chomp and $pre =~ s/(\n|^)([ \t]*)\Z/($1||$2) ? $space : ''/me - and $1 eq "\n" - and $prelines++; - } - - # remove trailing whitespace and check for a '-' chomp flag - s/\s*([-+])?\s*$//s; - $chomp = ($1 && $1 eq '+') ? 0 : ($1 || $postchomp); - my $space = $postchomp == &Template::Constants::CHOMP_COLLAPSE - ? ' ' : ''; - - $postlines++ - if $chomp and $text =~ s/ - ^ - ([ \t]*)\n # whitespace to newline - (?:(.|\n)|$) # any char (not EOF) - / - (($1||$2) ? $space : '') . (defined $2 ? $2 : '') - /ex; - } - - # any text preceding the directive can now be added - if (length $pre) { - push(@tokens, $interp - ? [ $pre, $line, 'ITEXT' ] - : ('TEXT', $pre) ); - $line += $prelines; - } - - # and now the directive, along with line number information - if (length $dir) { - # the TAGS directive is a compile-time switch - if ($dir =~ /^TAGS\s+(.*)/i) { - my @tags = split(/\s+/, $1); - if (scalar @tags > 1) { - ($start, $end) = map { quotemeta($_) } @tags; - } - elsif ($tags = $TAG_STYLE->{ $tags[0] }) { - ($start, $end) = @$tags; - } - else { - warn "invalid TAGS style: $tags[0]\n"; - } - } - else { - # DIRECTIVE is pushed as: - # [ $dirtext, $line_no(s), \@tokens ] - push(@tokens, - [ $dir, - ($dirlines - ? sprintf("%d-%d", $line, $line + $dirlines) - : $line), - $self->tokenise_directive($dir) ]); - } - } - - # update line counter to include directive lines and any extra - # newline chomped off the start of the following text - $line += $dirlines + $postlines; - } - - # anything remaining in the string is plain text - push(@tokens, $interp - ? [ $text, $line, 'ITEXT' ] - : ( 'TEXT', $text) ) - if length $text; - - return \@tokens; ## RETURN ## -} - - - -#------------------------------------------------------------------------ -# interpolate_text($text, $line) -# -# Examines $text looking for any variable references embedded like -# $this or like ${ this }. -#------------------------------------------------------------------------ - -sub interpolate_text { - my ($self, $text, $line) = @_; - my @tokens = (); - my ($pre, $var, $dir); - - - while ($text =~ - / - ( (?: \\. | [^\$] ){1,3000} ) # escaped or non-'$' character [$1] - | - ( \$ (?: # embedded variable [$2] - (?: \{ ([^\}]*) \} ) # ${ ... } [$3] - | - ([\w\.]+) # $word [$4] - ) - ) - /gx) { - - ($pre, $var, $dir) = ($1, $3 || $4, $2); - - # preceding text - if (defined($pre) && length($pre)) { - $line += $pre =~ tr/\n//; - $pre =~ s/\\\$/\$/g; - push(@tokens, 'TEXT', $pre); - } - # $variable reference - if ($var) { - $line += $dir =~ tr/\n/ /; - push(@tokens, [ $dir, $line, $self->tokenise_directive($var) ]); - } - # other '$' reference - treated as text - elsif ($dir) { - $line += $dir =~ tr/\n//; - push(@tokens, 'TEXT', $dir); - } - } - - return \@tokens; -} - - - -#------------------------------------------------------------------------ -# tokenise_directive($text) -# -# Called by the private _parse() method when it encounters a DIRECTIVE -# token in the list provided by the split_text() or interpolate_text() -# methods. The directive text is passed by parameter. -# -# The method splits the directive into individual tokens as recognised -# by the parser grammar (see Template::Grammar for details). It -# constructs a list of tokens each represented by 2 elements, as per -# split_text() et al. The first element contains the token type, the -# second the token itself. -# -# The method tokenises the string using a complex (but fast) regex. -# For a deeper understanding of the regex magic at work here, see -# Jeffrey Friedl's excellent book "Mastering Regular Expressions", -# from O'Reilly, ISBN 1-56592-257-3 -# -# Returns a reference to the list of chunks (each one being 2 elements) -# identified in the directive text. On error, the internal _ERROR string -# is set and undef is returned. -#------------------------------------------------------------------------ - -sub tokenise_directive { - my ($self, $text, $line) = @_; - my ($token, $uctoken, $type, $lookup); - my $lextable = $self->{ LEXTABLE }; - my $style = $self->{ STYLE }->[-1]; - my ($anycase, $start, $end) = @$style{ qw( ANYCASE START_TAG END_TAG ) }; - my @tokens = ( ); - - while ($text =~ - / - # strip out any comments - (\#[^\n]*) - | - # a quoted phrase matches in $3 - (["']) # $2 - opening quote, ' or " - ( # $3 - quoted text buffer - (?: # repeat group (no backreference) - \\\\ # an escaped backslash \\ - | # ...or... - \\\2 # an escaped quote \" or \' (match $1) - | # ...or... - . # any other character - | \n - )*? # non-greedy repeat - ) # end of $3 - \2 # match opening quote - | - # an unquoted number matches in $4 - (-?\d+(?:\.\d+)?) # numbers - | - # filename matches in $5 - ( \/?\w+(?:(?:\/|::?)\w*)+ | \/\w+) - | - # an identifier matches in $6 - (\w+) # variable identifier - | - # an unquoted word or symbol matches in $7 - ( [(){}\[\]:;,\/\\] # misc parenthesis and symbols -# | \-> # arrow operator (for future?) - | [+\-*] # math operations - | \$\{? # dollar with option left brace - | => # like '=' - | [=!<>]?= | [!<>] # eqality tests - | &&? | \|\|? # boolean ops - | \.\.? # n..n sequence - | \S+ # something unquoted - ) # end of $7 - /gmxo) { - - # ignore comments to EOL - next if $1; - - # quoted string - if (defined ($token = $3)) { - # double-quoted string may include $variable references - if ($2 eq '"') { - if ($token =~ /[\$\\]/) { - $type = 'QUOTED'; - # unescape " and \ but leave \$ escaped so that - # interpolate_text() doesn't incorrectly treat it - # as a variable reference -# $token =~ s/\\([\\"])/$1/g; - for ($token) { - s/\\([^\$nrt])/$1/g; - s/\\([nrt])/$QUOTED_ESCAPES->{ $1 }/ge; - } - push(@tokens, ('"') x 2, - @{ $self->interpolate_text($token) }, - ('"') x 2); - next; - } - else { - $type = 'LITERAL'; - $token =~ s['][\\']g; - $token = "'$token'"; - } - } - else { - $type = 'LITERAL'; - $token = "'$token'"; - } - } - # number - elsif (defined ($token = $4)) { - $type = 'NUMBER'; - } - elsif (defined($token = $5)) { - $type = 'FILENAME'; - } - elsif (defined($token = $6)) { - # reserved words may be in lower case unless case sensitive - $uctoken = $anycase ? uc $token : $token; - if (defined ($type = $lextable->{ $uctoken })) { - $token = $uctoken; - } - else { - $type = 'IDENT'; - } - } - elsif (defined ($token = $7)) { - # reserved words may be in lower case unless case sensitive - $uctoken = $anycase ? uc $token : $token; - unless (defined ($type = $lextable->{ $uctoken })) { - $type = 'UNQUOTED'; - } - } - - push(@tokens, $type, $token); - -# print(STDERR " +[ $type, $token ]\n") -# if $DEBUG; - } - -# print STDERR "tokenise directive() returning:\n [ @tokens ]\n" -# if $DEBUG; - - return \@tokens; ## RETURN ## -} - - -#------------------------------------------------------------------------ -# define_block($name, $block) -# -# Called by the parser 'defblock' rule when a BLOCK definition is -# encountered in the template. The name of the block is passed in the -# first parameter and a reference to the compiled block is passed in -# the second. This method stores the block in the $self->{ DEFBLOCK } -# hash which has been initialised by parse() and will later be used -# by the same method to call the store() method on the calling cache -# to define the block "externally". -#------------------------------------------------------------------------ - -sub define_block { - my ($self, $name, $block) = @_; - my $defblock = $self->{ DEFBLOCK } - || return undef; - - $self->debug("compiled block '$name':\n$block") - if $self->{ DEBUG } & Template::Constants::DEBUG_PARSER; - - $defblock->{ $name } = $block; - - return undef; -} - -sub push_defblock { - my $self = shift; - my $stack = $self->{ DEFBLOCK_STACK } ||= []; - push(@$stack, $self->{ DEFBLOCK } ); - $self->{ DEFBLOCK } = { }; -} - -sub pop_defblock { - my $self = shift; - my $defs = $self->{ DEFBLOCK }; - my $stack = $self->{ DEFBLOCK_STACK } || return $defs; - return $defs unless @$stack; - $self->{ DEFBLOCK } = pop @$stack; - return $defs; -} - - -#------------------------------------------------------------------------ -# add_metadata(\@setlist) -#------------------------------------------------------------------------ - -sub add_metadata { - my ($self, $setlist) = @_; - my $metadata = $self->{ METADATA } - || return undef; - - push(@$metadata, @$setlist); - - return undef; -} - - -#------------------------------------------------------------------------ -# location() -# -# Return Perl comment indicating current parser file and line -#------------------------------------------------------------------------ - -sub location { - my $self = shift; - return "\n" unless $self->{ FILE_INFO }; - my $line = ${ $self->{ LINE } }; - my $info = $self->{ FILEINFO }->[-1]; - my $file = $info->{ path } || $info->{ name } - || '(unknown template)'; - $line =~ s/\-.*$//; # might be 'n-n' - return "#line $line \"$file\"\n"; -} - - -#======================================================================== -# ----- PRIVATE METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# _parse(\@tokens, \@info) -# -# Parses the list of input tokens passed by reference and returns a -# Template::Directive::Block object which contains the compiled -# representation of the template. -# -# This is the main parser DFA loop. See embedded comments for -# further details. -# -# On error, undef is returned and the internal _ERROR field is set to -# indicate the error. This can be retrieved by calling the error() -# method. -#------------------------------------------------------------------------ - -sub _parse { - my ($self, $tokens, $info) = @_; - my ($token, $value, $text, $line, $inperl); - my ($state, $stateno, $status, $action, $lookup, $coderet, @codevars); - my ($lhs, $len, $code); # rule contents - my $stack = [ [ 0, undef ] ]; # DFA stack - -# DEBUG -# local $" = ', '; - - # retrieve internal rule and state tables - my ($states, $rules) = @$self{ qw( STATES RULES ) }; - - # call the grammar set_factory method to install emitter factory - $self->{ GRAMMAR }->install_factory($self->{ FACTORY }); - - $line = $inperl = 0; - $self->{ LINE } = \$line; - $self->{ FILE } = $info->{ name }; - $self->{ INPERL } = \$inperl; - - $status = CONTINUE; - my $in_string = 0; - - while(1) { - # get state number and state - $stateno = $stack->[-1]->[0]; - $state = $states->[$stateno]; - - # see if any lookaheads exist for the current state - if (exists $state->{'ACTIONS'}) { - - # get next token and expand any directives (i.e. token is an - # array ref) onto the front of the token list - while (! defined $token && @$tokens) { - $token = shift(@$tokens); - if (ref $token) { - ($text, $line, $token) = @$token; - if (ref $token) { - if ($info->{ DEBUG } && ! $in_string) { - # - - - - - - - - - - - - - - - - - - - - - - - - - - # This is gnarly. Look away now if you're easily - # frightened. We're pushing parse tokens onto the - # pending list to simulate a DEBUG directive like so: - # [% DEBUG msg line='20' text='INCLUDE foo' %] - # - - - - - - - - - - - - - - - - - - - - - - - - - - my $dtext = $text; - $dtext =~ s[(['\\])][\\$1]g; - unshift(@$tokens, - DEBUG => 'DEBUG', - IDENT => 'msg', - IDENT => 'line', - ASSIGN => '=', - LITERAL => "'$line'", - IDENT => 'text', - ASSIGN => '=', - LITERAL => "'$dtext'", - IDENT => 'file', - ASSIGN => '=', - LITERAL => "'$info->{ name }'", - (';') x 2, - @$token, - (';') x 2); - } - else { - unshift(@$tokens, @$token, (';') x 2); - } - $token = undef; # force redo - } - elsif ($token eq 'ITEXT') { - if ($inperl) { - # don't perform interpolation in PERL blocks - $token = 'TEXT'; - $value = $text; - } - else { - unshift(@$tokens, - @{ $self->interpolate_text($text, $line) }); - $token = undef; # force redo - } - } - } - else { - # toggle string flag to indicate if we're crossing - # a string boundary - $in_string = ! $in_string if $token eq '"'; - $value = shift(@$tokens); - } - }; - # clear undefined token to avoid 'undefined variable blah blah' - # warnings and let the parser logic pick it up in a minute - $token = '' unless defined $token; - - # get the next state for the current lookahead token - $action = defined ($lookup = $state->{'ACTIONS'}->{ $token }) - ? $lookup - : defined ($lookup = $state->{'DEFAULT'}) - ? $lookup - : undef; - } - else { - # no lookahead actions - $action = $state->{'DEFAULT'}; - } - - # ERROR: no ACTION - last unless defined $action; - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # shift (+ive ACTION) - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if ($action > 0) { - push(@$stack, [ $action, $value ]); - $token = $value = undef; - redo; - }; - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # reduce (-ive ACTION) - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ($lhs, $len, $code) = @{ $rules->[ -$action ] }; - - # no action imples ACCEPTance - $action - or $status = ACCEPT; - - # use dummy sub if code ref doesn't exist - $code = sub { $_[1] } - unless $code; - - @codevars = $len - ? map { $_->[1] } @$stack[ -$len .. -1 ] - : (); - - eval { - $coderet = &$code( $self, @codevars ); - }; - if ($@) { - my $err = $@; - chomp $err; - return $self->_parse_error($err); - } - - # reduce stack by $len - splice(@$stack, -$len, $len); - - # ACCEPT - return $coderet ## RETURN ## - if $status == ACCEPT; - - # ABORT - return undef ## RETURN ## - if $status == ABORT; - - # ERROR - last - if $status == ERROR; - } - continue { - push(@$stack, [ $states->[ $stack->[-1][0] ]->{'GOTOS'}->{ $lhs }, - $coderet ]), - } - - # ERROR ## RETURN ## - return $self->_parse_error('unexpected end of input') - unless defined $value; - - # munge text of last directive to make it readable -# $text =~ s/\n/\\n/g; - - return $self->_parse_error("unexpected end of directive", $text) - if $value eq ';'; # end of directive SEPARATOR - - return $self->_parse_error("unexpected token ($value)", $text); -} - - - -#------------------------------------------------------------------------ -# _parse_error($msg, $dirtext) -# -# Method used to handle errors encountered during the parse process -# in the _parse() method. -#------------------------------------------------------------------------ - -sub _parse_error { - my ($self, $msg, $text) = @_; - my $line = $self->{ LINE }; - $line = ref($line) ? $$line : $line; - $line = 'unknown' unless $line; - - $msg .= "\n [% $text %]" - if defined $text; - - return $self->error("line $line: $msg"); -} - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method returns a string representing the internal state of the -# object. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $output = "[Template::Parser] {\n"; - my $format = " %-16s => %s\n"; - my $key; - - foreach $key (qw( START_TAG END_TAG TAG_STYLE ANYCASE INTERPOLATE - PRE_CHOMP POST_CHOMP V1DOLLAR )) { - my $val = $self->{ $key }; - $val = '<undef>' unless defined $val; - $output .= sprintf($format, $key, $val); - } - - $output .= '}'; - return $output; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Parser - LALR(1) parser for compiling template documents - -=head1 SYNOPSIS - - use Template::Parser; - - $parser = Template::Parser->new(\%config); - $template = $parser->parse($text) - || die $parser->error(), "\n"; - -=head1 DESCRIPTION - -The Template::Parser module implements a LALR(1) parser and associated methods -for parsing template documents into Perl code. - -=head1 PUBLIC METHODS - -=head2 new(\%params) - -The new() constructor creates and returns a reference to a new -Template::Parser object. A reference to a hash may be supplied as a -parameter to provide configuration values. These may include: - -=over - - - - -=item START_TAG, END_TAG - -The START_TAG and END_TAG options are used to specify character -sequences or regular expressions that mark the start and end of a -template directive. The default values for START_TAG and END_TAG are -'[%' and '%]' respectively, giving us the familiar directive style: - - [% example %] - -Any Perl regex characters can be used and therefore should be escaped -(or use the Perl C<quotemeta> function) if they are intended to -represent literal characters. - - my $parser = Template::Parser->new({ - START_TAG => quotemeta('<+'), - END_TAG => quotemeta('+>'), - }); - -example: - - <+ INCLUDE foobar +> - -The TAGS directive can also be used to set the START_TAG and END_TAG values -on a per-template file basis. - - [% TAGS <+ +> %] - - - - - - -=item TAG_STYLE - -The TAG_STYLE option can be used to set both START_TAG and END_TAG -according to pre-defined tag styles. - - my $parser = Template::Parser->new({ - TAG_STYLE => 'star', - }); - -Available styles are: - - template [% ... %] (default) - template1 [% ... %] or %% ... %% (TT version 1) - metatext %% ... %% (Text::MetaText) - star [* ... *] (TT alternate) - php <? ... ?> (PHP) - asp <% ... %> (ASP) - mason <% ... > (HTML::Mason) - html <!-- ... --> (HTML comments) - -Any values specified for START_TAG and/or END_TAG will over-ride -those defined by a TAG_STYLE. - -The TAGS directive may also be used to set a TAG_STYLE - - [% TAGS html %] - <!-- INCLUDE header --> - - - - - - -=item PRE_CHOMP, POST_CHOMP - -Anything outside a directive tag is considered plain text and is -generally passed through unaltered (but see the INTERPOLATE option). -This includes all whitespace and newlines characters surrounding -directive tags. Directives that don't generate any output will leave -gaps in the output document. - -Example: - - Foo - [% a = 10 %] - Bar - -Output: - - Foo - - Bar - -The PRE_CHOMP and POST_CHOMP options can help to clean up some of this -extraneous whitespace. Both are disabled by default. - - my $parser = Template::Parser->new({ - PRE_CHOMP => 1, - POST_CHOMP => 1, - }); - -With PRE_CHOMP set to 1, the newline and whitespace preceding a directive -at the start of a line will be deleted. This has the effect of -concatenating a line that starts with a directive onto the end of the -previous line. - - Foo <----------. - | - ,---(PRE_CHOMP)----' - | - `-- [% a = 10 %] --. - | - ,---(POST_CHOMP)---' - | - `-> Bar - -With POST_CHOMP set to 1, any whitespace after a directive up to and -including the newline will be deleted. This has the effect of joining -a line that ends with a directive onto the start of the next line. - -If PRE_CHOMP or POST_CHOMP is set to 2, then instead of removing all -the whitespace, the whitespace will be collapsed to a single space. -This is useful for HTML, where (usually) a contiguous block of -whitespace is rendered the same as a single space. - -You may use the CHOMP_NONE, CHOMP_ALL, and CHOMP_COLLAPSE constants -from the Template::Constants module to deactivate chomping, remove -all whitespace, or collapse whitespace to a single space. - -PRE_CHOMP and POST_CHOMP can be activated for individual directives by -placing a '-' immediately at the start and/or end of the directive. - - [% FOREACH user = userlist %] - [%- user -%] - [% END %] - -The '-' characters activate both PRE_CHOMP and POST_CHOMP for the one -directive '[%- name -%]'. Thus, the template will be processed as if -written: - - [% FOREACH user = userlist %][% user %][% END %] - -Note that this is the same as if PRE_CHOMP and POST_CHOMP were set -to CHOMP_ALL; the only way to get the CHOMP_COLLAPSE behavior is -to set PRE_CHOMP or POST_CHOMP accordingly. If PRE_CHOMP or POST_CHOMP -is already set to CHOMP_COLLAPSE, using '-' will give you CHOMP_COLLAPSE -behavior, not CHOMP_ALL behavior. - -Similarly, '+' characters can be used to disable PRE_CHOMP or -POST_CHOMP (i.e. leave the whitespace/newline intact) options on a -per-directive basis. - - [% FOREACH user = userlist %] - User: [% user +%] - [% END %] - -With POST_CHOMP enabled, the above example would be parsed as if written: - - [% FOREACH user = userlist %]User: [% user %] - [% END %] - - - - - -=item INTERPOLATE - -The INTERPOLATE flag, when set to any true value will cause variable -references in plain text (i.e. not surrounded by START_TAG and END_TAG) -to be recognised and interpolated accordingly. - - my $parser = Template::Parser->new({ - INTERPOLATE => 1, - }); - -Variables should be prefixed by a '$' to identify them. Curly braces -can be used in the familiar Perl/shell style to explicitly scope the -variable name where required. - - # INTERPOLATE => 0 - <a href="http://[% server %]/[% help %]"> - <img src="[% images %]/help.gif"></a> - [% myorg.name %] - - # INTERPOLATE => 1 - <a href="http://$server/$help"> - <img src="$images/help.gif"></a> - $myorg.name - - # explicit scoping with { } - <img src="$images/${icon.next}.gif"> - -Note that a limitation in Perl's regex engine restricts the maximum length -of an interpolated template to around 32 kilobytes or possibly less. Files -that exceed this limit in size will typically cause Perl to dump core with -a segmentation fault. If you routinely process templates of this size -then you should disable INTERPOLATE or split the templates in several -smaller files or blocks which can then be joined backed together via -PROCESS or INCLUDE. - - - - - - - -=item ANYCASE - -By default, directive keywords should be expressed in UPPER CASE. The -ANYCASE option can be set to allow directive keywords to be specified -in any case. - - # ANYCASE => 0 (default) - [% INCLUDE foobar %] # OK - [% include foobar %] # ERROR - [% include = 10 %] # OK, 'include' is a variable - - # ANYCASE => 1 - [% INCLUDE foobar %] # OK - [% include foobar %] # OK - [% include = 10 %] # ERROR, 'include' is reserved word - -One side-effect of enabling ANYCASE is that you cannot use a variable -of the same name as a reserved word, regardless of case. The reserved -words are currently: - - GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER - IF UNLESS ELSE ELSIF FOR FOREACH WHILE SWITCH CASE - USE PLUGIN FILTER MACRO PERL RAWPERL BLOCK META - TRY THROW CATCH FINAL NEXT LAST BREAK RETURN STOP - CLEAR TO STEP AND OR NOT MOD DIV END - - -The only lower case reserved words that cannot be used for variables, -regardless of the ANYCASE option, are the operators: - - and or not mod div - - - - - - - - -=item V1DOLLAR - -In version 1 of the Template Toolkit, an optional leading '$' could be placed -on any template variable and would be silently ignored. - - # VERSION 1 - [% $foo %] === [% foo %] - [% $hash.$key %] === [% hash.key %] - -To interpolate a variable value the '${' ... '}' construct was used. -Typically, one would do this to index into a hash array when the key -value was stored in a variable. - -example: - - my $vars = { - users => { - aba => { name => 'Alan Aardvark', ... }, - abw => { name => 'Andy Wardley', ... }, - ... - }, - uid => 'aba', - ... - }; - - $template->process('user/home.html', $vars) - || die $template->error(), "\n"; - -'user/home.html': - - [% user = users.${uid} %] # users.aba - Name: [% user.name %] # Alan Aardvark - -This was inconsistent with double quoted strings and also the -INTERPOLATE mode, where a leading '$' in text was enough to indicate a -variable for interpolation, and the additional curly braces were used -to delimit variable names where necessary. Note that this use is -consistent with UNIX and Perl conventions, among others. - - # double quoted string interpolation - [% name = "$title ${user.name}" %] - - # INTERPOLATE = 1 - <img src="$images/help.gif"></a> - <img src="$images/${icon.next}.gif"> - -For version 2, these inconsistencies have been removed and the syntax -clarified. A leading '$' on a variable is now used exclusively to -indicate that the variable name should be interpolated -(e.g. subsituted for its value) before being used. The earlier example -from version 1: - - # VERSION 1 - [% user = users.${uid} %] - Name: [% user.name %] - -can now be simplified in version 2 as: - - # VERSION 2 - [% user = users.$uid %] - Name: [% user.name %] - -The leading dollar is no longer ignored and has the same effect of -interpolation as '${' ... '}' in version 1. The curly braces may -still be used to explicitly scope the interpolated variable name -where necessary. - -e.g. - - [% user = users.${me.id} %] - Name: [% user.name %] - -The rule applies for all variables, both within directives and in -plain text if processed with the INTERPOLATE option. This means that -you should no longer (if you ever did) add a leading '$' to a variable -inside a directive, unless you explicitly want it to be interpolated. - -One obvious side-effect is that any version 1 templates with variables -using a leading '$' will no longer be processed as expected. Given -the following variable definitions, - - [% foo = 'bar' - bar = 'baz' - %] - -version 1 would interpret the following as: - - # VERSION 1 - [% $foo %] => [% GET foo %] => bar - -whereas version 2 interprets it as: - - # VERSION 2 - [% $foo %] => [% GET $foo %] => [% GET bar %] => baz - -In version 1, the '$' is ignored and the value for the variable 'foo' is -retrieved and printed. In version 2, the variable '$foo' is first interpolated -to give the variable name 'bar' whose value is then retrieved and printed. - -The use of the optional '$' has never been strongly recommended, but -to assist in backwards compatibility with any version 1 templates that -may rely on this "feature", the V1DOLLAR option can be set to 1 -(default: 0) to revert the behaviour and have leading '$' characters -ignored. - - my $parser = Template::Parser->new({ - V1DOLLAR => 1, - }); - - - - - - -=item GRAMMAR - -The GRAMMAR configuration item can be used to specify an alternate -grammar for the parser. This allows a modified or entirely new -template language to be constructed and used by the Template Toolkit. - -Source templates are compiled to Perl code by the Template::Parser -using the Template::Grammar (by default) to define the language -structure and semantics. Compiled templates are thus inherently -"compatible" with each other and there is nothing to prevent any -number of different template languages being compiled and used within -the same Template Toolkit processing environment (other than the usual -time and memory constraints). - -The Template::Grammar file is constructed from a YACC like grammar -(using Parse::YAPP) and a skeleton module template. These files are -provided, along with a small script to rebuild the grammar, in the -'parser' sub-directory of the distribution. You don't have to know or -worry about these unless you want to hack on the template language or -define your own variant. There is a README file in the same directory -which provides some small guidance but it is assumed that you know -what you're doing if you venture herein. If you grok LALR parsers, -then you should find it comfortably familiar. - -By default, an instance of the default Template::Grammar will be -created and used automatically if a GRAMMAR item isn't specified. - - use MyOrg::Template::Grammar; - - my $parser = Template::Parser->new({ - GRAMMAR = MyOrg::Template::Grammar->new(); - }); - - - -=item DEBUG - -The DEBUG option can be used to enable various debugging features -of the Template::Parser module. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_PARSER | DEBUG_DIRS, - }); - -The DEBUG value can include any of the following. Multiple values -should be combined using the logical OR operator, '|'. - -=over 4 - -=item DEBUG_PARSER - -This flag causes the L<Template::Parser|Template::Parser> to generate -debugging messages that show the Perl code generated by parsing and -compiling each template. - -=item DEBUG_DIRS - -This option causes the Template Toolkit to generate comments -indicating the source file, line and original text of each directive -in the template. These comments are embedded in the template output -using the format defined in the DEBUG_FORMAT configuration item, or a -simple default format if unspecified. - -For example, the following template fragment: - - - Hello World - -would generate this output: - - ## input text line 1 : ## - Hello - ## input text line 2 : World ## - World - - -=back - - - - -=back - -=head2 parse($text) - -The parse() method parses the text passed in the first parameter and -returns a reference to a Template::Document object which contains the -compiled representation of the template text. On error, undef is -returned. - -Example: - - $doc = $parser->parse($text) - || die $parser->error(); - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - - - -=head1 VERSION - -2.81, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -The original Template::Parser module was derived from a standalone -parser generated by version 0.16 of the Parse::Yapp module. The -following copyright notice appears in the Parse::Yapp documentation. - - The Parse::Yapp module and its related modules and shell - scripts are copyright (c) 1998 Francois Desarmenien, - France. All rights reserved. - - You may use and distribute them under the terms of either - the GNU General Public License or the Artistic License, as - specified in the Perl README file. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Grammar|Template::Grammar>, L<Template::Directive|Template::Directive> - diff --git a/lib/Template/Plugin.pm b/lib/Template/Plugin.pm deleted file mode 100644 index a6c9df2..0000000 --- a/lib/Template/Plugin.pm +++ /dev/null @@ -1,409 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin -# -# DESCRIPTION -# -# Module defining a base class for a plugin object which can be loaded -# and instantiated via the USE directive. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Plugin.pm,v 2.65 2004/01/13 16:19:15 abw Exp $ -# -#============================================================================ - -package Template::Plugin; - -require 5.004; - -use strict; -use Template::Base; - -use vars qw( $VERSION $DEBUG $ERROR $AUTOLOAD ); -use base qw( Template::Base ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.65 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0; - - -#======================================================================== -# ----- CLASS METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# load() -# -# Class method called when the plugin module is first loaded. It -# returns the name of a class (by default, its own class) or a prototype -# object which will be used to instantiate new objects. The new() -# method is then called against the class name (class method) or -# prototype object (object method) to create a new instances of the -# object. -#------------------------------------------------------------------------ - -sub load { - return $_[0]; -} - - -#------------------------------------------------------------------------ -# new($context, $delegate, @params) -# -# Object constructor which is called by the Template::Context to -# instantiate a new Plugin object. This base class constructor is -# used as a general mechanism to load and delegate to other Perl -# modules. The context is passed as the first parameter, followed by -# a reference to a delegate object or the name of the module which -# should be loaded and instantiated. Any additional parameters passed -# to the USE directive are forwarded to the new() constructor. -# -# A plugin object is returned which has an AUTOLOAD method to delegate -# requests to the underlying object. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - bless { - }, $class; -} - -sub old_new { - my ($class, $context, $delclass, @params) = @_; - my ($delegate, $delmod); - - return $class->error("no context passed to $class constructor\n") - unless defined $context; - - if (ref $delclass) { - # $delclass contains a reference to a delegate object - $delegate = $delclass; - } - else { - # delclass is the name of a module to load and instantiate - ($delmod = $delclass) =~ s|::|/|g; - - eval { - require "$delmod.pm"; - $delegate = $delclass->new(@params) - || die "failed to instantiate $delclass object\n"; - }; - return $class->error($@) if $@; - } - - bless { - _CONTEXT => $context, - _DELEGATE => $delegate, - _PARAMS => \@params, - }, $class; -} - - -#------------------------------------------------------------------------ -# fail($error) -# -# Version 1 error reporting function, now replaced by error() inherited -# from Template::Base. Raises a "deprecated function" warning and then -# calls error(). -#------------------------------------------------------------------------ - -sub fail { - my $class = shift; - my ($pkg, $file, $line) = caller(); - warn "Template::Plugin::fail() is deprecated at $file line $line. Please use error()\n"; - $class->error(@_); -} - - -#======================================================================== -# ----- OBJECT METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# AUTOLOAD -# -# General catch-all method which delegates all calls to the _DELEGATE -# object. -#------------------------------------------------------------------------ - -sub OLD_AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; - - if (ref $self eq 'HASH') { - my $delegate = $self->{ _DELEGATE } || return; - return $delegate->$method(@_); - } - my ($pkg, $file, $line) = caller(); -# warn "no such '$method' method called on $self at $file line $line\n"; - return undef; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin - Base class for Template Toolkit plugins - -=head1 SYNOPSIS - - package MyOrg::Template::Plugin::MyPlugin; - use base qw( Template::Plugin ); - use Template::Plugin; - use MyModule; - - sub new { - my $class = shift; - my $context = shift; - bless { - ... - }, $class; - } - -=head1 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', - }); - -=head1 PLUGIN API - -The following methods form the basic interface between the Template -Toolkit and plugin modules. - -=over 4 - -=item 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' - } - -=item 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 - } - -=item error($error) - -This method, inherited from the Template::Base module, is used for -reporting and returning errors. It can be called as a package method -to set/return the $ERROR package variable, or as an object method to -set/return the object _ERROR member. When called with an argument, it -sets the relevant variable and returns undef. When called without an -argument, it returns the value of the variable. - - sub new { - my ($class, $context, $dsn) = @_; - - return $class->error('No data source specified') - unless $dsn; - - bless { - _DSN => $dsn, - }, $class; - } - - ... - - my $something = MyModule->new() - || die MyModule->error(), "\n"; - - $something->do_something() - || die $something->error(), "\n"; - -=back - -=head1 DEEPER MAGIC - -The Template::Context object that handles the loading and use of -plugins calls the new() 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() and error() are then called as -I<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. - -=head1 Template::Plugin Delegation - -As of version 2.01, the Template::Plugin module no longer provides an -AUTOLOAD method to delegate to other objects or classes. This was a -badly designed feature that caused more trouble than good. You can -easily add your own AUTOLOAD method to perform delegation if you -require this kind of functionality. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.65, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Plugins|Template::Plugins>, L<Template::Context|Template::Context> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Autoformat.pm b/lib/Template/Plugin/Autoformat.pm deleted file mode 100644 index b7153e4..0000000 --- a/lib/Template/Plugin/Autoformat.pm +++ /dev/null @@ -1,242 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Autoformat -# -# DESCRIPTION -# Plugin interface to Damian Conway's Text::Autoformat module. -# -# AUTHORS -# Robert McArthur <mcarthur@dstc.edu.au> -# - original plugin code -# -# Andy Wardley <abw@kfs.org> -# - added FILTER registration, support for forms and some additional -# documentation -# -# COPYRIGHT -# Copyright (C) 2000 Robert McArthur & 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Autoformat.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Autoformat; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; -use Text::Autoformat; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - -sub new { - my ($class, $context, $options) = @_; - my $filter_factory; - my $plugin; - - if ($options) { - # create a closure to generate filters with additional options - $filter_factory = sub { - my $context = shift; - my $filtopt = ref $_[-1] eq 'HASH' ? pop : { }; - @$filtopt{ keys %$options } = values %$options; - return sub { - tt_autoformat(@_, $filtopt); - }; - }; - - # and a closure to represent the plugin - $plugin = sub { - my $plugopt = ref $_[-1] eq 'HASH' ? pop : { }; - @$plugopt{ keys %$options } = values %$options; - tt_autoformat(@_, $plugopt); - }; - } - else { - # simple filter factory closure (no legacy options from constructor) - $filter_factory = sub { - my $context = shift; - my $filtopt = ref $_[-1] eq 'HASH' ? pop : { }; - return sub { - tt_autoformat(@_, $filtopt); - }; - }; - - # plugin without options can be static - $plugin = \&tt_autoformat; - } - - # now define the filter and return the plugin - $context->define_filter('autoformat', [ $filter_factory => 1 ]); - return $plugin; -} - -sub tt_autoformat { - my $options = ref $_[-1] eq 'HASH' ? pop : { }; - my $form = $options->{ form }; - my $out = $form ? Text::Autoformat::form($options, $form, @_) - : Text::Autoformat::autoformat(join('', @_), $options); - return $out; -} - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Autoformat - Interface to Text::Autoformat module - -=head1 SYNOPSIS - - [% USE autoformat(options) %] - - [% autoformat(text, more_text, ..., options) %] - - [% FILTER autoformat(options) %] - a block of text - [% END %] - -=head1 EXAMPLES - - # define some text for the examples - [% text = BLOCK %] - Be not afeard. The isle is full of noises, sounds and sweet - airs that give delight but hurt not. - [% END %] - - # pass options to constructor... - [% USE autoformat(case => 'upper') %] - [% autoformat(text) %] - - # and/or pass options to the autoformat subroutine itself - [% USE autoformat %] - [% autoformat(text, case => 'upper') %] - - # using the autoformat filter - [% USE autoformat(left => 10, right => 30) %] - [% FILTER autoformat %] - Be not afeard. The isle is full of noises, sounds and sweet - airs that give delight but hurt not. - [% END %] - - # another filter example with configuration options - [% USE autoformat %] - [% FILTER autoformat(left => 20) %] - Be not afeard. The isle is full of noises, sounds and sweet - airs that give delight but hurt not. - [% END %] - - # another FILTER example, defining a 'poetry' filter alias - [% USE autoformat %] - [% text FILTER poetry = autoformat(left => 20, right => 40) %] - - # reuse the 'poetry' filter alias - [% text FILTER poetry %] - - # shorthand form ('|' is an alias for 'FILTER') - [% text | autoformat %] - - # using forms - [% USE autoformat(form => '>>>>.<<<', numeric => 'AllPlaces') %] - [% autoformat(10, 20.32, 11.35) %] - -=head1 DESCRIPTION - -The autoformat plugin is an interface to Damian Conway's Text::Autoformat -Perl module which provides advanced text wrapping and formatting. - -Configuration options may be passed to the plugin constructor via the -USE directive. - - [% USE autoformat(right => 30) %] - -The autoformat subroutine can then be called, passing in text items which -will be wrapped and formatted according to the current configuration. - - [% autoformat('The cat sat on the mat') %] - -Additional configuration items can be passed to the autoformat subroutine -and will be merged with any existing configuration specified via the -constructor. - - [% autoformat(text, left => 20) %] - -Configuration options are passed directly to the Text::Autoformat plugin. -At the time of writing, the basic configuration items are: - - left left margin (default: 1) - right right margin (default 72) - justify justification as one of 'left', 'right', 'full' - or 'centre' (default: left) - case case conversion as one of 'lower', 'upper', - 'sentence', 'title', or 'highlight' (default: none) - squeeze squeeze whitespace (default: enabled) - -The plugin also accepts a 'form' item which can be used to define a -format string. When a form is defined, the plugin will call the -underlying form() subroutine in preference to autoformat(). - - [% USE autoformat(form => '>>>>.<<') %] - [% autoformat(123.45, 666, 3.14) %] - -Additional configuration items relevant to forms can also be specified. - - [% USE autoformat(form => '>>>>.<<', numeric => 'AllPlaces') %] - [% autoformat(123.45, 666, 3.14) %] - -These can also be passed directly to the autoformat subroutine. - - [% USE autoformat %] - [% autoformat( 123.45, 666, 3.14, - form => '>>>>.<<', - numeric => 'AllPlaces' ) - %] - -See L<Text::Autoformat> for further details. - -=head1 AUTHORS - -Robert McArthur E<lt>mcarthur@dstc.edu.auE<gt> wrote the original plugin -code, with some modifications and additions from Andy Wardley -E<lt>abw@wardley.orgE<gt>. - -Damian Conway E<lt>damian@conway.orgE<gt> wrote the Text::Autoformat -module (in his copious spare time :-) which does all the clever stuff. - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - -Copyright (C) 2000 Robert McArthur & 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Text::Autoformat|Text::Autoformat> - diff --git a/lib/Template/Plugin/CGI.pm b/lib/Template/Plugin/CGI.pm deleted file mode 100644 index 53b19d8..0000000 --- a/lib/Template/Plugin/CGI.pm +++ /dev/null @@ -1,168 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::CGI -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the CGI.pm module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: CGI.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::CGI; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; -use CGI; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - -sub new { - my $class = shift; - my $context = shift; - CGI->new(@_); -} - -package CGI; - -sub params { - my $self = shift; - local $" = ', '; - - return $self->{ _TT_PARAMS } ||= do { - # must call Vars() in a list context to receive - # plain list of key/vals rather than a tied hash - my $params = { $self->Vars() }; - - # convert any null separated values into lists - @$params{ keys %$params } = map { - /\0/ ? [ split /\0/ ] : $_ - } values %$params; - - $params; - }; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::CGI - Interface to the CGI module - -=head1 SYNOPSIS - - [% USE CGI %] - [% CGI.param('parameter') %] - - [% USE things = CGI %] - [% things.param('name') %] - - # see CGI docs for other methods provided by the CGI object - -=head1 DESCRIPTION - -This is a very simple Template Toolkit Plugin interface to the CGI module. -A CGI object will be instantiated via the following directive: - - [% USE CGI %] - -CGI methods may then be called as follows: - - [% CGI.header %] - [% CGI.param('parameter') %] - -An alias can be used to provide an alternate name by which the object should -be identified. - - [% USE mycgi = CGI %] - [% mycgi.start_form %] - [% mycgi.popup_menu({ Name => 'Color' - Values => [ 'Green' 'Black' 'Brown' ] }) %] - -Parenthesised parameters to the USE directive will be passed to the plugin -constructor: - - [% USE cgiprm = CGI('uid=abw&name=Andy+Wardley') %] - [% cgiprm.param('uid') %] - -=head1 METHODS - -In addition to all the methods supported by the CGI module, this -plugin defines the following. - -=head2 params() - -This method returns a reference to a hash of all the CGI parameters. -Any parameters that have multiple values will be returned as lists. - - [% USE CGI('user=abw&item=foo&item=bar') %] - - [% CGI.params.user %] # abw - [% CGI.params.item.join(', ') %] # foo, bar - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<CGI|CGI> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/DBI.pm b/lib/Template/Plugin/DBI.pm deleted file mode 100644 index b916bfc..0000000 --- a/lib/Template/Plugin/DBI.pm +++ /dev/null @@ -1,947 +0,0 @@ -#============================================================================== -# -# Template::Plugin::DBI -# -# DESCRIPTION -# A Template Toolkit plugin to provide access to a DBI data source. -# -# AUTHORS -# Original version by Simon Matthews <sam@knowledgepool.com> -# with some reworking by Andy Wardley <abw@kfs.org> and other -# contributions from Craig Barratt <craig@arraycomm.com>, -# Dave Hodgkinson <daveh@davehodgkinson.com> and Rafael Kitover -# <caelum@debian.org> -# -# COPYRIGHT -# Copyright (C) 1999-2000 Simon Matthews. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# $Id: DBI.pm,v 2.62 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================== - -package Template::Plugin::DBI; - -require 5.004; - -use strict; -use Template::Plugin; -use Template::Exception; -use DBI; - -use vars qw( $VERSION $DEBUG $QUERY $ITERATOR ); -use base qw( Template::Plugin ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.62 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; -$QUERY = 'Template::Plugin::DBI::Query'; -$ITERATOR = 'Template::Plugin::DBI::Iterator'; - -# alias _connect() to connect() for backwards compatability -*_connect = \*connect; - - -#------------------------------------------------------------------------ -# new($context, @params) -# -# Constructor which returns a reference to a new DBI plugin object. -# A connection string (dsn), user name and password may be passed as -# positional arguments or a hash array of connection parameters can be -# passed to initialise a connection. Otherwise, an unconnected DBI -# plugin object is returned. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $self = ref $class ? $class : bless { - _CONTEXT => $context, - _STH => [ ], - }, $class; - - $self->connect(@_) if @_; - - return $self; -} - - -#------------------------------------------------------------------------ -# connect( $data_source, $username, $password, $attributes ) -# connect( { data_source => 'dbi:driver:database' -# username => 'foo' -# password => 'bar' } ) -# -# Opens a DBI connection for the plugin. -#------------------------------------------------------------------------ - -sub connect { - my $self = shift; - my $params = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my ($dbh, $dsn, $user, $pass, $klobs); - - # set debug flag - $DEBUG = $params->{ debug } if exists $params->{ debug }; - $self->{ _DEBUG } = $params->{ debug } || 0; - - # fetch 'dbh' named paramater or use positional arguments or named - # parameters to specify 'dsn', 'user' and 'pass' - - if ($dbh = $params->{ dbh }) { - # disconnect any existing database handle that we previously opened - $self->{ _DBH }->disconnect() - if $self->{ _DBH } && $self->{ _DBH_CONNECT }; - - # store new dbh but leave _DBH_CONNECT false to prevent us - # from automatically closing it in the future - $self->{ _DBH } = $dbh; - $self->{ _DBH_CONNECT } = 0; - } - else { - - # certain Perl programmers are known to have problems with short - # term memory loss (see Tie::Hash::Cannabinol) so we let the poor - # blighters fumble any kind of argument that looks like it might - # identify the database - - $dsn = shift - || $params->{ data_source } - || $params->{ database } - || $params->{ connect } - || $params->{ dsn } - || $params->{ db } - || $ENV{DBI_DSN} - || return $self->_throw('data source not defined'); - - # add 'dbi:' prefix if it's not there - $dsn = "dbi:$dsn" unless $dsn =~ /^dbi:/i; - - $user = shift - || $params->{ username } - || $params->{ user }; - - $pass = shift - || $params->{ password } - || $params->{ pass }; - - # save connection data because we might need it later to do a tie() - @$self{ qw( _DSN _USER _PASS ) } = ($dsn, $user, $pass); - - # reuse existing database handle if connection params match - my $connect = join(':', $dsn || '', $user || '', $pass || ''); - return '' - if $self->{ _DBH } && $self->{ _DBH_CONNECT } eq $connect; - - # otherwise disconnect any existing database handle that we opened - $self->{ _DBH }->disconnect() - if $self->{ _DBH } && $self->{ _DBH_CONNECT }; - - # don't need DBI to automatically print errors because all calls go - # via this plugin interface and we always check return values - $params->{ PrintError } = 0 - unless defined $params->{ PrintError }; - - $self->{ _DBH } = DBI->connect_cached( $dsn, $user, $pass, $params ) - || return $self->_throw("DBI connect failed: $DBI::errstr"); - - # store the connection parameters - $self->{ _DBH_CONNECT } = $connect; - } - - return ''; -} - - -#------------------------------------------------------------------------ -# disconnect() -# -# Disconnects the current active database connection. -#------------------------------------------------------------------------ - -sub disconnect { - my $self = shift; - $self->{ _DBH }->disconnect() - if $self->{ _DBH }; - delete $self->{ _DBH }; - return ''; -} - - -#------------------------------------------------------------------------ -# tie( $table, $key ) -# -# Return a hash tied to a table in the database, indexed by the specified -# key. -#------------------------------------------------------------------------ - -sub tie { - my $self = shift; - my $params = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my ($table, $key, $klobs, $debug, %hash); - - eval { require Tie::DBI }; - $self->_throw("failed to load Tie::DBI module: $@") if $@; - - $table = shift - || $params->{ table } - || $self->_throw('table not defined'); - - $key = shift - || $params->{ key } - || $self->_throw('key not defined'); - - # Achtung der Klobberman! - $klobs = $params->{ clobber }; - $klobs = $params->{ CLOBBER } unless defined $klobs; - - # going the extra mile to allow user to use UPPER or lower case or - # inherit internel debug flag set by connect() - $debug = $params->{ debug }; - $debug = $params->{ DEBUG } unless defined $debug; - $debug = $self->{ _DEBUG } unless defined $debug; - - tie %hash, 'Tie::DBI', { - %$params, # any other Tie::DBI options like DEBUG, WARN, etc - db => $self->{ _DBH } || $self->{ _DSN }, - user => $self->{ _USER }, - password => $self->{ _PASS }, - table => $table, - key => $key, - CLOBBER => $klobs || 0, - DEBUG => $debug || 0, - }; - - return \%hash; -} - - -#------------------------------------------------------------------------ -# prepare($sql) -# -# Prepare a query and store the live statement handle internally for -# subsequent execute() calls. -#------------------------------------------------------------------------ - -sub prepare { - my $self = shift; - my $sql = shift || return undef; - - my $sth = $self->dbh->prepare($sql) - || return $self->_throw("DBI prepare failed: $DBI::errstr"); - - # create wrapper object around handle to return to template client - $sth = $QUERY->new($sth); - push(@{ $self->{ _STH } }, $sth); - - return $sth; -} - - -#------------------------------------------------------------------------ -# execute() -# -# Calls execute() on the most recent statement created via prepare(). -#------------------------------------------------------------------------ - -sub execute { - my $self = shift; - - my $sth = $self->{ _STH }->[-1] - || return $self->_throw('no query prepared'); - - $sth->execute(@_); -} - - -#------------------------------------------------------------------------ -# query($sql, @params) -# -# Prepares and executes a SQL query. -#------------------------------------------------------------------------ - -sub query { - my $self = shift; - my $sql = shift; - - $self->prepare($sql)->execute(@_); -} - - -#------------------------------------------------------------------------ -# do($sql, \%attr, @bind) -# -# Prepares and executes a SQL statement. -#------------------------------------------------------------------------ - -sub do { - my $self = shift; - - return $self->dbh->do(@_) - || $self->_throw("DBI do failed: $DBI::errstr"); -} - - -#------------------------------------------------------------------------ -# quote($value [, $data_type ]) -# -# Returns a quoted string (correct for the connected database) from the -# value passed in. -#------------------------------------------------------------------------ - -sub quote { - my $self = shift; - $self->dbh->quote(@_); -} - - -#------------------------------------------------------------------------ -# dbh() -# -# Internal method to retrieve the database handle belonging to the -# instance or attempt to create a new one using connect. -#------------------------------------------------------------------------ - -sub dbh { - my $self = shift; - - return $self->{ _DBH } || do { - $self->connect; - $self->{ _DBH }; - }; -} - - -#------------------------------------------------------------------------ -# DESTROY -# -# Called automatically when the plugin object goes out of scope to -# disconnect the database handle cleanly -#------------------------------------------------------------------------ - -sub DESTROY { - my $self = shift; - delete($self->{ _STH }); # first DESTROY any queries - $self->{ _DBH }->disconnect() - if $self->{ _DBH } && $self->{ _DBH_CONNECT }; -} - - -#------------------------------------------------------------------------ -# _throw($error) -# -# Raise an error by throwing it via die() as a Template::Exception -# object of type 'DBI'. -#------------------------------------------------------------------------ - -sub _throw { - my $self = shift; - my $error = shift || die "DBI throw() called without an error string\n"; - - # throw error as DBI exception - die (Template::Exception->new('DBI', $error)); -} - - -#======================================================================== -# Template::Plugin::DBI::Query -#======================================================================== - -package Template::Plugin::DBI::Query; -use vars qw( $DEBUG $ITERATOR ); - -*DEBUG = \$Template::Plugin::DBI::DEBUG; -*ITERATOR = \$Template::Plugin::DBI::ITERATOR; - - -sub new { - my ($class, $sth) = @_; - bless \$sth, $class; -} - -sub execute { - my $self = shift; - - $$self->execute(@_) - || return Template::Plugin::DBI->_throw("execute failed: $DBI::errstr"); - - $ITERATOR->new($$self); -} - -sub DESTROY { - my $self = shift; - $$self->finish(); -} - - -#======================================================================== -# Template::Plugin::DBI::Iterator; -#======================================================================== - -package Template::Plugin::DBI::Iterator; - -use Template::Iterator; -use base qw( Template::Iterator ); -use vars qw( $DEBUG ); - -*DEBUG = \$Template::Plugin::DBI::DEBUG; - - -sub new { - my ($class, $sth, $params) = @_; - - my $rows = $sth->rows(); - - my $self = bless { - _STH => $sth, - SIZE => $rows, - MAX => $rows - 1, - }, $class; - - - return $self; -} - - -#------------------------------------------------------------------------ -# get_first() -# -# Initialises iterator to read from statement handle. We maintain a -# one-record lookahead buffer to allow us to detect if the current -# record is the last in the series. -#------------------------------------------------------------------------ - -sub get_first { - my $self = shift; - $self->{ _STARTED } = 1; - - # set some status variables into $self - @$self{ qw( PREV ITEM FIRST LAST COUNT INDEX ) } - = ( undef, undef, 2, 0, 0, -1 ); - - # support 'number' as an alias for 'count' for backwards compatability - $self->{ NUMBER } = 0; - - print STDERR "get_first() called\n" if $DEBUG; - - # get the first row - $self->_fetchrow(); - - print STDERR "get_first() calling get_next()\n" if $DEBUG; - - return $self->get_next(); -} - - -#------------------------------------------------------------------------ -# get_next() -# -# Called to read remaining result records from statement handle. -#------------------------------------------------------------------------ - -sub get_next { - my $self = shift; - my ($data, $fixup); - - # increment the 'index' and 'count' counts - $self->{ INDEX }++; - $self->{ COUNT }++; - $self->{ NUMBER }++; # 'number' is old name for 'count' - - # decrement the 'first-record' flag - $self->{ FIRST }-- if $self->{ FIRST }; - - # we should have a row already cache in NEXT - return (undef, Template::Constants::STATUS_DONE) - unless $data = $self->{ NEXT }; - - # set PREV to be current ITEM from last iteration - $self->{ PREV } = $self->{ ITEM }; - - # look ahead to the next row so that the rowcache is refilled - $self->_fetchrow(); - - $self->{ ITEM } = $data; - return ($data, Template::Constants::STATUS_OK); -} - - -sub get { - my $self = shift; - my ($data, $error); - - ($data, $error) = $self->{ _STARTED } - ? $self->get_next() : $self->get_first(); - - return $data; -} - - -sub get_all { - my $self = shift; - my $sth = $self->{ _STH }; - my $error; - - my $data = $sth->fetchall_arrayref({}); - $self->throw($error) if ($error = $sth->err()); - unshift(@$data, $self->{ NEXT }) if $self->{ NEXT }; - $self->{ LAST } = 1; - $self->{ NEXT } = undef; - $sth->finish(); - - return $data; -} - - -#------------------------------------------------------------------------ -# _fetchrow() -# -# Retrieve a record from the statement handle and store in row cache. -#------------------------------------------------------------------------ - -sub _fetchrow { - my $self = shift; - my $sth = $self->{ _STH }; - - my $data = $sth->fetchrow_hashref() || do { - $self->{ LAST } = 1; - $self->{ NEXT } = undef; - $sth->finish(); - return; - }; - $self->{ NEXT } = $data; - return; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::DBI - Template interface to the DBI module - -=head1 SYNOPSIS - -Making an implicit database connection: - - # ...using positional arguments - [% USE DBI('dbi:driver:dbname', 'user', 'pass') %] - - # ...using named parameters - [% USE DBI( database = 'dbi:driver:dbname', - username = 'user', - password = 'pass' ) - %] - - # ...using short named parameters (4 lzy ppl and bad typsits) - [% USE DBI( db = 'driver:dbname', - user = 'user', - pass = 'pass' ) - %] - - # ...or an existing DBI database handle - [% USE DBI( dbh = my_dbh_ref ) %] - -Making explicit database connections: - - [% USE DBI %] - - [% DBI.connect(db, user, pass) %] - ... - - [% DBI.connect(new_db, new_user, new_pass) %] - ... - - [% DBI.disconnect %] # final disconnect is optional - -Making an automagical database connection using DBI_DSN environment variable: - - [% USE DBI %] - -Making database queries: - - # single step query - [% FOREACH user = DBI.query('SELECT * FROM users') %] - [% user.uid %] blah blah [% user.name %] etc. etc. - [% END %] - - # two stage prepare/execute - [% query = DBI.prepare('SELECT * FROM users WHERE uid = ?') %] - - [% FOREACH user = query.execute('sam') %] - ... - [% END %] - - [% FOREACH user = query.execute('abw') %] - ... - [% END %] - -Making non-SELECT statements: - - [% IF DBI.do("DELETE FROM users WHERE uid = '$uid'") %] - The user '[% uid %]' was successfully deleted. - [% END %] - -Using named DBI connections: - - [% USE one = DBI(...) %] - [% USE two = DBI(...) %] - - [% FOREACH item = one.query("SELECT ...etc...") %] - ... - [% END %] - - [% FOREACH item = two.query("SELECT ...etc...") %] - ... - [% END %] - -Tieing to a database table (via Tie::DBI): - - [% people = DBI.tie('users', 'uid') %] - - [% me = people.abw %] # => SELECT * FROM users WHERE uid='abw' - - I am [% me.name %] - - # clobber option allows table updates (see Tie::DBI) - [% people = DBI.tie('users', 'uid', clobber=1) %] - - [% people.abw.name = 'not a number' %] - - I am [% people.abw.name %] # I am a free man! - -=head1 DESCRIPTION - -This Template Toolkit plugin module provides an interface to the Perl -DBI/DBD modules, allowing you to integrate SQL queries into your -template documents. It also provides an interface via the Tie::DBI -module (if installed on your system) so that you can access database -records without having to embed any SQL in your templates. - -A DBI plugin object can be created as follows: - - [% USE DBI %] - -This creates an uninitialised DBI object. You can then open a connection -to a database using the connect() method. - - [% DBI.connect('dbi:driver:dbname', 'user', 'pass') %] - -The DBI connection can be opened when the plugin is created by passing -arguments to the constructor, called from the USE directive. - - [% USE DBI('dbi:driver:dbname', 'user', 'pass') %] - -You can also use named parameters to provide the data source connection -string, user name and password. - - [% USE DBI(database => 'dbi:driver:dbname', - username => 'user', - password => 'pass') %] - -For backwards compatability with previous versions of this plugin, you can -also spell 'database' as 'data_source'. - - [% USE DBI(data_source => 'dbi:driver:dbname', - username => 'user', - password => 'pass') %] - -Lazy Template hackers may prefer to use 'db', 'dsn' or 'connect' as a -shorthand form of the 'database' parameter, and 'user' and 'pass' as -shorthand forms of 'username' and 'password', respectively. You can -also drop the 'dbi:' prefix from the database connect string because -the plugin will add it on for you automagically. - - [% USE DBI(db => 'driver:dbname', - user => 'user', - pass => 'pass') %] - -Any additional DBI attributes can be specified as named parameters. -The 'PrintError' attribute defaults to 0 unless explicitly set true. - - [% USE DBI(db, user, pass, ChopBlanks=1) %] - -An alternate variable name can be provided for the plugin as per regular -Template Toolkit syntax: - - [% USE mydb = DBI('dbi:driver:dbname', 'user', 'pass') %] - - [% FOREACH item = mydb.query('SELECT * FROM users') %] - ... - [% END %] - -You can also specify the DBI plugin name in lower case if you prefer: - - [% USE dbi(dsn, user, pass) %] - - [% FOREACH item = dbi.query('SELECT * FROM users') %] - ... - [% END %] - -The disconnect() method can be called to explicitly disconnect the -current database, but this generally shouldn't be necessary as it is -called automatically when the plugin goes out of scope. You can call -connect() at any time to open a connection to another database. The -previous connection will be closed automatically. - -Internally, the DBI connect_cached() method is used instead of the -connect() method. This allows for connection caching in a server -environment, such as when the Template Toolkit is used from an Apache -mod_perl handler. In such a case, simply enable the mod_env module -and put in a line such as: - - SetEnv DBI_DSN "dbi:mysql:dbname;host=dbhost; - user=uname;password=pword" - -(NOTE: the string shown here is split across 2 lines for the sake of -reasonable page formatting, but you should specify it all as one long -string with no spaces or newlines). - -You can then use the DBI plugin without any parameters or the need -to explicitly call connect(). - -Once you've loaded a DBI plugin and opened a database connection using -one of the techniques shown above, you can then make queries on the database -using the familiar dotted notation: - - [% FOREACH user = DBI.query('SELECT * FROM users') %] - [% user.uid %] blah blah [% user.name %] etc. etc. - [% END %] - -The query() method prepares a query and executes it all in one go. -If you want to repeat a query with different parameters then you -can use a separate prepare/execute cycle. - - [% query = DBI.prepare('SELECT * FROM users WHERE uid = ?') %] - - [% FOREACH user = query.execute('sam') %] - ... - [% END %] - - [% FOREACH user = query.execute('abw') %] - ... - [% END %] - -The query() and execute() methods return an iterator object which -manages the result set returned. You can save a reference to the -iterator and access methods like size() to determine the number of -rows returned by a query. - - [% users = DBI.query('SELECT * FROM users') %] - [% users.size %] records returned - -or even - - [% DBI.query('SELECT * FROM users').size %] - -When used within a FOREACH loop, the iterator is always aliased to the -special C<loop> variable. This makes it possible to do things like this: - - [% FOREACH user = DBI.query('SELECT * FROM users') %] - [% loop.count %]/[% loop.size %]: [% user.name %] - [% END %] - -to generate a result set of the form: - - 1/3: Jerry Garcia - 2/3: Kurt Cobain - 3/3: Freddie Mercury - -See L<Template::Iterator> for further details on iterators and the -methods that they implement. - -The DBI plugin also provides the do() method to execute non-SELECT -statements like this: - - [% IF DBI.do("DELETE FROM users WHERE uid = '$uid'") %] - The user '[% uid %]' was successfully deleted. - [% END %] - -The plugin also allows you to create a tie to a table in the database -using the Tie::DBI module. Simply call the tie() method, passing the -name of the table and the primary key as arguments. - - [% people = DBI.tie('person', 'uid') %] - -You can then access records in the database table as if they were -entries in the 'people' hash. - - My name is [% people.abw.name %] - -IMPORTANT NOTE: the XS Stash (Template::Stash::XS) does not currently -support access to tied hashes. If you are using the XS stash and having -problems then you should try enabling the regular stash instead. You -can do this by setting $Template::Config::STASH to 'Template::Stash' -before instantiating the Template object. - -=head1 OBJECT METHODS - -=head2 connect($database, $username, $password) - -Establishes a database connection. This method accepts both positional -and named parameter syntax. e.g. - - [% DBI.connect( 'dbi:driver:dbname', 'timmy', 'sk8D00Dz' ) %] - - [% DBI.connect( database = 'dbi:driver:dbname' - username = 'timmy' - password = 'sk8D00Dz' ) %] - -The connect method allows you to connect to a data source explicitly. -It can also be used to reconnect an exisiting object to a different -data source. - -If you already have a database handle then you can instruct the plugin -to reuse it by passing it as the 'dbh' parameter. - - [% DBI.connect( dbh = my_dbh_ref ) %] - -=head2 query($sql) - -This method submits an SQL query to the database and creates an iterator -object to return the results. This may be used directly in a FOREACH -directive as shown below. Data is automatically fetched a row at a time -from the query result set as required for memory efficiency. - - [% FOREACH user = DBI.query('SELECT * FROM users') %] - Each [% user.field %] can be printed here - [% END %] - -=head2 prepare($sql) - -Prepare a query for later execution. This returns a compiled query -object (of the Template::Plugin::DBI::Query class) on which the -execute() method can subsequently be called. - - [% query = DBI.prepare('SELECT * FROM users WHERE id = ?') %] - -=head2 execute(@args) - -Execute a previously prepared query. This method should be called on -the query object returned by the prepare() method. Returns an -iterator object which can be used directly in a FOREACH directive. - - [% query = DBI.prepare('SELECT * FROM users WHERE manager = ?') %] - - [% FOREACH minion = query.execute('abw') %] - [% minion.name %] - [% END %] - - [% FOREACH minion = query.execute('sam') %] - [% minion.name %] - [% END %] - -=head2 do($sql) - -The do() method executes a sql statement from which no records are -returned. It will return true if the statement was successful - - [% IF DBI.do("DELETE FROM users WHERE uid = 'sam'") %] - The user was successfully deleted. - [% END %] - -=head2 tie($table, $key, \%args) - -Returns a reference to a hash array tied to a table in the database, -implemented using the Tie::DBI module. You should pass the name of -the table and the key field as arguments. - - [% people = DBI.tie('users', 'uid') %] - -Or if you prefer, you can use the 'table' and 'key' named parameters. - - [% people = DBI.tie(table='users', key='uid') %] - -In this example, the Tie::DBI module will convert the accesses into -the 'people' hash into SQL queries of the form: - - SELECT * FROM users WHERE uid=? - -For example: - - [% me = people.abw %] - -The record returned can then be accessed just like a normal hash. - - I am [% me.name %] - -You can also do things like this to iterate through all the records -in a table. - - [% FOREACH uid = people.keys.sort; - person = people.$uid - %] - * [% person.id %] : [% person.name %] - [% END %] - -With the 'clobber' (or 'CLOBBER') option set you can update the record -and have those changes automatically permeated back into the database. - - [% people = DBI.tie('users', 'uid', clobber=1) %] - - [% people.abw.name = 'not a number' %] - - I am [% people.abw.name %] # I am a free man! - -And you can also add new records. - - [% people.newguy = { - name = 'Nobby Newguy' - ...other fields... - } - %] - -See L<Tie::DBI> for further information on the 'CLOBBER' option. - -=head2 quote($value, $type) - -Calls the quote() method on the underlying DBI handle to quote the value -specified in the appropriate manner for its type. - -=head2 dbh() - -Return the database handle currently in use by the plugin. - -=head2 disconnect() - -Disconnects the current database. - -=head1 AUTHORS - -The DBI plugin was originally written by Simon A Matthews, and -distributed as a separate module. It was integrated into the Template -Toolkit distribution for version 2.00 and includes contributions from -Andy Wardley, Craig Barratt, Dave Hodgkinson and Rafael Kitover. - -=head1 VERSION - -2.62, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - -Copyright (C) 1999-2001 Simon Matthews. All Rights Reserved - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<DBI|DBI>, L<Tie::DBI|Tie::DBI> - diff --git a/lib/Template/Plugin/Datafile.pm b/lib/Template/Plugin/Datafile.pm deleted file mode 100644 index 5cf53af..0000000 --- a/lib/Template/Plugin/Datafile.pm +++ /dev/null @@ -1,198 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Datafile -# -# DESCRIPTION -# -# Template Toolkit Plugin which reads a datafile and constructs a -# list object containing hashes representing records in the file. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Datafile.pm,v 2.66 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Datafile; - -require 5.004; - -use strict; -use vars qw( @ISA $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.66 $ =~ /(\d+)\.(\d+)/); - -sub new { - my ($class, $context, $filename, $params) = @_; - my ($delim, $line, @fields, @data, @results); - my $self = [ ]; - local *FD; - local $/ = "\n"; - - $params ||= { }; - $delim = $params->{'delim'} || ':'; - $delim = quotemeta($delim); - - return $class->fail("No filename specified") - unless $filename; - - open(FD, $filename) - || return $class->fail("$filename: $!"); - - # first line of file should contain field definitions - while (! $line || $line =~ /^#/) { - $line = <FD>; - chomp $line; - $line =~ s/\r$//; - } - - (@fields = split(/\s*$delim\s*/, $line)) - || return $class->fail("first line of file must contain field names"); - - # read each line of the file - while (<FD>) { - chomp; - s/\r$//; - - # ignore comments and blank lines - next if /^#/ || /^\s*$/; - - # split line into fields - @data = split(/\s*$delim\s*/); - - # create hash record to represent data - my %record; - @record{ @fields } = @data; - - push(@$self, \%record); - } - -# return $self; - bless $self, $class; -} - - -sub as_list { - return $_[0]; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Datafile - Plugin to construct records from a simple data file - -=head1 SYNOPSIS - - [% USE mydata = datafile('/path/to/datafile') %] - [% USE mydata = datafile('/path/to/datafile', delim = '|') %] - - [% FOREACH record = mydata %] - [% record.this %] [% record.that %] - [% END %] - -=head1 DESCRIPTION - -This plugin provides a simple facility to construct a list of hash -references, each of which represents a data record of known structure, -from a data file. - - [% USE datafile(filename) %] - -A absolute filename must be specified (for this initial implementation at -least - in a future version it might also use the INCLUDE_PATH). An -optional 'delim' parameter may also be provided to specify an alternate -delimiter character. - - [% USE userlist = datafile('/path/to/file/users') %] - [% USE things = datafile('items', delim = '|') %] - -The format of the file is intentionally simple. The first line -defines the field names, delimited by colons with optional surrounding -whitespace. Subsequent lines then defines records containing data -items, also delimited by colons. e.g. - - id : name : email : tel - abw : Andy Wardley : abw@cre.canon.co.uk : 555-1234 - neilb : Neil Bowers : neilb@cre.canon.co.uk : 555-9876 - -Each line is read, split into composite fields, and then used to -initialise a hash array containing the field names as relevant keys. -The plugin returns a blessed list reference containing the hash -references in the order as defined in the file. - - [% FOREACH user = userlist %] - [% user.id %]: [% user.name %] - [% END %] - -The first line of the file B<must> contain the field definitions. -After the first line, blank lines will be ignored, along with comment -line which start with a '#'. - -=head1 BUGS - -Should handle file names relative to INCLUDE_PATH. -Doesn't permit use of ':' in a field. Some escaping mechanism is required. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.66, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Date.pm b/lib/Template/Plugin/Date.pm deleted file mode 100644 index 7351686..0000000 --- a/lib/Template/Plugin/Date.pm +++ /dev/null @@ -1,361 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Date -# -# DESCRIPTION -# -# Plugin to generate formatted date strings. -# -# AUTHORS -# Thierry-Michel Barral <kktos@electron-libre.com> -# Andy Wardley <abw@cre.canon.co.uk> -# -# COPYRIGHT -# Copyright (C) 2000 Thierry-Michel Barral, Andy Wardley. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Date.pm,v 2.71 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Date; - -use strict; -use vars qw( $VERSION $FORMAT @LOCALE_SUFFIX ); -use base qw( Template::Plugin ); -use Template::Plugin; - -use POSIX (); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.71 $ =~ /(\d+)\.(\d+)/); -$FORMAT = '%H:%M:%S %d-%b-%Y'; # default strftime() format -@LOCALE_SUFFIX = qw( .ISO8859-1 .ISO_8859-15 .US-ASCII .UTF-8 ); - -#------------------------------------------------------------------------ -# new(\%options) -#------------------------------------------------------------------------ - -sub new { - my ($class, $context, $params) = @_; - bless { - $params ? %$params : () - }, $class; -} - - -#------------------------------------------------------------------------ -# now() -# -# Call time() to return the current system time in seconds since the epoch. -#------------------------------------------------------------------------ - -sub now { - return time(); -} - - -#------------------------------------------------------------------------ -# format() -# format($time) -# format($time, $format) -# format($time, $format, $locale) -# format($time, $format, $locale, $gmt_flag) -# format(\%named_params); -# -# Returns a formatted time/date string for the specified time, $time, -# (or the current system time if unspecified) using the $format, $locale, -# and $gmt values specified as arguments or internal values set defined -# at construction time). Specifying a Perl-true value for $gmt will -# override the local time zone and force the output to be for GMT. -# Any or all of the arguments may be specified as named parameters which -# get passed as a hash array reference as the final argument. -# ------------------------------------------------------------------------ - -sub format { - my $self = shift; - my $params = ref($_[$#_]) eq 'HASH' ? pop(@_) : { }; - my $time = shift(@_) || $params->{ time } || $self->{ time } - || $self->now(); - my $format = @_ ? shift(@_) - : ($params->{ format } || $self->{ format } || $FORMAT); - my $locale = @_ ? shift(@_) - : ($params->{ locale } || $self->{ locale }); - my $gmt = @_ ? shift(@_) - : ($params->{ gmt } || $self->{ gmt }); - my (@date, $datestr); - - if ($time =~ /^\d+$/) { - # $time is now in seconds since epoch - if ($gmt) { - @date = (gmtime($time))[0..6]; - } - else { - @date = (localtime($time))[0..6]; - } - } - else { - # if $time is numeric, then we assume it's seconds since the epoch - # otherwise, we try to parse it as a 'H:M:S D:M:Y' string - @date = (split(/(?:\/| |:|-)/, $time))[2,1,0,3..5]; - return (undef, Template::Exception->new('date', - "bad time/date string: expects 'h:m:s d:m:y' got: '$time'")) - unless @date >= 6 && defined $date[5]; - $date[4] -= 1; # correct month number 1-12 to range 0-11 - $date[5] -= 1900; # convert absolute year to years since 1900 - $time = &POSIX::mktime(@date); - } - - if ($locale) { - # format the date in a specific locale, saving and subsequently - # restoring the current locale. - my $old_locale = &POSIX::setlocale(&POSIX::LC_ALL); - - # some systems expect locales to have a particular suffix - for my $suffix ('', @LOCALE_SUFFIX) { - my $try_locale = $locale.$suffix; - my $setlocale = &POSIX::setlocale(&POSIX::LC_ALL, $try_locale); - if (defined $setlocale && $try_locale eq $setlocale) { - $locale = $try_locale; - last; - } - } - $datestr = &POSIX::strftime($format, @date); - &POSIX::setlocale(&POSIX::LC_ALL, $old_locale); - } - else { - $datestr = &POSIX::strftime($format, @date); - } - - return $datestr; -} - -sub calc { - my $self = shift; - eval { require "Date/Calc.pm" }; - $self->throw("failed to load Date::Calc: $@") if $@; - return Template::Plugin::Date::Calc->new('no context'); -} - -sub manip { - my $self = shift; - eval { require "Date/Manip.pm" }; - $self->throw("failed to load Date::Manip: $@") if $@; - return Template::Plugin::Date::Manip->new('no context'); -} - - -sub throw { - my $self = shift; - die (Template::Exception->new('date', join(', ', @_))); -} - - -package Template::Plugin::Date::Calc; -use base qw( Template::Plugin ); -use vars qw( $AUTOLOAD ); -*throw = \&Template::Plugin::Date::throw; - -sub AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; - - my $sub = \&{"Date::Calc::$method"}; - $self->throw("no such Date::Calc method: $method") - unless $sub; - - &$sub(@_); -} - -package Template::Plugin::Date::Manip; -use base qw( Template::Plugin ); -use vars qw( $AUTOLOAD ); -*throw = \&Template::Plugin::Date::throw; - -sub AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; - - my $sub = \&{"Date::Manip::$method"}; - $self->throw("no such Date::Manip method: $method") - unless $sub; - - &$sub(@_); -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Date - Plugin to generate formatted date strings - -=head1 SYNOPSIS - - [% USE date %] - - # use current time and default format - [% date.format %] - - # specify time as seconds since epoch or 'h:m:s d-m-y' string - [% date.format(960973980) %] - [% date.format('4:20:36 21/12/2000') %] - - # specify format - [% date.format(mytime, '%H:%M:%S') %] - - # specify locale - [% date.format(date.now, '%a %d %b %y', 'en_GB') %] - - # named parameters - [% date.format(mytime, format = '%H:%M:%S') %] - [% date.format(locale = 'en_GB') %] - [% date.format(time = date.now, - format = '%H:%M:%S', - locale = 'en_GB) %] - - # specify default format to plugin - [% USE date(format = '%H:%M:%S', locale = 'de_DE') %] - - [% date.format %] - ... - -=head1 DESCRIPTION - -The Date plugin provides an easy way to generate formatted time and date -strings by delegating to the POSIX strftime() routine. - -The plugin can be loaded via the familiar USE directive. - - [% USE date %] - -This creates a plugin object with the default name of 'date'. An alternate -name can be specified as such: - - [% USE myname = date %] - -The plugin provides the format() method which accepts a time value, a -format string and a locale name. All of these parameters are optional -with the current system time, default format ('%H:%M:%S %d-%b-%Y') and -current locale being used respectively, if undefined. Default values -for the time, format and/or locale may be specified as named parameters -in the USE directive. - - [% USE date(format = '%a %d-%b-%Y', locale = 'fr_FR') %] - -When called without any parameters, the format() method returns a string -representing the current system time, formatted by strftime() according -to the default format and for the default locale (which may not be the -current one, if locale is set in the USE directive). - - [% date.format %] - -The plugin allows a time/date to be specified as seconds since the epoch, -as is returned by time(). - - File last modified: [% date.format(filemod_time) %] - -The time/date can also be specified as a string of the form 'h:m:s d/m/y'. -Any of the characters : / - or space may be used to delimit fields. - - [% USE day = date(format => '%A', locale => 'en_GB') %] - [% day.format('4:20:00 9-13-2000') %] - -Output: - - Tuesday - -A format string can also be passed to the format() method, and a locale -specification may follow that. - - [% date.format(filemod, '%d-%b-%Y') %] - [% date.format(filemod, '%d-%b-%Y', 'en_GB') %] - -A fourth parameter allows you to force output in GMT, in the case of -seconds-since-the-epoch input: - - [% date.format(filemod, '%d-%b-%Y', 'en_GB', 1) %] - -Note that in this case, if the local time is not GMT, then also specifying -'%Z' (time zone) in the format parameter will lead to an extremely -misleading result. - -Any or all of these parameters may be named. Positional parameters -should always be in the order ($time, $format, $locale). - - [% date.format(format => '%H:%M:%S') %] - [% date.format(time => filemod, format => '%H:%M:%S') %] - [% date.format(mytime, format => '%H:%M:%S') %] - [% date.format(mytime, format => '%H:%M:%S', locale => 'fr_FR') %] - [% date.format(mytime, format => '%H:%M:%S', gmt => 1) %] - ...etc... - -The now() method returns the current system time in seconds since the -epoch. - - [% date.format(date.now, '%A') %] - -The calc() method can be used to create an interface to the Date::Calc -module (if installed on your system). - - [% calc = date.calc %] - [% calc.Monday_of_Week(22, 2001).join('/') %] - -The manip() method can be used to create an interface to the Date::Manip -module (if installed on your system). - - [% manip = date.manip %] - [% manip.UnixDate("Noon Yesterday","%Y %b %d %H:%M") %] - -=head1 AUTHORS - -Thierry-Michel Barral E<lt>kktos@electron-libre.comE<gt> wrote the original -plugin. - -Andy Wardley E<lt>abw@cre.canon.co.ukE<gt> provided some minor -fixups/enhancements, a test script and documentation. - -Mark D. Mills E<lt>mark@hostile.orgE<gt> cloned Date::Manip from the -cute Date::Calc sub-plugin. - -=head1 VERSION - -2.71, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - -Copyright (C) 2000 Thierry-Michel Barral, Andy Wardley. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<POSIX|POSIX> - diff --git a/lib/Template/Plugin/Directory.pm b/lib/Template/Plugin/Directory.pm deleted file mode 100644 index ec6247e..0000000 --- a/lib/Template/Plugin/Directory.pm +++ /dev/null @@ -1,410 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Directory -# -# DESCRIPTION -# Plugin for encapsulating information about a file system directory. -# -# AUTHORS -# Michael Stevens <michael@etla.org>, with some mutilations from -# Andy Wardley <abw@kfs.org>. -# -# COPYRIGHT -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# $Id: Directory.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Directory; - -require 5.004; - -use strict; -use Cwd; -use File::Spec; -use Template::Plugin::File; -use vars qw( $VERSION ); -use base qw( Template::Plugin::File ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new(\%config) -# -# Constructor method. -#------------------------------------------------------------------------ - -sub new { - my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { }; - my ($class, $context, $path) = @_; - - return $class->throw('no directory specified') - unless defined $path and length $path; - - my $self = $class->SUPER::new($context, $path, $config); - my ($dir, @files, $name, $item, $abs, $rel, $check); - $self->{ files } = [ ]; - $self->{ dirs } = [ ]; - $self->{ list } = [ ]; - $self->{ _dir } = { }; - - # don't read directory if 'nostat' or 'noscan' set - return $self if $config->{ nostat } || $config->{ noscan }; - - $self->throw("$path: not a directory") - unless $self->{ isdir }; - - $self->scan($config); - - return $self; -} - - -#------------------------------------------------------------------------ -# scan(\%config) -# -# Scan directory for files and sub-directories. -#------------------------------------------------------------------------ - -sub scan { - my ($self, $config) = @_; - $config ||= { }; - local *DH; - my ($dir, @files, $name, $abs, $rel, $item); - - # set 'noscan' in config if recurse isn't set, to ensure Directories - # created don't try to scan deeper - $config->{ noscan } = 1 unless $config->{ recurse }; - - $dir = $self->{ abs }; - opendir(DH, $dir) or return $self->throw("$dir: $!"); - - @files = readdir DH; - closedir(DH) - or return $self->throw("$dir close: $!"); - - my ($path, $files, $dirs, $list) = @$self{ qw( path files dirs list ) }; - @$files = @$dirs = @$list = (); - - foreach $name (sort @files) { - next if $name =~ /^\./; - $abs = File::Spec->catfile($dir, $name); - $rel = File::Spec->catfile($path, $name); - - if (-d $abs) { - $item = Template::Plugin::Directory->new(undef, $rel, $config); - push(@$dirs, $item); - } - else { - $item = Template::Plugin::File->new(undef, $rel, $config); - push(@$files, $item); - } - push(@$list, $item); - $self->{ _dir }->{ $name } = $item; - } - - return ''; -} - - -#------------------------------------------------------------------------ -# file($filename) -# -# Fetch a named file from this directory. -#------------------------------------------------------------------------ - -sub file { - my ($self, $name) = @_; - return $self->{ _dir }->{ $name }; -} - - -#------------------------------------------------------------------------ -# present($view) -# -# Present self to a Template::View -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - $view->view_directory($self); -} - - -#------------------------------------------------------------------------ -# content($view) -# -# Present directory content to a Template::View. -#------------------------------------------------------------------------ - -sub content { - my ($self, $view) = @_; - return $self->{ list } unless $view; - my $output = ''; - foreach my $file (@{ $self->{ list } }) { - $output .= $file->present($view); - } - return $output; -} - - -#------------------------------------------------------------------------ -# throw($msg) -# -# Throw a 'Directory' exception. -#------------------------------------------------------------------------ - -sub throw { - my ($self, $error) = @_; - die (Template::Exception->new('Directory', $error)); -} - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Directory - Plugin for generating directory listings - -=head1 SYNOPSIS - - [% USE dir = Directory(dirpath) %] - - # files returns list of regular files - [% FOREACH file = dir.files %] - [% file.name %] [% file.path %] ... - [% END %] - - # dirs returns list of sub-directories - [% FOREACH subdir = dir.dirs %] - [% subdir.name %] [% subdir.path %] ... - [% END %] - - # list returns both interleaved in order - [% FOREACH item = dir.list %] - [% IF item.isdir %] - Directory: [% item.name %] - [% ELSE - File: [% item.name %] - [% END %] - [% END %] - - # define a VIEW to display dirs/files - [% VIEW myview %] - [% BLOCK file %] - File: [% item.name %] - [% END %] - - [% BLOCK directory %] - Directory: [% item.name %] - [% item.content(myview) | indent -%] - [% END %] - [% END %] - - # display directory content using view - [% myview.print(dir) %] - -=head1 DESCRIPTION - -This Template Toolkit plugin provides a simple interface to directory -listings. It is derived from the Template::Plugin::File module and -uses Template::Plugin::File object instances to represent files within -a directory. Sub-directories within a directory are represented by -further Template::Plugin::Directory instances. - -The constructor expects a directory name as an argument. - - [% USE dir = Directory('/tmp') %] - -It then provides access to the files and sub-directories contained within -the directory. - - # regular files (not directories) - [% FOREACH file = dir.files %] - [% file.name %] - [% END %] - - # directories only - [% FOREACH file = dir.dirs %] - [% file.name %] - [% END %] - - # files and/or directories - [% FOREACH file = dir.list %] - [% file.name %] ([% file.isdir ? 'directory' : 'file' %]) - [% END %] - - [% USE Directory('foo/baz') %] - -The plugin constructor will throw a 'Directory' error if the specified -path does not exist, is not a directory or fails to stat() (see -L<Template::Plugin::File>). Otherwise, it will scan the directory and -create lists named 'files' containing files, 'dirs' containing -directories and 'list' containing both files and directories combined. -The 'nostat' option can be set to disable all file/directory checks -and directory scanning. - -Each file in the directory will be represented by a -Template::Plugin::File object instance, and each directory by another -Template::Plugin::Directory. If the 'recurse' flag is set, then those -directories will contain further nested entries, and so on. With the -'recurse' flag unset, as it is by default, then each is just a place -marker for the directory and does not contain any further content -unless its scan() method is explicitly called. The 'isdir' flag can -be tested against files and/or directories, returning true if the item -is a directory or false if it is a regular file. - - [% FOREACH file = dir.list %] - [% IF file.isdir %] - * Directory: [% file.name %] - [% ELSE %] - * File: [% file.name %] - [% END %] - [% END %] - -This example shows how you might walk down a directory tree, displaying -content as you go. With the recurse flag disabled, as is the default, -we need to explicitly call the scan() method on each directory, to force -it to lookup files and further sub-directories contained within. - - [% USE dir = Directory(dirpath) %] - * [% dir.path %] - [% INCLUDE showdir %] - - [% BLOCK showdir -%] - [% FOREACH file = dir.list -%] - [% IF file.isdir -%] - * [% file.name %] - [% file.scan -%] - [% INCLUDE showdir dir=file FILTER indent(4) -%] - [% ELSE -%] - - [% f.name %] - [% END -%] - [% END -%] - [% END %] - -This example is adapted (with some re-formatting for clarity) from -a test in F<t/directry.t> which produces the following output: - - * test/dir - - file1 - - file2 - * sub_one - - bar - - foo - * sub_two - - waz.html - - wiz.html - - xyzfile - -The 'recurse' flag can be set (disabled by default) to cause the -constructor to automatically recurse down into all sub-directories, -creating a new Template::Plugin::Directory object for each one and -filling it with any further content. In this case there is no need -to explicitly call the scan() method. - - [% USE dir = Directory(dirpath, recurse=1) %] - ... - - [% IF file.isdir -%] - * [% file.name %] - [% INCLUDE showdir dir=file FILTER indent(4) -%] - [% ELSE -%] - ... - -From version 2.01, the Template Toolkit provides support for views. -A view can be defined as a VIEW ... END block and should contain -BLOCK definitions for files ('file') and directories ('directory'). - - [% VIEW myview %] - [% BLOCK file %] - - [% item.name %] - [% END %] - - [% BLOCK directory %] - * [% item.name %] - [% item.content(myview) FILTER indent %] - [% END %] - [% END %] - -Then the view print() method can be called, passing the -Directory object as an argument. - - [% USE dir = Directory(dirpath, recurse=1) %] - [% myview.print(dir) %] - -When a directory is presented to a view, either as [% myview.print(dir) %] -or [% dir.present(view) %], then the 'directory' BLOCK within the 'myview' -VIEW is processed, with the 'item' variable set to alias the Directory object. - - [% BLOCK directory %] - * [% item.name %] - [% item.content(myview) FILTER indent %] - [% END %] - -The directory name is first printed and the content(view) method is -then called to present each item within the directory to the view. -Further directories will be mapped to the 'directory' block, and files -will be mapped to the 'file' block. - -With the recurse option disabled, as it is by default, the 'directory' -block should explicitly call a scan() on each directory. - - [% VIEW myview %] - [% BLOCK file %] - - [% item.name %] - [% END %] - - [% BLOCK directory %] - * [% item.name %] - [% item.scan %] - [% item.content(myview) FILTER indent %] - [% END %] - [% END %] - - [% USE dir = Directory(dirpath) %] - [% myview.print(dir) %] - -=head1 TODO - -Might be nice to be able to specify accept/ignore options to catch -a subset of files. - -=head1 AUTHORS - -Michael Stevens E<lt>michael@etla.orgE<gt> wrote the original Directory plugin -on which this is based. Andy Wardley E<lt>abw@wardley.orgE<gt> split it into -separate File and Directory plugins, added some extra code and documentation -for VIEW support, and made a few other minor tweaks. - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::File|Template::Plugin::File>, L<Template::View|Template::View> - diff --git a/lib/Template/Plugin/Dumper.pm b/lib/Template/Plugin/Dumper.pm deleted file mode 100644 index 5dbf1f6..0000000 --- a/lib/Template/Plugin/Dumper.pm +++ /dev/null @@ -1,179 +0,0 @@ -#============================================================================== -# -# Template::Plugin::Dumper -# -# DESCRIPTION -# -# A Template Plugin to provide a Template Interface to Data::Dumper -# -# AUTHOR -# Simon Matthews <sam@knowledgepool.com> -# -# COPYRIGHT -# -# Copyright (C) 2000 Simon Matthews. All Rights Reserved -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#------------------------------------------------------------------------------ -# -# $Id: Dumper.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================== - -package Template::Plugin::Dumper; - -require 5.004; - -use strict; -use Template::Plugin; -use Data::Dumper; - -use vars qw( $VERSION $DEBUG @DUMPER_ARGS $AUTOLOAD ); -use base qw( Template::Plugin ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; -@DUMPER_ARGS = qw( Indent Pad Varname Purity Useqq Terse Freezer - Toaster Deepcopy Quotekeys Bless Maxdepth ); - -#============================================================================== -# ----- CLASS METHODS ----- -#============================================================================== - -#------------------------------------------------------------------------ -# new($context, \@params) -#------------------------------------------------------------------------ - -sub new { - my ($class, $context, $params) = @_; - my ($key, $val); - $params ||= { }; - - - foreach my $arg (@DUMPER_ARGS) { - no strict 'refs'; - if (defined ($val = $params->{ lc $arg }) - or defined ($val = $params->{ $arg })) { - ${"Data\::Dumper\::$arg"} = $val; - } - } - - bless { - _CONTEXT => $context, - }, $class; -} - -sub dump { - my $self = shift; - my $content = Dumper @_; - return $content; -} - - -sub dump_html { - my $self = shift; - my $content = Dumper @_; - for ($content) { - s/&/&/g; - s/</</g; - s/>/>/g; - s/\n/<br>\n/g; - } - return $content; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Dumper - Plugin interface to Data::Dumper - -=head1 SYNOPSIS - - [% USE Dumper %] - - [% Dumper.dump(variable) %] - [% Dumper.dump_html(variable) %] - -=head1 DESCRIPTION - -This is a very simple Template Toolkit Plugin Interface to the Data::Dumper -module. A Dumper object will be instantiated via the following directive: - - [% USE Dumper %] - -As a standard plugin, you can also specify its name in lower case: - - [% USE dumper %] - -The Data::Dumper 'Pad', 'Indent' and 'Varname' options are supported -as constructor arguments to affect the output generated. See L<Data::Dumper> -for further details. - - [% USE dumper(Indent=0, Pad="<br>") %] - -These options can also be specified in lower case. - - [% USE dumper(indent=0, pad="<br>") %] - -=head1 METHODS - -There are two methods supported by the Dumper object. Each will -output into the template the contents of the variables passed to the -object method. - -=head2 dump() - -Generates a raw text dump of the data structure(s) passed - - [% USE Dumper %] - [% Dumper.dump(myvar) %] - [% Dumper.dump(myvar, yourvar) %] - -=head2 dump_html() - -Generates a dump of the data structures, as per dump(), but with the -characters E<lt>, E<gt> and E<amp> converted to their equivalent HTML -entities and newlines converted to E<lt>brE<gt>. - - [% USE Dumper %] - [% Dumper.dump_html(myvar) %] - -=head1 AUTHOR - -Simon Matthews E<lt>sam@knowledgepool.comE<gt> - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - -Copyright (C) 2000 Simon Matthews All Rights Reserved. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Data::Dumper|Data::Dumper> - diff --git a/lib/Template/Plugin/File.pm b/lib/Template/Plugin/File.pm deleted file mode 100644 index d1d542e..0000000 --- a/lib/Template/Plugin/File.pm +++ /dev/null @@ -1,416 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::File -# -# DESCRIPTION -# Plugin for encapsulating information about a system file. -# -# AUTHOR -# Originally written by Michael Stevens <michael@etla.org> as the -# Directory plugin, then mutilated by Andy Wardley <abw@kfs.org> -# into separate File and Directory plugins, with some additional -# code for working with views, etc. -# -# COPYRIGHT -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# $Id: File.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::File; - -require 5.004; - -use strict; -use Cwd; -use File::Spec; -use File::Basename; -use Template::Plugin; - -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use vars qw( @STAT_KEYS ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - -@STAT_KEYS = qw( dev ino mode nlink uid gid rdev size - atime mtime ctime blksize blocks ); - - -#------------------------------------------------------------------------ -# new($context, $file, \%config) -# -# Create a new File object. Takes the pathname of the file as -# the argument following the context and an optional -# hash reference of configuration parameters. -#------------------------------------------------------------------------ - -sub new { - my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { }; - my ($class, $context, $path) = @_; - my ($root, $home, @stat, $abs); - - return $class->throw('no file specified') - unless defined $path and length $path; - - # path, dir, name, root, home - - if (File::Spec->file_name_is_absolute($path)) { - $root = ''; - } - elsif (($root = $config->{ root })) { - # strip any trailing '/' from root - $root =~ s[/$][]; - } - else { - $root = ''; - } - - my ($name, $dir, $ext) = fileparse($path, '\.\w+'); - # fixup various items - $dir =~ s[/$][]; - $dir = '' if $dir eq '.'; - $name = $name . $ext; - $ext =~ s/^\.//g; - my @fields = File::Spec->splitdir($dir); - shift @fields if @fields && ! length $fields[0]; - $home = join('/', ('..') x @fields); - $abs = File::Spec->catfile($root ? $root : (), $path); - - my $self = { - path => $path, - name => $name, - root => $root, - home => $home, - dir => $dir, - ext => $ext, - abs => $abs, - user => '', - group => '', - isdir => '', - stat => defined $config->{ stat } ? $config->{ stat } - : ! $config->{ nostat }, - map { ($_ => '') } @STAT_KEYS, - }; - - if ($self->{ stat }) { - (@stat = stat( $abs )) - || return $class->throw("$abs: $!"); - @$self{ @STAT_KEYS } = @stat; - unless ($config->{ noid }) { - $self->{ user } = eval { getpwuid( $self->{ uid }) || $self->{ uid } }; - $self->{ group } = eval { getgrgid( $self->{ gid }) || $self->{ gid } }; - } - $self->{ isdir } = -d $abs; - } - - bless $self, $class; -} - - -#------------------------------------------------------------------------- -# rel($file) -# -# Generate a relative filename for some other file relative to this one. -#------------------------------------------------------------------------ - -sub rel { - my ($self, $path) = @_; - $path = $path->{ path } if ref $path eq ref $self; # assumes same root - return $path if $path =~ m[^/]; - return $path unless $self->{ home }; - return $self->{ home } . '/' . $path; -} - - -#------------------------------------------------------------------------ -# present($view) -# -# Present self to a Template::View. -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - $view->view_file($self); -} - - -sub throw { - my ($self, $error) = @_; - die (Template::Exception->new('File', $error)); -} - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::File - Plugin providing information about files - -=head1 SYNOPSIS - - [% USE File(filepath) %] - [% File.path %] # full path - [% File.name %] # filename - [% File.dir %] # directory - -=head1 DESCRIPTION - -This plugin provides an abstraction of a file. It can be used to -fetch details about files from the file system, or to represent abstract -files (e.g. when creating an index page) that may or may not exist on -a file system. - -A file name or path should be specified as a constructor argument. e.g. - - [% USE File('foo.html') %] - [% USE File('foo/bar/baz.html') %] - [% USE File('/foo/bar/baz.html') %] - -The file should exist on the current file system (unless 'nostat' -option set, see below) as an absolute file when specified with as -leading '/' as per '/foo/bar/baz.html', or otherwise as one relative -to the current working directory. The constructor performs a stat() -on the file and makes the 13 elements returned available as the plugin -items: - - dev ino mode nlink uid gid rdev size - atime mtime ctime blksize blocks - -e.g. - - [% USE File('/foo/bar/baz.html') %] - - [% File.mtime %] - [% File.mode %] - ... - -In addition, the 'user' and 'group' items are set to contain the user -and group names as returned by calls to getpwuid() and getgrgid() for -the file 'uid' and 'gid' elements, respectively. On Win32 platforms -on which getpwuid() and getgrid() are not available, these values are -undefined. - - [% USE File('/tmp/foo.html') %] - [% File.uid %] # e.g. 500 - [% File.user %] # e.g. abw - -This user/group lookup can be disabled by setting the 'noid' option. - - [% USE File('/tmp/foo.html', noid=1) %] - [% File.uid %] # e.g. 500 - [% File.user %] # nothing - -The 'isdir' flag will be set if the file is a directory. - - [% USE File('/tmp') %] - [% File.isdir %] # 1 - -If the stat() on the file fails (e.g. file doesn't exists, bad -permission, etc) then the constructor will throw a 'File' exception. -This can be caught within a TRY...CATCH block. - - [% TRY %] - [% USE File('/tmp/myfile') %] - File exists! - [% CATCH File %] - File error: [% error.info %] - [% END %] - -Note the capitalisation of the exception type, 'File' to indicate an -error thrown by the 'File' plugin, to distinguish it from a regular -'file' exception thrown by the Template Toolkit. - -Note that the 'File' plugin can also be referenced by the lower case -name 'file'. However, exceptions are always thrown of the 'File' -type, regardless of the capitalisation of the plugin named used. - - [% USE file('foo.html') %] - [% file.mtime %] - -As with any other Template Toolkit plugin, an alternate name can be -specified for the object created. - - [% USE foo = file('foo.html') %] - [% foo.mtime %] - -The 'nostat' option can be specified to prevent the plugin constructor -from performing a stat() on the file specified. In this case, the -file does not have to exist in the file system, no attempt will be made -to verify that it does, and no error will be thrown if it doesn't. -The entries for the items usually returned by stat() will be set -empty. - - [% USE file('/some/where/over/the/rainbow.html', nostat=1) - [% file.mtime %] # nothing - -All File plugins, regardless of the nostat option, have set a number -of items relating to the original path specified. - -=over 4 - -=item path - -The full, original file path specified to the constructor. - - [% USE file('/foo/bar.html') %] - [% file.path %] # /foo/bar.html - -=item name - -The name of the file without any leading directories. - - [% USE file('/foo/bar.html') %] - [% file.name %] # bar.html - -=item dir - -The directory element of the path with the filename removed. - - [% USE file('/foo/bar.html') %] - [% file.name %] # /foo - -=item ext - -The file extension, if any, appearing at the end of the path following -a '.' (not included in the extension). - - [% USE file('/foo/bar.html') %] - [% file.ext %] # html - -=item home - -This contains a string of the form '../..' to represent the upward path -from a file to its root directory. - - [% USE file('bar.html') %] - [% file.home %] # nothing - - [% USE file('foo/bar.html') %] - [% file.home %] # .. - - [% USE file('foo/bar/baz.html') %] - [% file.home %] # ../.. - -=item root - -The 'root' item can be specified as a constructor argument, indicating -a root directory in which the named file resides. This is otherwise -set empty. - - [% USE file('foo/bar.html', root='/tmp') %] - [% file.root %] # /tmp - -=item abs - -This returns the absolute file path by constructing a path from the -'root' and 'path' options. - - [% USE file('foo/bar.html', root='/tmp') %] - [% file.path %] # foo/bar.html - [% file.root %] # /tmp - [% file.abs %] # /tmp/foo/bar.html - -=back - -In addition, the following method is provided: - -=over 4 - -=item rel(path) - -This returns a relative path from the current file to another path specified -as an argument. It is constructed by appending the path to the 'home' -item. - - [% USE file('foo/bar/baz.html') %] - [% file.rel('wiz/waz.html') %] # ../../wiz/waz.html - -=back - -=head1 EXAMPLES - - [% USE file('/foo/bar/baz.html') %] - - [% file.path %] # /foo/bar/baz.html - [% file.dir %] # /foo/bar - [% file.name %] # baz.html - [% file.home %] # ../.. - [% file.root %] # '' - [% file.abspath %] # /foo/bar/baz.html - [% file.ext %] # html - [% file.mtime %] # 987654321 - [% file.atime %] # 987654321 - [% file.uid %] # 500 - [% file.user %] # abw - - [% USE file('foo.html') %] - - [% file.path %] # foo.html - [% file.dir %] # '' - [% file.name %] # foo.html - [% file.root %] # '' - [% file.home %] # '' - [% file.abspath %] # foo.html - - [% USE file('foo/bar/baz.html') %] - - [% file.path %] # foo/bar/baz.html - [% file.dir %] # foo/bar - [% file.name %] # baz.html - [% file.root %] # '' - [% file.home %] # ../.. - [% file.abspath %] # foo/bar/baz.html - - [% USE file('foo/bar/baz.html', root='/tmp') %] - - [% file.path %] # foo/bar/baz.html - [% file.dir %] # foo/bar - [% file.name %] # baz.html - [% file.root %] # /tmp - [% file.home %] # ../.. - [% file.abspath %] # /tmp/foo/bar/baz.html - - # calculate other file paths relative to this file and its root - [% USE file('foo/bar/baz.html', root => '/tmp/tt2') %] - [% file.path('baz/qux.html') %] # ../../baz/qux.html - [% file.dir('wiz/woz.html') %] # ../../wiz/woz.html - - -=head1 AUTHORS - -Michael Stevens E<lt>michael@etla.orgE<gt> wrote the original Directory plugin -on which this is based. Andy Wardley E<lt>abw@wardley.orgE<gt> split it into -separate File and Directory plugins, added some extra code and documentation -for VIEW support, and made a few other minor tweaks. - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::Directory|Template::Plugin::Directory>, L<Template::View|Template::View> - diff --git a/lib/Template/Plugin/Filter.pm b/lib/Template/Plugin/Filter.pm deleted file mode 100644 index 38da7ba..0000000 --- a/lib/Template/Plugin/Filter.pm +++ /dev/null @@ -1,436 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Filter -# -# DESCRIPTION -# Template Toolkit module implementing a base class plugin -# object which acts like a filter and can be used with the -# FILTER directive. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2001 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. -# -# REVISION -# $Id: Filter.pm,v 1.30 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Filter; - -require 5.004; - -use strict; -use Template::Plugin; - -use base qw( Template::Plugin ); -use vars qw( $VERSION $DYNAMIC ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.30 $ =~ /(\d+)\.(\d+)/); -$DYNAMIC = 0 unless defined $DYNAMIC; - - -sub new { - my ($class, $context, @args) = @_; - my $config = @args && ref $args[-1] eq 'HASH' ? pop(@args) : { }; - - # look for $DYNAMIC - my $dynamic; - { - no strict 'refs'; - $dynamic = ${"$class\::DYNAMIC"}; - } - $dynamic = $DYNAMIC unless defined $dynamic; - - my $self = bless { - _CONTEXT => $context, - _DYNAMIC => $dynamic, - _ARGS => \@args, - _CONFIG => $config, - }, $class; - - return $self->init($config) - || $class->error($self->error()); -} - - -sub init { - my ($self, $config) = @_; - return $self; -} - - -sub factory { - my $self = shift; - - if ($self->{ _DYNAMIC }) { - return $self->{ _DYNAMIC_FILTER } ||= [ sub { - my ($context, @args) = @_; - my $config = ref $args[-1] eq 'HASH' ? pop(@args) : { }; - - return sub { - $self->filter(shift, \@args, $config); - }; - }, 1 ]; - } - else { - return $self->{ _STATIC_FILTER } ||= sub { - $self->filter(shift); - }; - } -} - - -sub filter { - my ($self, $text, $args, $config) = @_; - return $text; -} - - -sub merge_config { - my ($self, $newcfg) = @_; - my $owncfg = $self->{ _CONFIG }; - return $owncfg unless $newcfg; - return { %$owncfg, %$newcfg }; -} - - -sub merge_args { - my ($self, $newargs) = @_; - my $ownargs = $self->{ _ARGS }; - return $ownargs unless $newargs; - return [ @$ownargs, @$newargs ]; -} - - -sub install_filter { - my ($self, $name) = @_; - $self->{ _CONTEXT }->define_filter( $name => $self->factory() ); - return $self; -} - - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Filter - Base class for plugin filters - -=head1 SYNOPSIS - - 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 %] - -=head1 DESCRIPTION - -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 Template::Plugin::Filter; - use base qw( Template::Plugin::Filter ); - use vars qw( $DYNAMIC ); - - $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 %] - -=head1 EXAMPLE - -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; - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -1.30, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Filters|Template::Filters>, L<Template::Manual::Filters|Template::Manual::Filters> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Format.pm b/lib/Template/Plugin/Format.pm deleted file mode 100644 index bba55d2..0000000 --- a/lib/Template/Plugin/Format.pm +++ /dev/null @@ -1,124 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Format -# -# DESCRIPTION -# -# Simple Template Toolkit Plugin which creates formatting functions. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Format.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Format; - -require 5.004; - -use strict; -use vars qw( @ISA $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - - -sub new { - my ($class, $context, $format) = @_;; - return defined $format - ? make_formatter($format) - : \&make_formatter; -} - - -sub make_formatter { - my $format = shift; - $format = '%s' unless defined $format; - return sub { - my @args = @_; - push(@args, '') unless @args; - return sprintf($format, @args); - } -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Format - Plugin to create formatting functions - -=head1 SYNOPSIS - - [% USE format %] - [% commented = format('# %s') %] - [% commented('The cat sat on the mat') %] - - [% USE bold = format('<b>%s</b>') %] - [% bold('Hello') %] - -=head1 DESCRIPTION - -The format plugin constructs sub-routines which format text according to -a printf()-like format string. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Constants.pm b/lib/Template/Plugin/GD/Constants.pm deleted file mode 100644 index 6fc8e7c..0000000 --- a/lib/Template/Plugin/GD/Constants.pm +++ /dev/null @@ -1,138 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Constants -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD constants -# in the GD.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Constants.pm,v 1.55 2004/01/13 16:20:46 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Constants; - -require 5.004; - -use strict; -use GD qw(/^gd/ /^GD/); -use Template::Plugin; -use base qw( Template::Plugin ); -use vars qw( @ISA $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - my $self = { }; - bless $self, $class; - - # - # GD has exported various gd* and GD_* contstants. Find them. - # - foreach my $v ( keys(%Template::Plugin::GD::Constants::) ) { - $self->{$v} = eval($v) if ( $v =~ /^gd/ || $v =~ /^GD_/ ); - } - return $self; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Constants - Interface to GD module constants - -=head1 SYNOPSIS - - [% USE gdc = GD.Constants %] - - # --> the constants gdc.gdBrushed, gdc.gdSmallFont, gdc.GD_CMP_IMAGE - # are now available - -=head1 EXAMPLES - - [% FILTER null; - USE gdc = GD.Constants; - USE im = GD.Image(200,100); - black = im.colorAllocate(0 ,0, 0); - red = im.colorAllocate(255,0, 0); - r = im.string(gdc.gdLargeFont, 10, 10, "Large Red Text", red); - im.png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Constants plugin provides access to the various GD module's -constants (such as gdBrushed, gdSmallFont, gdTransparent, GD_CMP_IMAGE -etc). When GD.pm is used in perl it exports various contstants -into the caller's namespace. This plugin makes those exported -constants available as template variables. - -See L<Template::Plugin::GD::Image> and L<GD> for further examples and -details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -Lincoln D. Stein wrote the GD.pm interface to the GD library. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -The GD.pm interface is copyright 1995-2000, Lincoln D. Stein. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Image|Template::Plugin::GD::Image>, L<Template::Plugin::GD::Polygon|Template::Plugin::GD::Polygon>, L<GD|GD> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/area.pm b/lib/Template/Plugin/GD/Graph/area.pm deleted file mode 100644 index d09d024..0000000 --- a/lib/Template/Plugin/GD/Graph/area.pm +++ /dev/null @@ -1,148 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::area -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::area -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: area.pm,v 1.57 2004/01/13 16:20:51 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::area; - -require 5.004; - -use strict; -use GD::Graph::area; -use Template::Plugin; -use base qw( GD::Graph::area Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::area - Create area graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.area(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 5, 12, 24, 33, 19, 8, 6, 15, 21], - [ -1, -2, -5, -6, -3, 1.5, 1, 1.3, 2] - ]; - - USE my_graph = GD.Graph.area(); - my_graph.set( - two_axes => 1, - zero_axis => 1, - transparent => 0, - ); - my_graph.set_legend('left axis', 'right axis' ); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.area plugin provides an interface to the GD::Graph::area -class defined by the GD::Graph module. It allows one or more (x,y) data -sets to be plotted as lines with the area between the line and x-axis -shaded, in addition to axes and legends. - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/bars.pm b/lib/Template/Plugin/GD/Graph/bars.pm deleted file mode 100644 index 9bc08c5..0000000 --- a/lib/Template/Plugin/GD/Graph/bars.pm +++ /dev/null @@ -1,191 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::bars -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::bars -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: bars.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::bars; - -require 5.004; - -use strict; -use GD::Graph::bars; -use Template::Plugin; -use base qw( GD::Graph::bars Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::bars - Create bar graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.bars(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 1, 2, 5, 6, 3, 1.5, 1, 3, 4], - ]; - - USE my_graph = GD.Graph.bars(); - - my_graph.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'A Simple Bar Chart', - y_max_value => 8, - y_tick_number => 8, - y_label_skip => 2, - - # shadows - bar_spacing => 8, - shadow_depth => 4, - shadowclr => 'dred', - - transparent => 0, - ); - my_graph.plot(data).png | stdout(1); - END; - -%] - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 5, 12, 24, 33, 19, 8, 6, 15, 21], - [ 1, 2, 5, 6, 3, 1.5, 1, 3, 4], - ]; - - USE my_graph = GD.Graph.bars(); - - my_graph.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'Two data sets', - - # shadows - bar_spacing => 8, - shadow_depth => 4, - shadowclr => 'dred', - - long_ticks => 1, - y_max_value => 40, - y_tick_number => 8, - y_label_skip => 2, - bar_spacing => 3, - - accent_treshold => 200, - - transparent => 0, - ); - my_graph.set_legend( 'Data set 1', 'Data set 2' ); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.bars plugin provides an interface to the GD::Graph::bars -class defined by the GD::Graph module. It allows one or more (x,y) data -sets to be plotted with each point represented by a bar, in addition -to axes and legends. - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/bars3d.pm b/lib/Template/Plugin/GD/Graph/bars3d.pm deleted file mode 100644 index 79a930b..0000000 --- a/lib/Template/Plugin/GD/Graph/bars3d.pm +++ /dev/null @@ -1,166 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::bars3d -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::bars3d -# package in the GD::Graph3D.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: bars3d.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::bars3d; - -require 5.004; - -use strict; -use GD::Graph::bars3d; -use Template::Plugin; -use base qw( GD::Graph::bars3d Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::bars3d - Create 3D bar graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.bars3d(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec", ], - [-5, -4, -3, -3, -1, 0, 2, 1, 3, 4, 6, 7], - [4, 3, 5, 6, 3,1.5, -1, -3, -4, -6, -7, -8], - [1, 2, 2, 3, 4, 3, 1, -1, 0, 2, 3, 2], - ]; - - USE my_graph = GD.Graph.bars3d(); - - my_graph.set( - x_label => 'Month', - y_label => 'Measure of success', - title => 'A 3d Bar Chart', - - y_max_value => 8, - y_min_value => -8, - y_tick_number => 16, - y_label_skip => 2, - box_axis => 0, - line_width => 3, - zero_axis_only => 1, - x_label_position => 1, - y_label_position => 1, - - x_label_skip => 3, - x_tick_offset => 2, - - transparent => 0, - ); - my_graph.set_legend("Us", "Them", "Others"); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.bars3d plugin provides an interface to the GD::Graph::bars3d -class defined by the GD::Graph3d module. It allows one or more (x,y) data -sets to be plotted as y versus x bars with a 3-dimensional appearance, -together with axes and legends. - -See L<GD::Graph3d> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph3d module was written by Jeremy Wadsack. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph3d is copyright (C) 1999,2000 Wadsack-Allen. All Rights Reserved. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph>, L<GD::Graph3d|GD::Graph3d> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/lines.pm b/lib/Template/Plugin/GD/Graph/lines.pm deleted file mode 100644 index 678cc64..0000000 --- a/lib/Template/Plugin/GD/Graph/lines.pm +++ /dev/null @@ -1,178 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::lines -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::lines -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: lines.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::lines; - -require 5.004; - -use strict; -use GD::Graph::lines; -use Template::Plugin; -use base qw( GD::Graph::lines Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::lines - Create line graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.lines(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - USE g = GD.Graph.lines(300,200); - x = [1, 2, 3, 4]; - y = [5, 4, 2, 3]; - g.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'Title' - ); - g.plot([x, y]).png | stdout(1); - END; - -%] - - [% FILTER null; - data = [ - ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec", ], - [-5, -4, -3, -3, -1, 0, 2, 1, 3, 4, 6, 7], - [4, 3, 5, 6, 3,1.5, -1, -3, -4, -6, -7, -8], - [1, 2, 2, 3, 4, 3, 1, -1, 0, 2, 3, 2], - ]; - - USE my_graph = GD.Graph.lines(); - - my_graph.set( - x_label => 'Month', - y_label => 'Measure of success', - title => 'A Simple Line Graph', - - y_max_value => 8, - y_min_value => -8, - y_tick_number => 16, - y_label_skip => 2, - box_axis => 0, - line_width => 3, - zero_axis_only => 1, - x_label_position => 1, - y_label_position => 1, - - x_label_skip => 3, - x_tick_offset => 2, - - transparent => 0, - ); - my_graph.set_legend("Us", "Them", "Others"); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.lines plugin provides an interface to the GD::Graph::lines -class defined by the GD::Graph module. It allows one or more (x,y) data -sets to be plotted as y versus x lines with axes and legends. - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/lines3d.pm b/lib/Template/Plugin/GD/Graph/lines3d.pm deleted file mode 100644 index 1f12715..0000000 --- a/lib/Template/Plugin/GD/Graph/lines3d.pm +++ /dev/null @@ -1,166 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::lines3d -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::lines3d -# package in the GD::Graph3D.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: lines3d.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::lines3d; - -require 5.004; - -use strict; -use GD::Graph::lines3d; -use Template::Plugin; -use base qw( GD::Graph::lines3d Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::lines3d - Create 3D line graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.lines3d(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec", ], - [-5, -4, -3, -3, -1, 0, 2, 1, 3, 4, 6, 7], - [4, 3, 5, 6, 3,1.5, -1, -3, -4, -6, -7, -8], - [1, 2, 2, 3, 4, 3, 1, -1, 0, 2, 3, 2], - ]; - - USE my_graph = GD.Graph.lines3d(); - - my_graph.set( - x_label => 'Month', - y_label => 'Measure of success', - title => 'A 3d Line Graph', - - y_max_value => 8, - y_min_value => -8, - y_tick_number => 16, - y_label_skip => 2, - box_axis => 0, - line_width => 3, - zero_axis_only => 1, - x_label_position => 1, - y_label_position => 1, - - x_label_skip => 3, - x_tick_offset => 2, - - transparent => 0, - ); - my_graph.set_legend("Us", "Them", "Others"); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.lines3d plugin provides an interface to the GD::Graph::lines3d -class defined by the GD::Graph3d module. It allows one or more (x,y) data -sets to be plotted as y versus x lines with a 3-dimensional appearance, -together with axes and legends. - -See L<GD::Graph3d> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph3d module was written by Jeremy Wadsack. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph3d is copyright (C) 1999,2000 Wadsack-Allen. All Rights Reserved. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph>, L<GD::Graph3d|GD::Graph3d> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/linespoints.pm b/lib/Template/Plugin/GD/Graph/linespoints.pm deleted file mode 100644 index 8dc48d9..0000000 --- a/lib/Template/Plugin/GD/Graph/linespoints.pm +++ /dev/null @@ -1,158 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::linespoints -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::linespoints -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: linespoints.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::linespoints; - -require 5.004; - -use strict; -use GD::Graph::linespoints; -use Template::Plugin; -use base qw( GD::Graph::linespoints Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::linespoints - Create line/point graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.linespoints(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [50, 52, 53, 54, 55, 56, 57, 58, 59], - [60, 61, 61, 63, 68, 66, 65, 61, 58], - [70, 72, 71, 74, 78, 73, 75, 71, 68], - ]; - - USE my_graph = GD.Graph.linespoints; - - my_graph.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'A Lines and Points Graph', - y_max_value => 80, - y_tick_number => 6, - y_label_skip => 2, - y_long_ticks => 1, - x_tick_length => 2, - markers => [ 1, 5 ], - skip_undef => 1, - transparent => 0, - ); - my_graph.set_legend('data set 1', 'data set 2', 'data set 3'); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.linespoints plugin provides an interface to the -GD::Graph::linespoints class defined by the GD::Graph module. It allows -one or more (x,y) data sets to be plotted as y versus x lines, plus -symbols placed at each point, in addition to axes and legends. - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/mixed.pm b/lib/Template/Plugin/GD/Graph/mixed.pm deleted file mode 100644 index 10dd533..0000000 --- a/lib/Template/Plugin/GD/Graph/mixed.pm +++ /dev/null @@ -1,176 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::mixed -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::mixed -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: mixed.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::mixed; - -require 5.004; - -use strict; -use GD::Graph::mixed; -use Template::Plugin; -use base qw( GD::Graph::mixed Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::mixed - Create mixed graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.mixed(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 1, 2, 5, 6, 3, 1.5, -1, -3, -4], - [ -4, -3, 1, 1, -3, -1.5, -2, -1, 0], - [ 9, 8, 9, 8.4, 7.1, 7.5, 8, 3, -3], - [ 0.1, 0.2, 0.5, 0.4, 0.3, 0.5, 0.1, 0, 0.4], - [ -0.1, 2, 5, 4, -3, 2.5, 3.2, 4, -4], - ]; - - USE my_graph = GD.Graph.mixed(); - - my_graph.set( - types => ['lines', 'lines', 'points', 'area', 'linespoints'], - default_type => 'points', - ); - - my_graph.set( - - x_label => 'X Label', - y_label => 'Y label', - title => 'A Mixed Type Graph', - - y_max_value => 10, - y_min_value => -5, - y_tick_number => 3, - y_label_skip => 0, - x_plot_values => 0, - y_plot_values => 0, - - long_ticks => 1, - x_ticks => 0, - - legend_marker_width => 24, - line_width => 3, - marker_size => 5, - - bar_spacing => 8, - - transparent => 0, - ); - - my_graph.set_legend('one', 'two', 'three', 'four', 'five', 'six'); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.mixed plugin provides an interface to the GD::Graph::mixed -class defined by the GD::Graph module. It allows one or more (x,y) data -sets to be plotted with various styles (lines, points, bars, areas etc). - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/pie.pm b/lib/Template/Plugin/GD/Graph/pie.pm deleted file mode 100644 index e72e26c..0000000 --- a/lib/Template/Plugin/GD/Graph/pie.pm +++ /dev/null @@ -1,141 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::pie -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::pie -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: pie.pm,v 1.55 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::pie; - -require 5.004; - -use strict; -use GD::Graph::pie; -use Template::Plugin; -use base qw( GD::Graph::pie Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::pie - Create pie charts with legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.pie(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th"], - [ 4, 2, 3, 4, 3, 3.5] - ]; - - USE my_graph = GD.Graph.pie( 250, 200 ); - - my_graph.set( - title => 'A Pie Chart', - label => 'Label', - axislabelclr => 'black', - pie_height => 36, - - transparent => 0, - ); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.pie plugin provides an interface to the GD::Graph::pie -class defined by the GD::Graph module. It allows an (x,y) data set to -be plotted as a pie chart. The x values are typically strings. - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/pie3d.pm b/lib/Template/Plugin/GD/Graph/pie3d.pm deleted file mode 100644 index 5f677e0..0000000 --- a/lib/Template/Plugin/GD/Graph/pie3d.pm +++ /dev/null @@ -1,145 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::pie3d -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::pie3d -# package in the GD::Graph3D.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: pie3d.pm,v 1.55 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::pie3d; - -require 5.004; - -use strict; -use GD::Graph::pie3d; -use Template::Plugin; -use base qw( GD::Graph::pie3d Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::pie3d - Create 3D pie charts with legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.pie3d(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th"], - [ 4, 2, 3, 4, 3, 3.5] - ]; - - USE my_graph = GD.Graph.pie3d( 250, 200 ); - - my_graph.set( - title => 'A Pie Chart', - label => 'Label', - axislabelclr => 'black', - pie_height => 36, - - transparent => 0, - ); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.pie3d plugin provides an interface to the GD::Graph::pie3d -class defined by the GD::Graph module. It allows an (x,y) data set to -be plotted as a 3d pie chart. The x values are typically strings. - -Note that GD::Graph::pie already produces a 3d effect, so GD::Graph::pie3d -is just a wrapper around GD::Graph::pie. Similarly, the plugin -GD.Graph.pie3d is effectively the same as the plugin GD.Graph.pie. - -See L<GD::Graph3d> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph3d module was written by Jeremy Wadsack. The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph3d is copyright (c) 1999,2000 Wadsack-Allen. All Rights Reserved. GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::points|Template::Plugin::GD::Graph::points>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<GD::Graph|GD::Graph>, L<GD::Graph3d|GD::Graph3d> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Graph/points.pm b/lib/Template/Plugin/GD/Graph/points.pm deleted file mode 100644 index 97acf51..0000000 --- a/lib/Template/Plugin/GD/Graph/points.pm +++ /dev/null @@ -1,155 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Graph::points -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Graph::points -# package in the GD::Graph.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: points.pm,v 1.57 2004/01/13 16:20:56 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Graph::points; - -require 5.004; - -use strict; -use GD::Graph::points; -use Template::Plugin; -use base qw( GD::Graph::points Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.57 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return $class->SUPER::new(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - - -sub set_legend -{ - my $self = shift; - - $self->SUPER::set_legend(ref $_[0] ? @{$_[0]} : @_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Graph::points - Create point graphs with axes and legends - -=head1 SYNOPSIS - - [% USE g = GD.Graph.points(x_size, y_size); %] - -=head1 EXAMPLES - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 5, 12, 24, 33, 19, 8, 6, 15, 21], - [ 1, 2, 5, 6, 3, 1.5, 2, 3, 4], - ]; - USE my_graph = GD.Graph.points(); - my_graph.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'A Points Graph', - y_max_value => 40, - y_tick_number => 8, - y_label_skip => 2, - legend_placement => 'RC', - long_ticks => 1, - marker_size => 6, - markers => [ 1, 7, 5 ], - - transparent => 0, - ); - my_graph.set_legend('one', 'two'); - my_graph.plot(data).png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Graph.points plugin provides an interface to the GD::Graph::points -class defined by the GD::Graph module. It allows one or more (x,y) data -sets to be plotted as points, in addition to axes and legends. - -See L<GD::Graph> for more details. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Graph module was written by Martien Verbruggen. - - -=head1 VERSION - -1.57, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Graph is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Graph::lines|Template::Plugin::GD::Graph::lines>, L<Template::Plugin::GD::Graph::lines3d|Template::Plugin::GD::Graph::lines3d>, L<Template::Plugin::GD::Graph::bars|Template::Plugin::GD::Graph::bars>, L<Template::Plugin::GD::Graph::bars3d|Template::Plugin::GD::Graph::bars3d>, L<Template::Plugin::GD::Graph::linespoints|Template::Plugin::GD::Graph::linespoints>, L<Template::Plugin::GD::Graph::area|Template::Plugin::GD::Graph::area>, L<Template::Plugin::GD::Graph::mixed|Template::Plugin::GD::Graph::mixed>, L<Template::Plugin::GD::Graph::pie|Template::Plugin::GD::Graph::pie>, L<Template::Plugin::GD::Graph::pie3d|Template::Plugin::GD::Graph::pie3d>, L<GD::Graph|GD::Graph> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Image.pm b/lib/Template/Plugin/GD/Image.pm deleted file mode 100644 index 46a06d7..0000000 --- a/lib/Template/Plugin/GD/Image.pm +++ /dev/null @@ -1,184 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Image -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Image -# class in the GD.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Image.pm,v 1.55 2004/01/13 16:20:46 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Image; - -require 5.004; - -use strict; -use GD; -use Template::Plugin; -use base qw( GD Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return new GD::Image(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Image - Interface to GD Graphics Library - -=head1 SYNOPSIS - - [% USE im = GD.Image(x_size, y_size) %] - -=head1 EXAMPLES - - [% FILTER null; - USE gdc = GD.Constants; - USE im = GD.Image(200,100); - black = im.colorAllocate(0 ,0, 0); - red = im.colorAllocate(255,0, 0); - r = im.string(gdc.gdLargeFont, 10, 10, "Large Red Text", red); - im.png | stdout(1); - END; - -%] - - [% FILTER null; - USE im = GD.Image(100,100); - # allocate some colors - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0, 255); - # Draw a blue oval - im.arc(50,50,95,75,0,360,blue); - # And fill it with red - im.fill(50,50,red); - # Output binary image in PNG format - im.png | stdout(1); - END; - -%] - - [% FILTER null; - USE im = GD.Image(100,100); - USE c = GD.Constants; - USE poly = GD.Polygon; - - # allocate some colors - white = im.colorAllocate(255,255,255); - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0,255); - green = im.colorAllocate(0, 255,0); - - # make the background transparent and interlaced - im.transparent(white); - im.interlaced('true'); - - # Put a black frame around the picture - im.rectangle(0,0,99,99,black); - - # Draw a blue oval - im.arc(50,50,95,75,0,360,blue); - - # And fill it with red - im.fill(50,50,red); - - # Draw a blue triangle - poly.addPt(50,0); - poly.addPt(99,99); - poly.addPt(0,99); - im.filledPolygon(poly, blue); - - # Output binary image in PNG format - im.png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Image plugin provides an interface to GD.pm's GD::Image class. -The GD::Image class is the main interface to GD.pm. - -It is very important that no extraneous template output appear before or -after the image. Since some methods return values that would otherwise -appear in the output, it is recommended that GD.Image code be wrapped in -a null filter. The methods that produce the final output (eg, png, jpeg, -gd etc) can then explicitly make their output appear by using the -stdout filter, with a non-zero argument to force binary mode (required -for non-modern operating systems). - -See L<GD> for a complete description of the GD library and all the -methods that can be called via the GD.Image plugin. -See L<Template::Plugin::GD::Constants> for a plugin that allows you -access to GD.pm's constants. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -Lincoln D. Stein wrote the GD.pm interface to the GD library. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -The GD.pm interface is copyright 1995-2000, Lincoln D. Stein. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Polygon|Template::Plugin::GD::Polygon>, L<Template::Plugin::GD::Constants|Template::Plugin::GD::Constants>, L<GD|GD> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Polygon.pm b/lib/Template/Plugin/GD/Polygon.pm deleted file mode 100644 index 0d1d5c6..0000000 --- a/lib/Template/Plugin/GD/Polygon.pm +++ /dev/null @@ -1,155 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Polygon -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Polygon -# class in the GD.pm module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Polygon.pm,v 1.55 2004/01/13 16:20:46 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Polygon; - -require 5.004; - -use strict; -use GD; -use Template::Plugin; -use base qw( Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - return new GD::Polygon(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Polygon - Interface to GD module Polygon class - -=head1 SYNOPSIS - - [% USE poly = GD.Polygon; - poly.addPt(50,0); - poly.addPt(99,99); - %] - -=head1 EXAMPLES - - [% FILTER null; - USE im = GD.Image(100,100); - USE c = GD.Constants; - - # allocate some colors - white = im.colorAllocate(255,255,255); - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0,255); - green = im.colorAllocate(0, 255,0); - - # make the background transparent and interlaced - im.transparent(white); - im.interlaced('true'); - - # Put a black frame around the picture - im.rectangle(0,0,99,99,black); - - # Draw a blue oval - im.arc(50,50,95,75,0,360,blue); - - # And fill it with red - im.fill(50,50,red); - - # Draw a blue triangle by defining a polygon - USE poly = GD.Polygon; - poly.addPt(50,0); - poly.addPt(99,99); - poly.addPt(0,99); - im.filledPolygon(poly, blue); - - # Output binary image in PNG format - im.png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Polygon plugin provides an interface to GD.pm's GD::Polygon class. - -See L<GD> for a complete description of the GD library and all the -methods that can be called via the GD.Polygon plugin. -See L<Template::Plugin::GD::Image> for the main interface to the -GD functions. -See L<Template::Plugin::GD::Constants> for a plugin that allows you -access to GD.pm's constants. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -Lincoln D. Stein wrote the GD.pm interface to the GD library. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -The GD.pm interface is copyright 1995-2000, Lincoln D. Stein. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Image|Template::Plugin::GD::Image>, L<Template::Plugin::GD::Constants|Template::Plugin::GD::Constants>, L<GD|GD> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Text.pm b/lib/Template/Plugin/GD/Text.pm deleted file mode 100644 index f18b2e0..0000000 --- a/lib/Template/Plugin/GD/Text.pm +++ /dev/null @@ -1,140 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Text -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Text -# module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Text.pm,v 1.55 2004/01/13 16:20:46 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Text; - -require 5.004; - -use strict; -use GD::Text; -use Template::Plugin; -use base qw( GD::Text Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - return new GD::Text(@_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Text - Text utilities for use with GD - -=head1 SYNOPSIS - - [% USE gd_text = GD.Text %] - -=head1 EXAMPLES - - [% - USE gd_c = GD.Constants; - USE t = GD.Text; - x = t.set_text('Some text'); - r = t.get('width', 'height', 'char_up', 'char_down'); - r.join(":"); "\n"; # returns 54:13:13:0. - -%] - - [% - USE gd_c = GD.Constants; - USE t = GD.Text(text => 'FooBar Banana', font => gd_c.gdGiantFont); - t.get('width'); "\n"; # returns 117. - -%] - -=head1 DESCRIPTION - -The GD.Text plugin provides an interface to the GD::Text module. -It allows attributes of strings such as width and height in pixels -to be computed. - -See L<GD::Text> for more details. See -L<Template::Plugin::GD::Text::Align> and -L<Template::Plugin::GD::Text::Wrap> for plugins that -allow you to render aligned or wrapped text in GD images. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Text module was written by Martien Verbruggen. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Text is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Text::Wrap|Template::Plugin::GD::Text::Wrap>, L<Template::Plugin::GD::Text::Align|Template::Plugin::GD::Text::Align>, L<GD|GD>, L<GD::Text|GD::Text> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Text/Align.pm b/lib/Template/Plugin/GD/Text/Align.pm deleted file mode 100644 index 8b79069..0000000 --- a/lib/Template/Plugin/GD/Text/Align.pm +++ /dev/null @@ -1,147 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Text::Align -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Text::Align -# module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Align.pm,v 1.55 2004/01/13 16:21:46 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Text::Align; - -require 5.004; - -use strict; -use GD::Text::Align; -use Template::Plugin; -use base qw( GD::Text::Align Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - my $gd = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - return $class->SUPER::new($gd, @_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Text::Align - Draw aligned strings in GD images - -=head1 SYNOPSIS - - [% USE align = GD.Text.Align(gd_image); %] - -=head1 EXAMPLES - - [% FILTER null; - USE im = GD.Image(100,100); - USE gdc = GD.Constants; - # allocate some colors - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0, 255); - # Draw a blue oval - im.arc(50,50,95,75,0,360,blue); - - USE a = GD.Text.Align(im); - a.set_font(gdc.gdLargeFont); - a.set_text("Hello"); - a.set(colour => red, halign => "center"); - a.draw(50,70,0); - - # Output image in PNG format - im.png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Text.Align plugin provides an interface to the GD::Text::Align -module. It allows text to be drawn in GD images with various alignments -and orientations. - -See L<GD::Text::Align> for more details. See -L<Template::Plugin::GD::Text::Wrap> for a plugin -that allow you to render wrapped text in GD images. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Text module was written by Martien Verbruggen. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Text is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Text|Template::Plugin::GD::Text>, L<Template::Plugin::GD::Text::Wrap|Template::Plugin::GD::Text::Wrap>, L<GD|GD>, L<GD::Text::Align|GD::Text::Align> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/GD/Text/Wrap.pm b/lib/Template/Plugin/GD/Text/Wrap.pm deleted file mode 100644 index 0438599..0000000 --- a/lib/Template/Plugin/GD/Text/Wrap.pm +++ /dev/null @@ -1,183 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::GD::Text::Wrap -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the GD::Text::Wrap -# module. -# -# AUTHOR -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 2001 Craig Barratt. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Wrap.pm,v 1.55 2004/01/13 16:21:46 abw Exp $ -# -#============================================================================ - -package Template::Plugin::GD::Text::Wrap; - -require 5.004; - -use strict; -use GD::Text::Wrap; -use Template::Plugin; -use base qw( GD::Text::Wrap Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.55 $ =~ /(\d+)\.(\d+)/); - -sub new -{ - my $class = shift; - my $context = shift; - my $gd = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - return $class->SUPER::new($gd, @_); -} - -sub set -{ - my $self = shift; - - push(@_, %{pop(@_)}) if ( @_ & 1 && ref($_[@_-1]) eq "HASH" ); - $self->SUPER::set(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::GD::Text::Wrap - Break and wrap strings in GD images - -=head1 SYNOPSIS - - [% USE align = GD.Text.Wrap(gd_image); %] - -=head1 EXAMPLES - - [% FILTER null; - USE gd = GD.Image(200,400); - USE gdc = GD.Constants; - black = gd.colorAllocate(0, 0, 0); - green = gd.colorAllocate(0, 255, 0); - txt = "This is some long text. " | repeat(10); - USE wrapbox = GD.Text.Wrap(gd, - line_space => 4, - color => green, - text => txt, - ); - wrapbox.set_font(gdc.gdMediumBoldFont); - wrapbox.set(align => 'center', width => 160); - wrapbox.draw(20, 20); - gd.png | stdout(1); - END; - -%] - - [% txt = BLOCK -%] - Lorem ipsum dolor sit amet, consectetuer adipiscing elit, - sed diam nonummy nibh euismod tincidunt ut laoreet dolore - magna aliquam erat volutpat. - [% END -%] - [% FILTER null; - # - # This example follows the example in GD::Text::Wrap, except - # we create a second image that is a copy just enough of the - # first image to hold the final text, plus a border. - # - USE gd = GD.Image(400,400); - USE gdc = GD.Constants; - green = gd.colorAllocate(0, 255, 0); - blue = gd.colorAllocate(0, 0, 255); - USE wrapbox = GD.Text.Wrap(gd, - line_space => 4, - color => green, - text => txt, - ); - wrapbox.set_font(gdc.gdMediumBoldFont); - wrapbox.set(align => 'center', width => 140); - rect = wrapbox.get_bounds(5, 5); - x0 = rect.0; - y0 = rect.1; - x1 = rect.2 + 9; - y1 = rect.3 + 9; - gd.filledRectangle(0, 0, x1, y1, blue); - gd.rectangle(0, 0, x1, y1, green); - wrapbox.draw(x0, y0); - nx = x1 + 1; - ny = y1 + 1; - USE gd2 = GD.Image(nx, ny); - gd2.copy(gd, 0, 0, 0, 0, x1, y1); - gd2.png | stdout(1); - END; - -%] - -=head1 DESCRIPTION - -The GD.Text.Wrap plugin provides an interface to the GD::Text::Wrap -module. It allows multiples line of text to be drawn in GD images with -various wrapping and alignment. - -See L<GD::Text::Wrap> for more details. See -L<Template::Plugin::GD::Text::Align> for a plugin -that allow you to draw text with various alignment -and orientation. - -=head1 AUTHOR - -Craig Barratt E<lt>craig@arraycomm.comE<gt> - - -The GD::Text module was written by Martien Verbruggen. - - -=head1 VERSION - -1.55, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Craig Barratt E<lt>craig@arraycomm.comE<gt> - -GD::Text is copyright 1999 Martien Verbruggen. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Plugin::GD|Template::Plugin::GD>, L<Template::Plugin::GD::Text::Align|Template::Plugin::GD::Text::Align>, L<GD|GD>, L<GD::Text::Wrap|GD::Text::Wrap> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/HTML.pm b/lib/Template/Plugin/HTML.pm deleted file mode 100644 index 5cb63e0..0000000 --- a/lib/Template/Plugin/HTML.pm +++ /dev/null @@ -1,197 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::HTML -# -# DESCRIPTION -# -# Template Toolkit plugin providing useful functionality for generating -# HTML. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -#---------------------------------------------------------------------------- -# -# $Id: HTML.pm,v 2.56 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::HTML; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.56 $ =~ /(\d+)\.(\d+)/); - -sub new { - my ($class, $context, @args) = @_; - my $hash = ref $args[-1] eq 'HASH' ? pop @args : { }; - bless { - _SORTED => $hash->{ sorted } || 0, - }, $class; -} - -sub element { - my ($self, $name, $attr) = @_; - ($name, $attr) = %$name if ref $name eq 'HASH'; - return '' unless defined $name and length $name; - $attr = $self->attributes($attr); - $attr = " $attr" if $attr; - return "<$name$attr>"; -} - -sub attributes { - my ($self, $hash) = @_; - return '' unless UNIVERSAL::isa($hash, 'HASH'); - - my @keys = keys %$hash; - @keys = sort @keys if $self->{ _SORTED }; - - join(' ', map { - "$_=\"" . $self->escape( $hash->{ $_ } ) . '"'; - } @keys); -} - -sub escape { - my ($self, $text) = @_; - for ($text) { - s/&/&/g; - s/</</g; - s/>/>/g; - s/"/"/g; - } - $text; -} - -sub url { - my ($self, $text) = @_; - return undef unless defined $text; - $text =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; - return $text; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::HTML - Plugin to create HTML elements - -=head1 SYNOPSIS - - [% USE HTML %] - - [% HTML.escape("if (a < b && c > d) ..." %] - - [% HTML.element(table => { border => 1, cellpadding => 2 }) %] - - [% HTML.attributes(border => 1, cellpadding => 2) %] - -=head1 DESCRIPTION - -The HTML plugin is very new and very basic, implementing a few useful -methods for generating HTML. It is likely to be extended in the future -or integrated with a larger project to generate HTML elements in a generic -way (as discussed recently on the mod_perl mailing list). - -=head1 METHODS - -=head2 escape(text) - -Returns the source text with any HTML reserved characters such as -E<lt>, E<gt>, etc., correctly esacped to their entity equivalents. - -=head2 attributes(hash) - -Returns the elements of the hash array passed by reference correctly -formatted (e.g. values quoted and correctly escaped) as attributes for -an HTML element. - -=head2 element(type, attributes) - -Generates an HTML element of the specified type and with the attributes -provided as an optional hash array reference as the second argument or -as named arguments. - - [% HTML.element(table => { border => 1, cellpadding => 2 }) %] - [% HTML.element('table', border=1, cellpadding=2) %] - [% HTML.element(table => attribs) %] - -=head1 DEBUGGING - -The HTML plugin accepts a 'sorted' option as a constructor argument -which, when set to any true value, causes the attributes generated by -the attributes() method (either directly or via element()) to be -returned in sorted order. Order of attributes isn't important in -HTML, but this is provided mainly for the purposes of debugging where -it is useful to have attributes generated in a deterministic order -rather than whatever order the hash happened to feel like returning -the keys in. - - [% USE HTML(sorted=1) %] - [% HTML.element( foo => { charlie => 1, bravo => 2, alpha => 3 } ) %] - -generates: - - <foo alpha="3" bravo="2" charlie="1"> - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.56, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Image.pm b/lib/Template/Plugin/Image.pm deleted file mode 100644 index 4eb509c..0000000 --- a/lib/Template/Plugin/Image.pm +++ /dev/null @@ -1,425 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Image -# -# DESCRIPTION -# Plugin for encapsulating information about an image. -# -# AUTHOR -# Andy Wardley <abw@wardley.org> -# -# COPYRIGHT -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# $Id: Image.pm,v 1.13 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Image; - -require 5.004; - -use strict; -use Template::Exception; -use Template::Plugin; -use File::Spec; -#use Image::Info; -#use Image::Size; - -use base qw( Template::Plugin ); -use vars qw( $VERSION $AUTOLOAD ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.13 $ =~ /(\d+)\.(\d+)/); - -BEGIN { - if (eval { require Image::Info; }) { - *img_info = \&Image::Info::image_info; - } - elsif (eval { require Image::Size; }) { - *img_info = sub { - my $file = shift; - my @stuff = Image::Size::imgsize($file); - return { "width" => $stuff[0], - "height" => $stuff[1], - "error" => - # imgsize returns either a three letter file type - # or an error message as third value - (defined($stuff[2]) && length($stuff[2]) > 3 - ? $stuff[2] - : undef), - }; - } - } - else { - die(Template::Exception->new("image", - "Couldn't load Image::Info or Image::Size: $@")); - } - -} - -#------------------------------------------------------------------------ -# new($context, $name, \%config) -# -# Create a new Image object. Takes the pathname of the file as -# the argument following the context and an optional -# hash reference of configuration parameters. -#------------------------------------------------------------------------ - -sub new { - my $config = ref($_[-1]) eq 'HASH' ? pop(@_) : { }; - my ($class, $context, $name) = @_; - my ($root, $file, $type); - - # name can be a positional or named argument - $name = $config->{ name } unless defined $name; - - return $class->throw('no image file specified') - unless defined $name and length $name; - - # name can be specified as an absolute path or relative - # to a root directory - - if ($root = $config->{ root }) { - $file = File::Spec->catfile($root, $name); - } - else { - $file = $name; - } - - # Make a note of whether we are using Image::Size or - # Image::Info -- at least for the test suite - $type = $INC{"Image/Size.pm"} ? "Image::Size" : "Image::Info"; - - # do we want to check to see if file exists? - - bless { - name => $name, - file => $file, - root => $root, - type => $type, - }, $class; -} - -#------------------------------------------------------------------------ -# init() -# -# Calls image_info on $self->{ file } -#------------------------------------------------------------------------ - -sub init { - my $self = shift; - return $self if $self->{ size }; - - my $image = img_info($self->{ file }); - return $self->throw($image->{ error }) if defined $image->{ error }; - - @$self{ keys %$image } = values %$image; - $self->{ size } = [ $image->{ width }, $image->{ height } ]; - - $self->{ modtime } = (stat $self->{ file })[10]; - - return $self; -} - -#------------------------------------------------------------------------ -# attr() -# -# Return the width and height as HTML/XML attributes. -#------------------------------------------------------------------------ - -sub attr { - my $self = shift; - my $size = $self->size(); - return "width=\"$size->[0]\" height=\"$size->[1]\""; -} - -#------------------------------------------------------------------------ -# modtime() -# -# Return last modification time as a time_t: -# -# [% date.format(image.modtime, "%Y/%m/%d") %] -#------------------------------------------------------------------------ - -sub modtime { - my $self = shift; - $self->init; - return $self->{ modtime }; -} - -#------------------------------------------------------------------------ -# tag(\%options) -# -# Return an XHTML img tag. -#------------------------------------------------------------------------ - -sub tag { - my $self = shift; - my $options = ref $_[0] eq 'HASH' ? shift : { @_ }; - - my $tag = "<img src=\"$self->{ name }\" " . $self->attr(); - - if (%$options) { - while (my ($key, $val) = each %$options) { - $tag .= " $key=\"$val\""; - } - } - - $tag .= ' />'; - - return $tag; -} - - -sub throw { - my ($self, $error) = @_; - die (Template::Exception->new('Image', $error)); -} - -sub AUTOLOAD { - my $self = shift; - (my $a = $AUTOLOAD) =~ s/.*:://; - - $self->init; - return $self->{ $a }; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Image - Plugin access to image sizes - -=head1 SYNOPSIS - - [% USE Image(filename) %] - [% Image.width %] - [% Image.height %] - [% Image.size.join(', ') %] - [% Image.attr %] - [% Image.tag %] - -=head1 DESCRIPTION - -This plugin provides an interface to the Image::Info or Image::Size -modules for determining the size of image files. - -You can specify the plugin name as either 'Image' or 'image'. The -plugin object created will then have the same name. The file name of -the image should be specified as a positional or named argument. - - [% # all these are valid, take your pick %] - [% USE Image('foo.gif') %] - [% USE image('bar.gif') %] - [% USE Image 'ping.gif' %] - [% USE image(name='baz.gif') %] - [% USE Image name='pong.gif' %] - -You can also provide an alternate name for an Image plugin object. - - [% USE img1 = image 'foo.gif' %] - [% USE img2 = image 'bar.gif' %] - -The 'width' and 'height' methods return the width and height of the -image, respectively. The 'size' method returns a reference to a 2 -element list containing the width and height. - - [% USE image 'foo.gif' %] - width: [% image.width %] - height: [% image.height %] - size: [% image.size.join(', ') %] - -The 'attr' method returns the height and width as HTML/XML attributes. - - [% USE image 'foo.gif' %] - [% image.attr %] - -Typical output: - - width="60" height="20" - -The 'tag' method returns a complete XHTML tag referencing the image. - - [% USE image 'foo.gif' %] - [% image.tag %] - -Typical output: - - <img src="foo.gif" width="60" height="20" /> - -You can provide any additional attributes that should be added to the -XHTML tag. - - - [% USE image 'foo.gif' %] - [% image.tag(border=0, class="logo") %] - -Typical output: - - <img src="foo.gif" width="60" height="20" border="0" class="logo" /> - -The 'modtime' method returns the ctime of the file in question, suitable -for use with date.format: - - [% USE image 'foo.gif' %] - [% USE date %] - [% date.format(image.modtime, "%B, %e %Y") %] - -=head1 CATCHING ERRORS - -If the image file cannot be found then the above methods will throw an -'Image' error. You can enclose calls to these methods in a -TRY...CATCH block to catch any potential errors. - - [% TRY; - image.width; - CATCH; - error; # print error - END - %] - -=head1 USING Image::Info - -At run time, the plugin tries to load Image::Info in preference to -Image::Size. If Image::Info is found, then some additional methods are -available, in addition to 'size', 'width', 'height', 'attr', and 'tag'. -These additional methods are named after the elements that Image::Info -retrieves from the image itself; see L<Image::Info> for more details --- the types of methods available depend on the type of image. -These additional methods will always include the following: - -=over 4 - -=item file_media_type - -This is the MIME type that is appropriate for the given file format. -The corresponding value is a string like: "image/png" or "image/jpeg". - -=item file_ext - -The is the suggested file name extention for a file of the given -file format. The value is a 3 letter, lowercase string like -"png", "jpg". - - -=item color_type - -The value is a short string describing what kind of values the pixels -encode. The value can be one of the following: - - Gray - GrayA - RGB - RGBA - CMYK - YCbCr - CIELab - -These names can also be prefixed by "Indexed-" if the image is -composed of indexes into a palette. Of these, only "Indexed-RGB" is -likely to occur. - -(It is similar to the TIFF field PhotometricInterpretation, but this -name was found to be too long, so we used the PNG inpired term -instead.) - -=item resolution - -The value of this field normally gives the physical size of the image -on screen or paper. When the unit specifier is missing then this field -denotes the squareness of pixels in the image. - -The syntax of this field is: - - <res> <unit> - <xres> "/" <yres> <unit> - <xres> "/" <yres> - -The E<lt>resE<gt>, E<lt>xresE<gt> and E<lt>yresE<gt> fields are -numbers. The E<lt>unitE<gt> is a string like C<dpi>, C<dpm> or -C<dpcm> (denoting "dots per inch/cm/meter). - -=item SamplesPerPixel - -This says how many channels there are in the image. For some image -formats this number might be higher than the number implied from the -C<color_type>. - -=item BitsPerSample - -This says how many bits are used to encode each of samples. The value -is a reference to an array containing numbers. The number of elements -in the array should be the same as C<SamplesPerPixel>. - -=item Comment - -Textual comments found in the file. The value is a reference to an -array if there are multiple comments found. - -=item Interlace - -If the image is interlaced, then this tell which interlace method is -used. - -=item Compression - -This tell which compression algorithm is used. - -=item Gamma - -A number. - - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -1.13, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Iterator.pm b/lib/Template/Plugin/Iterator.pm deleted file mode 100644 index 0f33b2f..0000000 --- a/lib/Template/Plugin/Iterator.pm +++ /dev/null @@ -1,118 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Iterator -# -# DESCRIPTION -# -# Plugin to create a Template::Iterator from a list of items and optional -# configuration parameters. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Iterator.pm,v 2.62 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Iterator; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; -use Template::Iterator; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.62 $ =~ /(\d+)\.(\d+)/); - -#------------------------------------------------------------------------ -# new($context, \@data, \%args) -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - Template::Iterator->new(@_); -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Iterator - Plugin to create iterators (Template::Iterator) - -=head1 SYNOPSIS - - [% USE iterator(list, args) %] - - [% FOREACH item = iterator %] - [% '<ul>' IF iterator.first %] - <li>[% item %] - [% '</ul>' IF iterator.last %] - [% END %] - -=head1 DESCRIPTION - -The iterator plugin provides a way to create a Template::Iterator object -to iterate over a data set. An iterator is implicitly automatically by the -FOREACH directive. This plugin allows the iterator to be explicitly created -with a given name. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.62, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::Iterator|Template::Iterator> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Pod.pm b/lib/Template/Plugin/Pod.pm deleted file mode 100644 index e5f82c2..0000000 --- a/lib/Template/Plugin/Pod.pm +++ /dev/null @@ -1,116 +0,0 @@ -#============================================================================== -# -# Template::Plugin::Pod -# -# DESCRIPTION -# Pod parser and object model. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -# REVISION -# $Id: Pod.pm,v 2.62 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Pod; - -require 5.004; - -use strict; -use Template::Plugin; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.62 $ =~ /(\d+)\.(\d+)/); - -use Pod::POM; - -#------------------------------------------------------------------------ -# new($context, \%config) -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - - Pod::POM->new(@_); -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Pod - Plugin interface to Pod::POM (Pod Object Model) - -=head1 SYNOPSIS - - [% USE Pod(podfile) %] - - [% FOREACH head1 = Pod.head1; - FOREACH head2 = head1/head2; - ... - END; - END - %] - -=head1 DESCRIPTION - -This plugin is an interface to the Pod::POM module. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.62, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Pod::POM|Pod::POM> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Procedural.pm b/lib/Template/Plugin/Procedural.pm deleted file mode 100644 index 8601225..0000000 --- a/lib/Template/Plugin/Procedural.pm +++ /dev/null @@ -1,170 +0,0 @@ -#============================================================================== -# -# Template::Plugin::Procedural -# -# DESCRIPTION -# -# A Template Plugin to provide a Template Interface to Data::Dumper -# -# AUTHOR -# Mark Fowler <mark@twoshortplanks.com> -# -# COPYRIGHT -# -# Copyright (C) 2002 Mark Fowler. All Rights Reserved -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#------------------------------------------------------------------------------ -# -# $Id: Procedural.pm,v 1.11 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================== - -package Template::Plugin::Procedural; - -require 5.004; - -use strict; - -use vars qw( $VERSION $DEBUG $AUTOLOAD ); -use base qw( Template::Plugin ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.11 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; - -#------------------------------------------------------------------------ -# load -#------------------------------------------------------------------------ - -sub load -{ - my ($class, $context) = @_; - - # create a proxy namespace that will be used for objects - my $proxy = "Template::Plugin::" . $class; - - # okay, in our proxy create the autoload routine that will - # call the right method in the real class - no strict "refs"; - *{ $proxy . "::AUTOLOAD" } = - sub - { - # work out what the method is called - $AUTOLOAD =~ s!^.*::!!; - - print STDERR "Calling '$AUTOLOAD' in '$class'\n" - if $DEBUG; - - # look up the sub for that method (but in a OO way) - my $uboat = $class->can($AUTOLOAD); - - # if it existed call it as a subroutine, not as a method - if ($uboat) - { - shift @_; - return $uboat->(@_); - } - - print STDERR "Eeek, no such method '$AUTOLOAD'\n" - if $DEBUG; - - return ""; - }; - - # create a simple new method that simply returns a blessed - # scalar as the object. - *{ $proxy . "::new" } = - sub - { - my $this; - return bless \$this, $_[0]; - }; - - return $proxy; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Procedural - Base class for procedural plugins - -=head1 SYNOPSIS - - package Template::Plugin::LWPSimple; - use base qw(Template::Plugin::Procedural); - use LWP::Simple; # exports 'get' - 1; - - [% USE LWPSimple %] - [% LWPSimple.get("http://www.tt2.org/") %] - -=head1 DESCRIPTION - -B<Template::Plugin::Procedural> is a base class for Template Toolkit -plugins that causes defined subroutines to be called directly rather -than as a method. Essentially this means that subroutines will not -receive the class name or object as its first argument. - -This is most useful when creating plugins for modules that normally -work by exporting subroutines that do not expect such additional -arguments. - -Despite the fact that subroutines will not be called in an OO manner, -inheritance still function as normal. A class that uses -B<Template::Plugin::Procedural> can be subclassed and both subroutines -defined in the subclass and subroutines defined in the original class -will be available to the Template Toolkit and will be called without -the class/object argument. - -=head1 AUTHOR - -Mark Fowler E<lt>mark@twoshortplanks.comE<gt> - -L<http://www.twoshortplanks.com|http://www.twoshortplanks.com> - - - - -=head1 VERSION - -1.11, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2002 Mark Fowler E<lt>mark@twoshortplanks.comE<gt> - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/String.pm b/lib/Template/Plugin/String.pm deleted file mode 100644 index 34dd007..0000000 --- a/lib/Template/Plugin/String.pm +++ /dev/null @@ -1,796 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::String -# -# DESCRIPTION -# Template Toolkit plugin to implement a basic String object. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2001 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. -# -# REVISION -# $Id: String.pm,v 2.33 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::String; - -require 5.004; - -use strict; -use Template::Plugin; -use Template::Exception; - -use base qw( Template::Plugin ); -use vars qw( $VERSION $ERROR); -use overload q|""| => "text", - fallback => 1; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.33 $ =~ /(\d+)\.(\d+)/); -$ERROR = ''; - -*centre = \*center; -*append = \*push; -*prepend = \*unshift; - -#------------------------------------------------------------------------ - -sub new { - my ($class, @args) = @_; - my $context = ref $class ? undef : shift(@args); - my $config = @args && ref $args[-1] eq 'HASH' ? pop(@args) : { }; - - $class = ref($class) || $class; - - my $text = defined $config->{ text } - ? $config->{ text } - : (@args ? shift(@args) : ''); - -# print STDERR "text: [$text]\n"; -# print STDERR "class: [$class]\n"; - - my $self = bless { - text => $text, - filters => [ ], - _CONTEXT => $context, - }, $class; - - my $filter = $config->{ filter } || $config->{ filters }; - - # install any output filters specified as 'filter' or 'filters' option - $self->output_filter($filter) - if $filter; - - return $self; -} - - -sub text { - my $self = shift; - return $self->{ text } unless @{ $self->{ filters } }; - - my $text = $self->{ text }; - my $context = $self->{ _CONTEXT }; - - foreach my $dispatch (@{ $self->{ filters } }) { - my ($name, $args) = @$dispatch; - my $code = $context->filter($name, $args) - || $self->throw($context->error()); - $text = &$code($text); - } - return $text; -} - - -sub copy { - my $self = shift; - $self->new($self->{ text }); -} - - -sub throw { - my $self = shift; - - die (Template::Exception->new('String', join('', @_))); -} - - -#------------------------------------------------------------------------ -# output_filter($filter) -# -# Install automatic output filter(s) for the string. $filter can a list: -# [ 'name1', 'name2' => [ ..args.. ], name4 => { ..args.. } ] or a hash -# { name1 => '', name2 => [ args ], name3 => { args } } -#------------------------------------------------------------------------ - -sub output_filter { - my ($self, $filter) = @_; - my ($name, $args, $dispatch); - my $filters = $self->{ filters }; - my $count = 0; - - if (ref $filter eq 'HASH') { - $filter = [ %$filter ]; - } - elsif (ref $filter ne 'ARRAY') { - $filter = [ split(/\s*\W+\s*/, $filter) ]; - } - - while (@$filter) { - $name = shift @$filter; - - # args may follow as a reference (or empty string, e.g. { foo => '' } - if (@$filter && (ref($filter->[0]) || ! length $filter->[0])) { - $args = shift @$filter; - if ($args) { - $args = [ $args ] unless ref $args eq 'ARRAY'; - } - else { - $args = [ ]; - } - } - else { - $args = [ ]; - } - -# $self->DEBUG("adding output filter $name(@$args)\n"); - - push(@$filters, [ $name, $args ]); - $count++; - } - - return ''; -} - - -#------------------------------------------------------------------------ - -sub push { - my $self = shift; - $self->{ text } .= join('', @_); - return $self; -} - - -sub unshift { - my $self = shift; - $self->{ text } = join('', @_) . $self->{ text }; - return $self; -} - - -sub pop { - my $self = shift; - my $strip = shift || return $self; - $self->{ text } =~ s/$strip$//; - return $self; -} - - -sub shift { - my $self = shift; - my $strip = shift || return $self; - $self->{ text } =~ s/^$strip//; - return $self; -} - -#------------------------------------------------------------------------ - -sub center { - my ($self, $width) = @_; - my $text = $self->{ text }; - my $len = length $text; - $width ||= 0; - - if ($len < $width) { - my $lpad = int(($width - $len) / 2); - my $rpad = $width - $len - $lpad; - $self->{ text } = (' ' x $lpad) . $self->{ text } . (' ' x $rpad); - } - - return $self; -} - - -sub left { - my ($self, $width) = @_; - my $len = length $self->{ text }; - $width ||= 0; - - $self->{ text } .= (' ' x ($width - $len)) - if $width > $len; - - return $self; -} - - -sub right { - my ($self, $width) = @_; - my $len = length $self->{ text }; - $width ||= 0; - - $self->{ text } = (' ' x ($width - $len)) . $self->{ text } - if $width > $len; - - return $self; -} - - -sub format { - my ($self, $format) = @_; - $format = '%s' unless defined $format; - $self->{ text } = sprintf($format, $self->{ text }); - return $self; -} - - -sub filter { - my ($self, $name, @args) = @_; - - my $context = $self->{ _CONTEXT }; - - my $code = $context->filter($name, \@args) - || $self->throw($context->error()); - return &$code($self->{ text }); -} - - -#------------------------------------------------------------------------ - -sub upper { - my $self = CORE::shift; - $self->{ text } = uc $self->{ text }; - return $self; -} - - -sub lower { - my $self = CORE::shift; - $self->{ text } = lc $self->{ text }; - return $self; -} - - -sub capital { - my $self = CORE::shift; - $self->{ text } =~ s/^(.)/\U$1/; - return $self; -} - -#------------------------------------------------------------------------ - -sub chop { - my $self = CORE::shift; - chop $self->{ text }; - return $self; -} - - -sub chomp { - my $self = CORE::shift; - chomp $self->{ text }; - return $self; -} - - -sub trim { - my $self = CORE::shift; - for ($self->{ text }) { - s/^\s+//; - s/\s+$//; - } - return $self; -} - - -sub collapse { - my $self = CORE::shift; - for ($self->{ text }) { - s/^\s+//; - s/\s+$//; - s/\s+/ /g - } - return $self; - -} - -#------------------------------------------------------------------------ - -sub length { - my $self = CORE::shift; - return length $self->{ text }; -} - - -sub truncate { - my ($self, $length, $suffix) = @_; - return $self unless defined $length; - $suffix ||= ''; - return $self if CORE::length $self->{ text } <= $length; - $self->{ text } = substr($self->{ text }, 0, - $length - CORE::length($suffix)) . $suffix; - return $self; -} - - -sub repeat { - my ($self, $n) = @_; - return $self unless defined $n; - $self->{ text } = $self->{ text } x $n; - return $self; -} - - -sub replace { - my ($self, $search, $replace) = @_; - return $self unless defined $search; - $replace = '' unless defined $replace; - $self->{ text } =~ s/$search/$replace/g; - return $self; -} - - -sub remove { - my ($self, $search) = @_; - $search = '' unless defined $search; - $self->{ text } =~ s/$search//g; - return $self; -} - - -sub split { - my $self = CORE::shift; - my $split = CORE::shift; - my $limit = CORE::shift || 0; - $split = '\s+' unless defined $split; - return [ split($split, $self->{ text }, $limit) ]; -} - - -sub search { - my ($self, $pattern) = @_; - return $self->{ text } =~ /$pattern/; -} - - -sub equals { - my ($self, $comparison) = @_; - return $self->{ text } eq $comparison; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::String - Object oriented interface for string manipulation - -=head1 SYNOPSIS - - # create String objects via USE directive - [% USE String %] - [% USE String 'initial text' %] - [% USE String text => 'initial text' %] - - # or from an existing String via new() - [% newstring = String.new %] - [% newstring = String.new('newstring text') %] - [% newstring = String.new( text => 'newstring text' ) %] - - # or from an existing String via copy() - [% newstring = String.copy %] - - # append text to string - [% String.append('text to append') %] - - # format left, right or center/centre padded - [% String.left(20) %] - [% String.right(20) %] - [% String.center(20) %] # American spelling - [% String.centre(20) %] # European spelling - - # and various other methods... - -=head1 DESCRIPTION - -This module implements a String class for doing stringy things to -text in an object-oriented way. - -You can create a String object via the USE directive, adding any -initial text value as an argument or as the named parameter 'text'. - - [% USE String %] - [% USE String 'initial text' %] - [% USE String text='initial text' %] - -The object created will be referenced as 'String' by default, but you -can provide a different variable name for the object to be assigned -to: - - [% USE greeting = String 'Hello World' %] - -Once you've got a String object, you can use it as a prototype to -create other String objects with the new() method. - - [% USE String %] - [% greeting = String.new('Hello World') %] - -The new() method also accepts an initial text string as an argument -or the named parameter 'text'. - - [% greeting = String.new( text => 'Hello World' ) %] - -You can also call copy() to create a new String as a copy of the -original. - - [% greet2 = greeting.copy %] - -The String object has a text() method to return the content of the -string. - - [% greeting.text %] - -However, it is sufficient to simply print the string and let the -overloaded stringification operator call the text() method -automatically for you. - - [% greeting %] - -Thus, you can treat String objects pretty much like any regular piece -of text, interpolating it into other strings, for example: - - [% msg = "It printed '$greeting' and then dumped core\n" %] - -You also have the benefit of numerous other methods for manipulating -the string. - - [% msg.append("PS Don't eat the yellow snow") %] - -Note that all methods operate on and mutate the contents of the string -itself. If you want to operate on a copy of the string then simply -take a copy first: - - [% msg.copy.append("PS Don't eat the yellow snow") %] - -These methods return a reference to the String object itself. This -allows you to chain multiple methods together. - - [% msg.copy.append('foo').right(72) %] - -It also means that in the above examples, the String is returned which -causes the text() method to be called, which results in the new value of -the string being printed. To suppress printing of the string, you can -use the CALL directive. - - [% foo = String.new('foo') %] - - [% foo.append('bar') %] # prints "foobar" - - [% CALL foo.append('bar') %] # nothing - -=head1 METHODS - -=head2 Construction Methods - -The following methods are used to create new String objects. - -=over 4 - -=item new() - -Creates a new string using an initial value passed as a positional -argument or the named parameter 'text'. - - [% USE String %] - [% msg = String.new('Hello World') %] - [% msg = String.new( text => 'Hello World' ) %] - -=item copy() - -Creates a new String object which contains a copy of the original string. - - [% msg2 = msg.copy %] - -=back - -=head2 Inspection Methods - -These methods are used to inspect the string content or other parameters -relevant to the string. - -=over 4 - -=item text() - -Returns the internal text value of the string. The stringification -operator is overloaded to call this method. Thus the following are -equivalent: - - [% msg.text %] - [% msg %] - -=item length() - -Returns the length of the string. - - [% USE String("foo") %] - - [% String.length %] # => 3 - -=item search($pattern) - -Searches the string for the regular expression specified in $pattern -returning true if found or false otherwise. - - [% item = String.new('foo bar baz wiz waz woz') %] - - [% item.search('wiz') ? 'WIZZY! :-)' : 'not wizzy :-(' %] - -=item split($pattern, $limit) - -Splits the string based on the delimiter $pattern and optional $limit. -Delegates to Perl's internal split() so the parameters are exactly the same. - - [% FOREACH item.split %] - ... - [% END %] - - [% FOREACH item.split('baz|waz') %] - ... - [% END %] - -=back - -=head2 Mutation Methods - -These methods modify the internal value of the string. For example: - - [% USE str=String('foobar') %] - - [% str.append('.html') %] # str => 'foobar.html' - -The value of the String 'str' is now 'foobar.html'. If you don't want -to modify the string then simply take a copy first. - - [% str.copy.append('.html') %] - -These methods all return a reference to the String object itself. This -has two important benefits. The first is that when used as above, the -String object 'str' returned by the append() method will be stringified -with a call to its text() method. This will return the newly modified -string content. In other words, a directive like: - - [% str.append('.html') %] - -will update the string and also print the new value. If you just want -to update the string but not print the new value then use CALL. - - [% CALL str.append('.html') %] - -The other benefit of these methods returning a reference to the String -is that you can chain as many different method calls together as you -like. For example: - - [% String.append('.html').trim.format(href) %] - -Here are the methods: - -=over 4 - -=item push($suffix, ...) / append($suffix, ...) - -Appends all arguments to the end of the string. The -append() method is provided as an alias for push(). - - [% msg.push('foo', 'bar') %] - [% msg.append('foo', 'bar') %] - -=item pop($suffix) - -Removes the suffix passed as an argument from the end of the String. - - [% USE String 'foo bar' %] - [% String.pop(' bar') %] # => 'foo' - -=item unshift($prefix, ...) / prepend($prefix, ...) - -Prepends all arguments to the beginning of the string. The -prepend() method is provided as an alias for unshift(). - - [% msg.unshift('foo ', 'bar ') %] - [% msg.prepend('foo ', 'bar ') %] - -=item shift($prefix) - -Removes the prefix passed as an argument from the start of the String. - - [% USE String 'foo bar' %] - [% String.shift('foo ') %] # => 'bar' - -=item left($pad) - -If the length of the string is less than $pad then the string is left -formatted and padded with spaces to $pad length. - - [% msg.left(20) %] - -=item right($pad) - -As per left() but right padding the String to a length of $pad. - - [% msg.right(20) %] - -=item center($pad) / centre($pad) - -As per left() and right() but formatting the String to be centered within -a space padded string of length $pad. The centre() method is provided as -an alias for center() to keep Yanks and Limeys happy. - - [% msg.center(20) %] # American spelling - [% msg.centre(20) %] # European spelling - -=item format($format) - -Apply a format in the style of sprintf() to the string. - - [% USE String("world") %] - [% String.format("Hello %s\n") %] # => "Hello World\n" - -=item upper() - -Converts the string to upper case. - - [% USE String("foo") %] - - [% String.upper %] # => 'FOO' - -=item lower() - -Converts the string to lower case - - [% USE String("FOO") %] - - [% String.lower %] # => 'foo' - -=item capital() - -Converts the first character of the string to upper case. - - [% USE String("foo") %] - - [% String.capital %] # => 'Foo' - -The remainder of the string is left untouched. To force the string to -be all lower case with only the first letter capitalised, you can do -something like this: - - [% USE String("FOO") %] - - [% String.lower.capital %] # => 'Foo' - -=item chop() - -Removes the last character from the string. - - [% USE String("foop") %] - - [% String.chop %] # => 'foo' - -=item chomp() - -Removes the trailing newline from the string. - - [% USE String("foo\n") %] - - [% String.chomp %] # => 'foo' - -=item trim() - -Removes all leading and trailing whitespace from the string - - [% USE String(" foo \n\n ") %] - - [% String.trim %] # => 'foo' - -=item collapse() - -Removes all leading and trailing whitespace and collapses any sequences -of multiple whitespace to a single space. - - [% USE String(" \n\r \t foo \n \n bar \n") %] - - [% String.collapse %] # => "foo bar" - -=item truncate($length, $suffix) - -Truncates the string to $length characters. - - [% USE String('long string') %] - [% String.truncate(4) %] # => 'long' - -If $suffix is specified then it will be appended to the truncated -string. In this case, the string will be further shortened by the -length of the suffix to ensure that the newly constructed string -complete with suffix is exactly $length characters long. - - [% USE msg = String('Hello World') %] - [% msg.truncate(8, '...') %] # => 'Hello...' - -=item replace($search, $replace) - -Replaces all occurences of $search in the string with $replace. - - [% USE String('foo bar foo baz') %] - [% String.replace('foo', 'wiz') %] # => 'wiz bar wiz baz' - -=item remove($search) - -Remove all occurences of $search in the string. - - [% USE String('foo bar foo baz') %] - [% String.remove('foo ') %] # => 'bar baz' - -=item repeat($count) - -Repeats the string $count times. - - [% USE String('foo ') %] - [% String.repeat(3) %] # => 'foo foo foo ' - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.33, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Table.pm b/lib/Template/Plugin/Table.pm deleted file mode 100644 index c1fd79a..0000000 --- a/lib/Template/Plugin/Table.pm +++ /dev/null @@ -1,464 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Table -# -# DESCRIPTION -# -# Plugin to order a linear data set into a virtual 2-dimensional table -# from which row and column permutations can be fetched. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Table.pm,v 2.64 2004/01/13 16:20:38 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Table; - -require 5.004; - -use strict; -use vars qw( @ISA $VERSION $AUTOLOAD ); -use base qw( Template::Plugin ); -use Template::Plugin; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($context, \@data, \%args) -# -# This constructor method initialises the object to iterate through -# the data set passed by reference to a list as the first parameter. -# It calculates the shape of the permutation table based on the ROWS -# or COLS parameters specified in the $args hash reference. The -# OVERLAP parameter may be provided to specify the number of common -# items that should be shared between subseqent columns. -#------------------------------------------------------------------------ - -sub new { - my ($class, $context, $data, $params) = @_; - my ($size, $rows, $cols, $coloff, $overlap, $error); - - # if the data item is a reference to a Template::Iterator object, - # or subclass thereof, we call its get_all() method to extract all - # the data it contains - if (UNIVERSAL::isa($data, 'Template::Iterator')) { - ($data, $error) = $data->get_all(); - return $class->error("iterator failed to provide data for table: ", - $error) - if $error; - } - - return $class->error('invalid table data, expecting a list') - unless ref $data eq 'ARRAY'; - - $params ||= { }; - return $class->error('invalid table parameters, expecting a hash') - unless ref $params eq 'HASH'; - - # ensure keys are folded to upper case - @$params{ map { uc } keys %$params } = values %$params; - - $size = scalar @$data; - $overlap = $params->{ OVERLAP } || 0; - - # calculate number of columns based on a specified number of rows - if ($rows = $params->{ ROWS }) { - if ($size < $rows) { - $rows = $size; # pad? - $cols = 1; - $coloff = 0; - } - else { - $coloff = $rows - $overlap; - $cols = int ($size / $coloff) - + ($size % $coloff > $overlap ? 1 : 0) - } - } - # calculate number of rows based on a specified number of columns - elsif ($cols = $params->{ COLS }) { - if ($size < $cols) { - $cols = $size; - $rows = 1; - $coloff = 1; - } - else { - $coloff = int ($size / $cols) - + ($size % $cols > $overlap ? 1 : 0); - $rows = $coloff + $overlap; - } - } - else { - $rows = $size; - $cols = 1; - $coloff = 0; - } - - bless { - _DATA => $data, - _SIZE => $size, - _NROWS => $rows, - _NCOLS => $cols, - _COLOFF => $coloff, - _OVERLAP => $overlap, - _PAD => defined $params->{ PAD } ? $params->{ PAD } : 1, - }, $class; -} - - -#------------------------------------------------------------------------ -# row($n) -# -# Returns a reference to a list containing the items in the row whose -# number is specified by parameter. If the row number is undefined, -# it calls rows() to return a list of all rows. -#------------------------------------------------------------------------ - -sub row { - my ($self, $row) = @_; - my ($data, $cols, $offset, $size, $pad) - = @$self{ qw( _DATA _NCOLS _COLOFF _SIZE _PAD) }; - my @set; - - # return all rows if row number not specified - return $self->rows() - unless defined $row; - - return () if $row >= $self->{ _NROWS } || $row < 0; - - my $index = $row; - - for (my $c = 0; $c < $cols; $c++) { - push(@set, $index < $size - ? $data->[$index] - : ($pad ? undef : ())); - $index += $offset; - } - return \@set; -} - - -#------------------------------------------------------------------------ -# col($n) -# -# Returns a reference to a list containing the items in the column whose -# number is specified by parameter. If the column number is undefined, -# it calls cols() to return a list of all columns. -#------------------------------------------------------------------------ - -sub col { - my ($self, $col) = @_; - my ($data, $size) = @$self{ qw( _DATA _SIZE ) }; - my ($start, $end); - my $blanks = 0; - - # return all cols if row number not specified - return $self->cols() - unless defined $col; - - return () if $col >= $self->{ _NCOLS } || $col < 0; - - $start = $self->{ _COLOFF } * $col; - $end = $start + $self->{ _NROWS } - 1; - $end = $start if $end < $start; - if ($end >= $size) { - $blanks = ($end - $size) + 1; - $end = $size - 1; - } - return () if $start >= $size; - return [ @$data[$start..$end], - $self->{ _PAD } ? ((undef) x $blanks) : () ]; -} - - -#------------------------------------------------------------------------ -# rows() -# -# Returns all rows as a reference to a list of rows. -#------------------------------------------------------------------------ - -sub rows { - my $self = shift; - return [ map { $self->row($_) } (0..$self->{ _NROWS }-1) ]; -} - - -#------------------------------------------------------------------------ -# cols() -# -# Returns all rows as a reference to a list of rows. -#------------------------------------------------------------------------ - -sub cols { - my $self = shift; - return [ map { $self->col($_) } (0..$self->{ _NCOLS }-1) ]; -} - - -#------------------------------------------------------------------------ -# AUTOLOAD -# -# Provides read access to various internal data members. -#------------------------------------------------------------------------ - -sub AUTOLOAD { - my $self = shift; - my $item = $AUTOLOAD; - $item =~ s/.*:://; - return if $item eq 'DESTROY'; - - if ($item =~ /^data|size|nrows|ncols|overlap|pad$/) { - return $self->{ $item }; - } - else { - return (undef, "no such table method: $item"); - } -} - - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Table - Plugin to present data in a table - -=head1 SYNOPSIS - - [% USE table(list, rows=n, cols=n, overlap=n, pad=0) %] - - [% FOREACH item = table.row(n) %] - [% item %] - [% END %] - - [% FOREACH item = table.col(n) %] - [% item %] - [% END %] - - [% FOREACH row = table.rows %] - [% FOREACH item = row %] - [% item %] - [% END %] - [% END %] - - [% FOREACH col = table.cols %] - [% col.first %] - [% col.last %] ([% col.size %] entries) - [% END %] - -=head1 DESCRIPTION - -The Table plugin allows you to format a list of data items into a -virtual table. When you create a Table plugin via the USE directive, -simply pass a list reference as the first parameter and then specify -a fixed number of rows or columns. - - [% USE Table(list, rows=5) %] - [% USE table(list, cols=5) %] - -The 'Table' plugin name can also be specified in lower case as shown -in the second example above. You can also specify an alternative variable -name for the plugin as per regular Template Toolkit syntax. - - [% USE mydata = table(list, rows=5) %] - -The plugin then presents a table based view on the data set. The data -isn't actually reorganised in any way but is available via the row(), -col(), rows() and cols() as if formatted into a simple two dimensional -table of n rows x n columns. Thus, if our sample 'alphabet' list -contained the letters 'a' to 'z', the above USE directives would -create plugins that represented the following views of the alphabet. - - [% USE table(alphabet, ... %] - - rows=5 cols=5 - a f k p u z a g m s y - b g l q v b h n t z - c h m r w c i o u - d i n s x d j p v - e j o t y e k q w - f l r x - -We can request a particular row or column using the row() and col() -methods. - - [% USE table(alphabet, rows=5) %] - [% FOREACH item = table.row(0) %] - # [% item %] set to each of [ a f k p u z ] in turn - [% END %] - - [% FOREACH item = table.col(2) %] - # [% item %] set to each of [ m n o p q r ] in turn - [% END %] - -Data in rows is returned from left to right, columns from top to -bottom. The first row/column is 0. By default, rows or columns that -contain empty values will be padded with the undefined value to fill -it to the same size as all other rows or columns. For example, the -last row (row 4) in the first example would contain the values [ e j o -t y undef ]. The Template Toolkit will safely accept these undefined -values and print a empty string. You can also use the IF directive to -test if the value is set. - - [% FOREACH item = table.row(4) %] - [% IF item %] - Item: [% item %] - [% END %] - [% END %] - -You can explicitly disable the 'pad' option when creating the plugin to -returned shortened rows/columns where the data is empty. - - [% USE table(alphabet, cols=5, pad=0) %] - [% FOREACH item = table.col(4) %] - # [% item %] set to each of 'y z' - [% END %] - -The rows() method returns all rows/columns in the table as a reference -to a list of rows (themselves list references). The row() methods -when called without any arguments calls rows() to return all rows in -the table. - -Ditto for cols() and col(). - - [% USE table(alphabet, cols=5) %] - [% FOREACH row = table.rows %] - [% FOREACH item = row %] - [% item %] - [% END %] - [% END %] - -The Template Toolkit provides the first(), last() and size() methods -that can be called on list references to return the first/last entry -or the number of entried. The following example shows how we might -use this to provide an alphabetical index split into 3 even parts. - - [% USE table(alphabet, cols=3, pad=0) %] - [% FOREACH group = table.col %] - [ [% group.first %] - [% group.last %] ([% group.size %] letters) ] - [% END %] - -This produces the following output: - - [ a - i (9 letters) ] - [ j - r (9 letters) ] - [ s - z (8 letters) ] - -We can also use the general purpose join() list method which joins -the items of the list using the connecting string specified. - - [% USE table(alphabet, cols=5) %] - [% FOREACH row = table.rows %] - [% row.join(' - ') %] - [% END %] - -Data in the table is ordered downwards rather than across but can easily -be transformed on output. For example, to format our data in 5 columns -with data ordered across rather than down, we specify 'rows=5' to order -the data as such: - - a f . . - b g . - c h - d i - e j - -and then iterate down through each column (a-e, f-j, etc.) printing -the data across. - - a b c d e - f g h i j - . . - . - -Example code to do so would be much like the following: - - [% USE table(alphabet, rows=3) %] - [% FOREACH cols = table.cols %] - [% FOREACH item = cols %] - [% item %] - [% END %] - [% END %] - - a b c - d e f - g h i - j . . - . - -In addition to a list reference, the Table plugin constructor may be -passed a reference to a Template::Iterator object or subclass thereof. -The get_all() method is first called on the iterator to return all -remaining items. These are then available via the usual Table interface. - - [% USE DBI(dsn,user,pass) -%] - - # query() returns an iterator - [% results = DBI.query('SELECT * FROM alphabet ORDER BY letter') %] - - # pass into Table plugin - [% USE table(results, rows=8 overlap=1 pad=0) -%] - - [% FOREACH row = table.cols -%] - [% row.first.letter %] - [% row.last.letter %]: - [% row.join(', ') %] - [% END %] - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/URL.pm b/lib/Template/Plugin/URL.pm deleted file mode 100644 index c2246b7..0000000 --- a/lib/Template/Plugin/URL.pm +++ /dev/null @@ -1,236 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::URL -# -# DESCRIPTION -# -# Template Toolkit Plugin for constructing URL's from a base stem -# and adaptable parameters. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -#---------------------------------------------------------------------------- -# -# $Id: URL.pm,v 2.64 2004/01/13 16:20:39 abw Exp $ -# -#============================================================================ - -package Template::Plugin::URL; - -require 5.004; - -use strict; -use vars qw( @ISA $VERSION ); -use Template::Plugin; - -@ISA = qw( Template::Plugin ); -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($context, $baseurl, \%url_params) -# -# Constructor method which returns a sub-routine closure for constructing -# complex URL's from a base part and hash of additional parameters. -#------------------------------------------------------------------------ - -sub new { - my ($class, $context, $base, $args) = @_; - $args ||= { }; - - return sub { - my $newbase = shift unless ref $_[0] eq 'HASH'; - my $newargs = shift || { }; - my $combo = { %$args, %$newargs }; - my $urlargs = join('&', -# map { "$_=" . escape($combo->{ $_ }) } - map { args($_, $combo->{ $_ }) } - grep { defined $combo->{ $_ } } - sort keys %$combo); - - my $query = $newbase || $base || ''; - $query .= '?' if length $query && length $urlargs; - $query .= $urlargs if length $urlargs; - - return $query - } -} - - -sub args { - my ($key, $val) = @_; - $key = escape($key); - return map { - "$key=" . escape($_); - } ref $val eq 'ARRAY' ? @$val : $val; - -} - -#------------------------------------------------------------------------ -# escape($url) -# -# URL-encode data. Borrowed with minor modifications from CGI.pm. -# Kudos to Lincold Stein. -#------------------------------------------------------------------------ - -sub escape { - my $toencode = shift; - return undef unless defined($toencode); - $toencode=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; - return $toencode; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::URL - Plugin to construct complex URLs - -=head1 SYNOPSIS - - [% USE url('/cgi-bin/foo.pl') %] - - [% url(debug = 1, id = 123) %] - # ==> /cgi/bin/foo.pl?debug=1&id=123 - - - [% USE mycgi = url('/cgi-bin/bar.pl', mode='browse', debug=1) %] - - [% mycgi %] - # ==> /cgi/bin/bar.pl?mode=browse&debug=1 - - [% mycgi(mode='submit') %] - # ==> /cgi/bin/bar.pl?mode=submit&debug=1 - - [% mycgi(debug='d2 p0', id='D4-2k[4]') %] - # ==> /cgi-bin/bar.pl?mode=browse&debug=d2%20p0&id=D4-2k%5B4%5D - - -=head1 DESCRIPTION - -The URL plugin can be used to construct complex URLs from a base stem -and a hash array of additional query parameters. - -The constructor should be passed a base URL and optionally, a hash array -reference of default parameters and values. Used from with a Template -Documents, this would look something like the following: - - [% USE url('http://www.somewhere.com/cgi-bin/foo.pl') %] - [% USE url('/cgi-bin/bar.pl', mode='browse') %] - [% USE url('/cgi-bin/baz.pl', mode='browse', debug=1) %] - -When the plugin is then called without any arguments, the default base -and parameters are returned as a formatted query string. - - [% url %] - -For the above three examples, these will produce the following outputs: - - http://www.somewhere.com/cgi-bin/foo.pl - /cgi-bin/bar.pl?mode=browse - /cgi-bin/baz.pl?mode=browse&debug=1 - -Additional parameters may be also be specified: - - [% url(mode='submit', id='wiz') %] - -Which, for the same three examples, produces: - - http://www.somewhere.com/cgi-bin/foo.pl?mode=submit&id=wiz - /cgi-bin/bar.pl?mode=browse&id=wiz - /cgi-bin/baz.pl?mode=browse&debug=1&id=wiz - -A new base URL may also be specified as the first option: - - [% url('/cgi-bin/waz.pl', test=1) %] - -producing - - /cgi-bin/waz.pl?test=1 - /cgi-bin/waz.pl?mode=browse&test=1 - /cgi-bin/waz.pl?mode=browse&debug=1&test=1 - - -The ordering of the parameters is non-deterministic due to fact that -Perl's hashes themselves are unordered. This isn't a problem as the -ordering of CGI parameters is insignificant (to the best of my knowledge). -All values will be properly escaped thanks to some code borrowed from -Lincoln Stein's CGI.pm. e.g. - - [% USE url('/cgi-bin/woz.pl') %] - [% url(name="Elrich von Benjy d'Weiro") %] - -Here the spaces and "'" character are escaped in the output: - - /cgi-bin/woz.pl?name=Elrich%20von%20Benjy%20d%27Weiro - -Alternate name may be provided for the plugin at construction time -as per regular Template Toolkit syntax. - - [% USE mycgi = url('cgi-bin/min.pl') %] - - [% mycgi(debug=1) %] - -Note that in the following line, additional parameters are seperated -by '&', while common usage on the Web is to just use '&'. '&' -is actually the Right Way to do it. See this URL for more information: -http://ppewww.ph.gla.ac.uk/~flavell/www/formgetbyurl.html - - /cgi-bin/waz.pl?mode=browse&debug=1&test=1 - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/View.pm b/lib/Template/Plugin/View.pm deleted file mode 100644 index c22ba16..0000000 --- a/lib/Template/Plugin/View.pm +++ /dev/null @@ -1,127 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::View -# -# DESCRIPTION -# A user-definable view based on templates. Similar to the concept of -# a "Skin". -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -# REVISION -# $Id: View.pm,v 2.63 2004/01/13 16:20:39 abw Exp $ -# -#============================================================================ - -package Template::Plugin::View; - -require 5.004; - -use strict; -use Template::Plugin; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.63 $ =~ /(\d+)\.(\d+)/); - -use Template::View; - -#------------------------------------------------------------------------ -# new($context, \%config) -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $view = Template::View->new($context, @_) - || return $class->error($Template::View::ERROR); - $view->seal(); - return $view; -} - - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::View - Plugin to create views (Template::View) - -=head1 SYNOPSIS - - [% USE view( - prefix = 'splash/' # template prefix/suffix - suffix = '.tt2' - bgcol = '#ffffff' # and any other variables you - style = 'Fancy HTML' # care to define as view metadata, - items = [ foo, bar.baz ] # including complex data and - foo = bar ? baz : x.y.z # expressions - %] - - [% view.title %] # access view metadata - - [% view.header(title = 'Foo!') %] # view "methods" process blocks or - [% view.footer %] # templates with prefix/suffix added - -=head1 DESCRIPTION - -This plugin module creates Template::View objects. Views are an -experimental feature and are subject to change in the near future. -In the mean time, please consult L<Template::View> for further info. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.63, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Template::View|Template::View> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/Wrap.pm b/lib/Template/Plugin/Wrap.pm deleted file mode 100644 index 96c600a..0000000 --- a/lib/Template/Plugin/Wrap.pm +++ /dev/null @@ -1,162 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::Wrap -# -# DESCRIPTION -# Plugin for wrapping text via the Text::Wrap module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 1996-2000 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Wrap.pm,v 2.63 2004/01/13 16:20:40 abw Exp $ -# -#============================================================================ - -package Template::Plugin::Wrap; - -require 5.004; - -use strict; -use vars qw( @ISA $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; -use Text::Wrap; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.63 $ =~ /(\d+)\.(\d+)/); - -sub new { - my ($class, $context, $format) = @_;; - $context->define_filter('wrap', [ \&wrap_filter_factory => 1 ]); - return \&tt_wrap; -} - -sub tt_wrap { - my $text = shift; - my $width = shift || 72; - my $itab = shift; - my $ntab = shift; - $itab = '' unless defined $itab; - $ntab = '' unless defined $ntab; - $Text::Wrap::columns = $width; - Text::Wrap::wrap($itab, $ntab, $text); -} - -sub wrap_filter_factory { - my ($context, @args) = @_; - return sub { - my $text = shift; - tt_wrap($text, @args); - } -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::Wrap - Plugin interface to Text::Wrap - -=head1 SYNOPSIS - - [% USE wrap %] - - # call wrap subroutine - [% wrap(mytext, width, initial_tab, subsequent_tab) %] - - # or use wrap FILTER - [% mytext FILTER wrap(width, initital_tab, subsequent_tab) %] - -=head1 DESCRIPTION - -This plugin provides an interface to the Text::Wrap module which -provides simple paragraph formatting. - -It defines a 'wrap' subroutine which can be called, passing the input -text and further optional parameters to specify the page width (default: -72), and tab characters for the first and subsequent lines (no defaults). - - [% USE wrap %] - - [% text = BLOCK %] - First, attach the transmutex multiplier to the cross-wired - quantum homogeniser. - [% END %] - - [% wrap(text, 40, '* ', ' ') %] - -Output: - - * First, attach the transmutex - multiplier to the cross-wired quantum - homogeniser. - -It also registers a 'wrap' filter which accepts the same three optional -arguments but takes the input text directly via the filter input. - - [% FILTER bullet = wrap(40, '* ', ' ') -%] - First, attach the transmutex multiplier to the cross-wired quantum - homogeniser. - [%- END %] - - [% FILTER bullet -%] - Then remodulate the shield to match the harmonic frequency, taking - care to correct the phase difference. - [% END %] - -Output: - - * First, attach the transmutex - multiplier to the cross-wired quantum - homogeniser. - - * Then remodulate the shield to match - the harmonic frequency, taking - care to correct the phase difference. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@wardley.orgE<gt> - -The Text::Wrap module was written by David Muir Sharnoff -E<lt>muir@idiom.comE<gt> with help from Tim Pierce and many -others. - -=head1 VERSION - -2.63, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<Text::Wrap|Text::Wrap> - diff --git a/lib/Template/Plugin/XML/DOM.pm b/lib/Template/Plugin/XML/DOM.pm deleted file mode 100644 index 30bac3b..0000000 --- a/lib/Template/Plugin/XML/DOM.pm +++ /dev/null @@ -1,841 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::DOM -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the XML::DOM.pm module. -# -# AUTHORS -# Andy Wardley <abw@kfs.org> -# Simon Matthews <sam@knowledgepool.com> -# -# COPYRIGHT -# Copyright (C) 2000 Andy Wardley, Simon Matthews. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: DOM.pm,v 2.54 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::DOM; - -require 5.004; - -use strict; -use Template::Plugin; -use XML::DOM; - -use base qw( Template::Plugin ); -use vars qw( $VERSION $DEBUG ); - -$VERSION = 2.6; -$DEBUG = 0 unless defined $DEBUG; - - -#------------------------------------------------------------------------ -# new($context, \%config) -# -# Constructor method for XML::DOM plugin. Creates an XML::DOM::Parser -# object and initialise plugin configuration. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - - my $parser ||= XML::DOM::Parser->new(%$args) - || return $class->_throw("failed to create XML::DOM::Parser\n"); - - # we've had to deprecate the old usage because it broke things big time - # with DOM trees never getting cleaned up. - return $class->_throw("XML::DOM usage has changed - you must now call parse()\n") - if @_; - - bless { - _PARSER => $parser, - _DOCS => [ ], - _CONTEXT => $context, - _PREFIX => $args->{ prefix } || '', - _SUFFIX => $args->{ suffix } || '', - _DEFAULT => $args->{ default } || '', - _VERBOSE => $args->{ verbose } || 0, - _NOSPACE => $args->{ nospace } || 0, - _DEEP => $args->{ deep } || 0, - }, $class; -} - - -#------------------------------------------------------------------------ -# parse($content, \%named_params) -# -# Parses an XML stream, provided as the first positional argument (assumed -# to be a filename unless it contains a '<' character) or specified in -# the named parameter hash as one of 'text', 'xml' (same as text), 'file' -# or 'filename'. -#------------------------------------------------------------------------ - -sub parse { - my $self = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my $parser = $self->{ _PARSER }; - my ($content, $about, $method, $doc); - - # determine the input source from a positional parameter (may be a - # filename or XML text if it contains a '<' character) or by using - # named parameters which may specify one of 'file', 'filename', 'text' - # or 'xml' - - if ($content = shift) { - if ($content =~ /\</) { - $about = 'xml text'; - $method = 'parse'; - } - else { - $about = "xml file $content"; - $method = 'parsefile'; - } - } - elsif ($content = $args->{ text } || $args->{ xml }) { - $about = 'xml text'; - $method = 'parse'; - } - elsif ($content = $args->{ file } || $args->{ filename }) { - $about = "xml file $content"; - $method = 'parsefile'; - } - else { - return $self->_throw('no filename or xml text specified'); - } - - # parse the input source using the appropriate method determined above - eval { $doc = $parser->$method($content) } and not $@ - or return $self->_throw("failed to parse $about: $@"); - - # update XML::DOM::Document _UserData to contain config details - $doc->[ XML::DOM::Node::_UserData ] = { - map { ( $_ => $self->{ $_ } ) } - qw( _CONTEXT _PREFIX _SUFFIX _VERBOSE _NOSPACE _DEEP _DEFAULT ), - }; - - # keep track of all DOM docs for subsequent dispose() -# print STDERR "DEBUG: $self adding doc: $doc\n" -# if $DEBUG; - - push(@{ $self->{ _DOCS } }, $doc); - - return $doc; -} - - -#------------------------------------------------------------------------ -# _throw($errmsg) -# -# Raised a Template::Exception of type XML.DOM via die(). -#------------------------------------------------------------------------ - -sub _throw { - my ($self, $error) = @_; - die (Template::Exception->new('XML.DOM', $error)); -} - - -#------------------------------------------------------------------------ -# DESTROY -# -# Cleanup method which calls dispose() on any and all DOM documents -# created by this object. Also breaks any circular references that -# may exist with the context object. -#------------------------------------------------------------------------ - -sub DESTROY { - my $self = shift; - - # call dispose() on each document produced by this parser - foreach my $doc (@{ $self->{ _DOCS } }) { -# print STDERR "DEBUG: $self destroying $doc\n" -# if $DEBUG; - if (ref $doc) { -# print STDERR "disposing of $doc\n"; - undef $doc->[ XML::DOM::Node::_UserData ]->{ _CONTEXT }; - $doc->dispose(); - } - } - delete $self->{ _CONTEXT }; - delete $self->{ _PARSER }; -} - - - -#======================================================================== -package XML::DOM::Node; -#======================================================================== - - -#------------------------------------------------------------------------ -# present($view) -# -# Method to present node via a view (supercedes all that messy toTemplate -# stuff below). -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - - if ($self->getNodeType() == XML::DOM::ELEMENT_NODE) { - # it's an element - $view->view($self->getTagName(), $self); - } - else { - my $text = $self->toString(); - $view->view('text', $text); - } -} - -sub content { - my ($self, $view) = @_; - my $output = ''; - foreach my $node (@{ $self->getChildNodes }) { - $output .= $node->present($view); - -# abw test passing args, Aug 2001 -# $output .= $view->print($node); - } - return $output; -} - - -#------------------------------------------------------------------------ -# toTemplate($prefix, $suffix, \%named_params) -# -# Process the current node as a template. -#------------------------------------------------------------------------ - -sub toTemplate { - my $self = shift; - _template_node($self, $self->_args(@_)); -} - - -#------------------------------------------------------------------------ -# childrenToTemplate($prefix, $suffix, \%named_params) -# -# Process all the current node's children as templates. -#------------------------------------------------------------------------ - -sub childrenToTemplate { - my $self = shift; - _template_kids($self, $self->_args(@_)); -} - - -#------------------------------------------------------------------------ -# allChildrenToTemplate($prefix, $suffix, \%named_params) -# -# Process all the current node's children, and their children, and -# their children, etc., etc., as templates. Same effect as calling the -# childrenToTemplate() method with the 'deep' option set. -#------------------------------------------------------------------------ - -sub allChildrenToTemplate { - my $self = shift; - my $args = $self->_args(@_); - $args->{ deep } = 1; - _template_kids($self, $args); -} - - -#------------------------------------------------------------------------ -# _args($prefix, $suffix, \%name_params) -# -# Reads the optional positional parameters, $prefix and $suffix, and -# also examines any named parameters hash to construct a set of -# current configuration parameters. Where not specified directly, the -# object defaults are used. -#------------------------------------------------------------------------ - -sub _args { - my $self = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my $doc = $self->getOwnerDocument() || $self; - my $data = $doc->[ XML::DOM::Node::_UserData ]; - - return { - prefix => @_ ? shift : $args->{ prefix } || $data->{ _PREFIX }, - suffix => @_ ? shift : $args->{ suffix } || $data->{ _SUFFIX }, - verbose => $args->{ verbose } || $data->{ _VERBOSE }, - nospace => $args->{ nospace } || $data->{ _NOSPACE }, - deep => $args->{ deep } || $data->{ _DEEP }, - default => $args->{ default } || $data->{ _DEFAULT }, - context => $data->{ _CONTEXT }, - }; -} - - - -#------------------------------------------------------------------------ -# _template_node($node, $args, $vars) -# -# Process a template for the current DOM node where the template name -# is taken from the node TagName, with any specified 'prefix' and/or -# 'suffix' applied. The 'default' argument can also be provided to -# specify a default template to be used when a specific template can't -# be found. The $args parameter referenced a hash array through which -# these configuration items are passed (see _args()). The current DOM -# node is made available to the template as the variable 'node', along -# with any other variables passed in the optional $vars hash reference. -# To permit the 'children' and 'prune' callbacks to be raised as node -# methods (see _template_kids() below), these items, if defined in the -# $vars hash, are copied into the node object where its AUTOLOAD method -# can find them. -#------------------------------------------------------------------------ - -sub _template_node { - my $node = shift || die "no XML::DOM::Node reference\n"; - my $args = shift || die "no XML::DOM args passed to _template_node\n"; - my $vars = shift || { }; - my $context = $args->{ context } || die "no context in XML::DOM args\n"; - my $template; - my $output = ''; - - # if this is not an element then it is text so output it - unless ($node->getNodeType() == XML::DOM::ELEMENT_NODE ) { - if ($args->{ verbose }) { - $output = $node->toString(); - $output =~ s/\s+$// if $args->{ nospace }; - } - } - else { - my $element = ( $args->{ prefix } || '' ) - . $node->getTagName() - . ( $args->{ suffix } || '' ); - - # locate a template by name built from prefix, tagname and suffix - # or fall back on any default template specified - eval { $template = $context->template($element) }; - eval { $template = $context->template($args->{ default }) } - if $@ && $args->{ default }; - $template = $element unless $template; - - # copy 'children' and 'prune' callbacks into node object (see AUTOLOAD) - my $doc = $node->getOwnerDocument() || $node; - my $data = $doc->[ XML::DOM::Node::_UserData ]; - - $data->{ _TT_CHILDREN } = $vars->{ children }; - $data->{ _TT_PRUNE } = $vars->{ prune }; - - # add node reference to existing vars hash - $vars->{ node } = $node; - - $output = $context->include($template, $vars); - - # break any circular references - delete $vars->{ node }; - delete $data->{ _TT_CHILDREN }; - delete $data->{ _TT_PRUNE }; - } - - return $output; -} - - -#------------------------------------------------------------------------ -# _template_kids($node, $args) -# -# Process all the children of the current node as templates, via calls -# to _template_node(). If the 'deep' argument is set, then the process -# will continue recursively. In this case, the node template is first -# processed, followed by any children of that node (i.e. depth first, -# parent before). A closure called 'children' is created and added -# to the Stash variables passed to _template_node(). This can be called -# from the parent template to process all child nodes at the current point. -# This then "prunes" the tree preventing the children from being processed -# after the parent template. A 'prune' callback is also added to prune -# the tree without processing the children. Note that _template_node() -# copies these callbacks into each parent node, allowing them to be called -# as [% node. -#------------------------------------------------------------------------ - -sub _template_kids { - my $node = shift || die "no XML::DOM::Node reference\n"; - my $args = shift || die "no XML::DOM args passed to _template_kids\n"; - my $context = $args->{ context } || die "no context in XML::DOM args\n"; - my $output = ''; - - foreach my $kid ( $node->getChildNodes() ) { - # define some callbacks to allow template to call [% content %] - # or [% prune %]. They are also inserted into each node reference - # so they can be called as [% node.content %] and [% node.prune %] - my $prune = 0; - my $vars = { }; - $vars->{ children } = sub { - $prune = 1; - _template_kids($kid, $args); - }; - $vars->{ prune } = sub { - $prune = 1; - return ''; - }; - - $output .= _template_node($kid, $args, $vars); - $output .= _template_kids($kid, $args) - if $args->{ deep } && ! $prune; - } - return $output; -} - - -#======================================================================== -package XML::DOM::Element; -#======================================================================== - -use vars qw( $AUTOLOAD ); - -sub AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - my $attrib; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; - - my $doc = $self->getOwnerDocument() || $self; - my $data = $doc->[ XML::DOM::Node::_UserData ]; - - # call 'content' or 'prune' callbacks, if defined (see _template_node()) - return &$attrib() - if ($method =~ /^children|prune$/) - && defined($attrib = $data->{ "_TT_\U$method" }) - && ref $attrib eq 'CODE'; - - return $attrib - if defined ($attrib = $self->getAttribute($method)); - - return ''; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::DOM - Plugin interface to XML::DOM - -=head1 SYNOPSIS - - # load plugin - [% USE dom = XML.DOM %] - - # also provide XML::Parser options - [% USE dom = XML.DOM(ProtocolEncoding =E<gt> 'ISO-8859-1') %] - - # parse an XML file - [% doc = dom.parse(filename) %] - [% doc = dom.parse(file => filename) %] - - # parse XML text - [% doc = dom.parse(xmltext) %] - [% doc = dom.parse(text => xmltext) %] - - # call any XML::DOM methods on document/element nodes - [% FOREACH node = doc.getElementsByTagName('report') %] - * [% node.getAttribute('title') %] # or just '[% node.title %]' - [% END %] - - # define VIEW to present node(s) - [% VIEW report notfound='xmlstring' %] - # handler block for a <report>...</report> element - [% BLOCK report %] - [% item.content(view) %] - [% END %] - - # handler block for a <section title="...">...</section> element - [% BLOCK section %] - <h1>[% item.title %]</h1> - [% item.content(view) %] - [% END %] - - # default template block converts item to string representation - [% BLOCK xmlstring; item.toString; END %] - - # block to generate simple text - [% BLOCK text; item; END %] - [% END %] - - # now present node (and children) via view - [% report.print(node) %] - - # or print node content via view - [% node.content(report) %] - - # following methods are soon to be deprecated in favour of views - [% node.toTemplate %] - [% node.childrenToTemplate %] - [% node.allChildrenToTemplate %] - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser (2.19 or later) and XML::DOM -(1.27 or later) modules be installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -Note that the XML::DOM module is now distributed as part of the -'libxml-enno' bundle. - -=head1 DESCRIPTION - -This is a Template Toolkit plugin interfacing to the XML::DOM module. -The plugin loads the XML::DOM module and creates an XML::DOM::Parser -object which is stored internally. The parse() method can then be -called on the plugin to parse an XML stream into a DOM document. - - [% USE dom = XML.DOM %] - [% doc = dom.parse('/tmp/myxmlfile') %] - -NOTE: earlier versions of this XML::DOM plugin expected a filename to -be passed as an argument to the constructor. This is no longer -supported due to the fact that it caused a serious memory leak. We -apologise for the inconvenience but must insist that you change your -templates as shown: - - # OLD STYLE: now fails with a warning - [% USE dom = XML.DOM('tmp/myxmlfile') %] - - # NEW STYLE: do this instead - [% USE dom = XML.DOM %] - [% doc = dom.parse('tmp/myxmlfile') %] - -The root of the problem lies in XML::DOM creating massive circular -references in the object models it constructs. The dispose() method -must be called on each document to release the memory that it would -otherwise hold indefinately. The XML::DOM plugin object (i.e. 'dom' -in these examples) acts as a sentinel for the documents it creates -('doc' and any others). When the plugin object goes out of scope at -the end of the current template, it will automatically call dispose() -on any documents that it has created. Note that if you dispose of the -the plugin object before the end of the block (i.e. by assigning a -new value to the 'dom' variable) then the documents will also be -disposed at that point and should not be used thereafter. - - [% USE dom = XML.DOM %] - [% doc = dom.parse('/tmp/myfile') %] - [% dom = 'new value' %] # releases XML.DOM plugin and calls - # dispose() on 'doc', so don't use it! - -Any template processing parameters (see toTemplate() method and -friends, below) can be specified with the constructor and will be used -to define defaults for the object. - - [% USE dom = XML.DOM(prefix => 'theme1/') %] - -The plugin constructor will also accept configuration options destined -for the XML::Parser object: - - [% USE dom = XML.DOM(ProtocolEncoding => 'ISO-8859-1') %] - -=head1 METHODS - -=head2 parse() - -The parse() method accepts a positional parameter which contains a filename -or XML string. It is assumed to be a filename unless it contains a E<lt> -character. - - [% xmlfile = '/tmp/foo.xml' %] - [% doc = dom.parse(xmlfile) %] - - [% xmltext = BLOCK %] - <xml> - <blah><etc/></blah> - ... - </xml> - [% END %] - [% doc = dom.parse(xmltext) %] - -The named parameters 'file' (or 'filename') and 'text' (or 'xml') can also -be used: - - [% doc = dom.parse(file = xmlfile) %] - [% doc = dom.parse(text = xmltext) %] - -The parse() method returns an instance of the XML::DOM::Document object -representing the parsed document in DOM form. You can then call any -XML::DOM methods on the document node and other nodes that its methods -may return. See L<XML::DOM> for full details. - - [% FOREACH node = doc.getElementsByTagName('CODEBASE') %] - * [% node.getAttribute('href') %] - [% END %] - -This plugin also provides an AUTOLOAD method for XML::DOM::Node which -calls getAttribute() for any undefined methods. Thus, you can use the -short form of - - [% node.attrib %] - -in place of - - [% node.getAttribute('attrib') %] - -=head2 toTemplate() - -B<NOTE: This method will soon be deprecated in favour of the VIEW based -approach desribed below.> - -This method will process a template for the current node on which it is -called. The template name is constructed from the node TagName with any -optional 'prefix' and/or 'suffix' options applied. A 'default' template -can be named to be used when the specific template cannot be found. The -node object is available to the template as the 'node' variable. - -Thus, for this XML fragment: - - <page title="Hello World!"> - ... - </page> - -and this template definition: - - [% BLOCK page %] - Page: [% node.title %] - [% END %] - -the output of calling toTemplate() on the E<lt>pageE<gt> node would be: - - Page: Hello World! - -=head2 childrenToTemplate() - -B<NOTE: This method will soon be deprecated in favour of the VIEW based -approach desribed below.> - -Effectively calls toTemplate() for the current node and then for each of -the node's children. By default, the parent template is processed first, -followed by each of the children. The 'children' closure can be called -from within the parent template to have them processed and output -at that point. This then suppresses the children from being processed -after the parent template. - -Thus, for this XML fragment: - - <foo> - <bar id="1"/> - <bar id="2"/> - </foo> - -and these template definitions: - - [% BLOCK foo %] - start of foo - end of foo - [% END %] - - [% BLOCK bar %] - bar [% node.id %] - [% END %] - -the output of calling childrenToTemplate() on the parent E<lt>fooE<gt> node -would be: - - start of foo - end of foo - bar 1 - bar 2 - -Adding a call to [% children %] in the 'foo' template: - - [% BLOCK foo %] - start of foo - [% children %] - end of foo - [% END %] - -then creates output as: - - start of foo - bar 1 - bar 2 - end of foo - -The 'children' closure can also be called as a method of the node, if you -prefer: - - [% BLOCK foo %] - start of foo - [% node.children %] - end of foo - [% END %] - -The 'prune' closure is also defined and can be called as [% prune %] or -[% node.prune %]. It prunes the currrent node, preventing any descendants -from being further processed. - - [% BLOCK anynode %] - [% node.toString; node.prune %] - [% END %] - -=head2 allChildrenToTemplate() - -B<NOTE: This method will soon be deprecated in favour of the VIEW based -approach desribed below.> - -Similar to childrenToTemplate() but processing all descendants (i.e. children -of children and so on) recursively. This is identical to calling the -childrenToTemplate() method with the 'deep' flag set to any true value. - -=head1 PRESENTING DOM NODES USING VIEWS - -You can define a VIEW to present all or part of a DOM tree by automatically -mapping elements onto templates. Consider a source document like the -following: - - <report> - <section title="Introduction"> - <p> - Blah blah. - <ul> - <li>Item 1</li> - <li>item 2</li> - </ul> - </p> - </section> - <section title="The Gory Details"> - ... - </section> - </report> - -We can load it up via the XML::DOM plugin and fetch the node for the -E<lt>reportE<gt> element. - - [% USE dom = XML.DOM; - doc = dom.parse(file => filename); - report = doc.getElementsByTagName('report') - %] - -We can then define a VIEW as follows to present this document fragment in -a particular way. The L<Template::Manual::Views> documentation -contains further details on the VIEW directive and various configuration -options it supports. - - [% VIEW report_view notfound='xmlstring' %] - # handler block for a <report>...</report> element - [% BLOCK report %] - [% item.content(view) %] - [% END %] - - # handler block for a <section title="...">...</section> element - [% BLOCK section %] - <h1>[% item.title %]</h1> - [% item.content(view) %] - [% END %] - - # default template block converts item to string representation - [% BLOCK xmlstring; item.toString; END %] - - # block to generate simple text - [% BLOCK text; item; END %] - [% END %] - -Each BLOCK defined within the VIEW represents a presentation style for -a particular element or elements. The current node is available via the -'item' variable. Elements that contain other content can generate it -according to the current view by calling [% item.content(view) %]. -Elements that don't have a specific template defined are mapped to the -'xmlstring' template via the 'notfound' parameter specified in the VIEW -header. This replicates the node as an XML string, effectively allowing -general XML/XHTML markup to be passed through unmodified. - -To present the report node via the view, we simply call: - - [% report_view.print(report) %] - -The output from the above example would look something like this: - - <h1>Introduction</h1> - <p> - Blah blah. - <ul> - <li>Item 1</li> - <li>item 2</li> - </ul> - </p> - - <h1>The Gory Details</h1> - ... - -To print just the content of the report node (i.e. don't process the -'report' template for the report node), you can call: - - [% report.content(report_view) %] - -=head1 AUTHORS - -This plugin module was written by Andy Wardley E<lt>abw@wardley.orgE<gt> -and Simon Matthews E<lt>sam@knowledgepool.comE<gt>. - -The XML::DOM module is by Enno Derksen E<lt>enno@att.comE<gt> and Clark -Cooper E<lt>coopercl@sch.ge.comE<gt>. It extends the the XML::Parser -module, also by Clark Cooper which itself is built on James Clark's expat -library. - -=head1 VERSION - -2.6, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 HISTORY - -Version 2.5 : updated for use with version 1.27 of the XML::DOM module. - -=over 4 - -=item * - -XML::DOM 1.27 now uses array references as the underlying data type -for DOM nodes instead of hash array references. User data is now -bound to the _UserData node entry instead of being forced directly -into the node hash. - -=back - -=head1 BUGS - -The childrenToTemplate() and allChildrenToTemplate() methods can easily -slip into deep recursion. - -The 'verbose' and 'nospace' options are not documented. They may -change in the near future. - -=head1 COPYRIGHT - -Copyright (C) 2000-2001 Andy Wardley, Simon Matthews. All Rights Reserved. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::DOM|XML::DOM>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugin/XML/RSS.pm b/lib/Template/Plugin/XML/RSS.pm deleted file mode 100644 index 32da7d8..0000000 --- a/lib/Template/Plugin/XML/RSS.pm +++ /dev/null @@ -1,194 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::RSS -# -# DESCRIPTION -# -# Template Toolkit plugin which interfaces to Jonathan Eisenzopf's XML::RSS -# module. RSS is the Rich Site Summary format. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -#---------------------------------------------------------------------------- -# -# $Id: RSS.pm,v 2.64 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::RSS; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; -use XML::RSS; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - -sub load { - return $_[0]; -} - -sub new { - my ($class, $context, $filename) = @_; - - return $class->fail('No filename specified') - unless $filename; - - my $rss = XML::RSS->new - or return $class->fail('failed to create XML::RSS'); - - # Attempt to determine if $filename is an XML string or - # a filename. Based on code from the XML.XPath plugin. - eval { - if ($filename =~ /\</) { - $rss->parse($filename); - } - else { - $rss->parsefile($filename) - } - } and not $@ - or return $class->fail("failed to parse $filename: $@"); - - return $rss; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::RSS - Plugin interface to XML::RSS - -=head1 SYNOPSIS - - [% USE news = XML.RSS($filename) %] - - [% FOREACH item = news.items %] - [% item.title %] - [% item.link %] - [% END %] - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser and XML::RSS modules be -installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -=head1 DESCRIPTION - -This Template Toolkit plugin provides a simple interface to the -XML::RSS module. - - [% USE news = XML.RSS('mysite.rdf') %] - -It creates an XML::RSS object, which is then used to parse the RSS -file specified as a parameter in the USE directive. A reference to -the XML::RSS object is then returned. - -An RSS (Rich Site Summary) file is typically used to store short news -'headlines' describing different links within a site. This example is -extracted from http://slashdot.org/slashdot.rdf. - - <?xml version="1.0"?><rdf:RDF - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns="http://my.netscape.com/rdf/simple/0.9/"> - - <channel> - <title>Slashdot:News for Nerds. Stuff that Matters.</title> - <link>http://slashdot.org</link> - <description>News for Nerds. Stuff that Matters</description> - </channel> - - <image> - <title>Slashdot</title> - <url>http://slashdot.org/images/slashdotlg.gif</url> - <link>http://slashdot.org</link> - </image> - - <item> - <title>DVD CCA Battle Continues Next Week</title> - <link>http://slashdot.org/article.pl?sid=00/01/12/2051208</link> - </item> - - <item> - <title>Matrox to fund DRI Development</title> - <link>http://slashdot.org/article.pl?sid=00/01/13/0718219</link> - </item> - - <item> - <title>Mike Shaver Leaving Netscape</title> - <link>http://slashdot.org/article.pl?sid=00/01/13/0711258</link> - </item> - - </rdf:RDF> - -The attributes of the channel and image elements can be retrieved directly -from the plugin object using the familiar dotted compound notation: - - [% news.channel.title %] - [% news.channel.link %] - [% news.channel.etc... %] - - [% news.image.title %] - [% news.image.url %] - [% news.image.link %] - [% news.image.etc... %] - -The list of news items can be retrieved using the 'items' method: - - [% FOREACH item = news.items %] - [% item.title %] - [% item.link %] - [% END %] - -=head1 AUTHORS - -This plugin was written by Andy Wardley E<lt>abw@wardley.orgE<gt>, -inspired by an article in Web Techniques by Randal Schwartz -E<lt>merlyn@stonehenge.comE<gt>. - -The XML::RSS module, which implements all of the functionality that -this plugin delegates to, was written by Jonathan Eisenzopf -E<lt>eisen@pobox.comE<gt>. - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::RSS|XML::RSS>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugin/XML/Simple.pm b/lib/Template/Plugin/XML/Simple.pm deleted file mode 100644 index aaa4479..0000000 --- a/lib/Template/Plugin/XML/Simple.pm +++ /dev/null @@ -1,124 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::Simple -# -# DESCRIPTION -# Template Toolkit plugin interfacing to the XML::Simple.pm module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2001 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Simple.pm,v 2.63 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::Simple; - -require 5.004; - -use strict; -use Template::Plugin; -use XML::Simple; - -use base qw( Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.63 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($context, $file_or_text, \%config) -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $input = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - - XMLin($input, %$args); -} - - - -#------------------------------------------------------------------------ -# _throw($errmsg) -# -# Raise a Template::Exception of type XML.Simple via die(). -#------------------------------------------------------------------------ - -sub _throw { - my ($self, $error) = @_; - die (Template::Exception->new('XML.Simple', $error)); -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::Simple - Plugin interface to XML::Simple - -=head1 SYNOPSIS - - # load plugin and specify XML file to parse - [% USE xml = XML.Simple(xml_file_or_text) %] - -=head1 DESCRIPTION - -This is a Template Toolkit plugin interfacing to the XML::Simple module. - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser and XML::Simple modules be -installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -=head1 AUTHORS - -This plugin wrapper module was written by Andy Wardley -E<lt>abw@wardley.orgE<gt>. - -The XML::Simple module which implements all the core functionality -was written by Grant McLean E<lt>grantm@web.co.nzE<gt>. - -=head1 VERSION - -2.63, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::Simple|XML::Simple>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugin/XML/Style.pm b/lib/Template/Plugin/XML/Style.pm deleted file mode 100644 index 7613f2f..0000000 --- a/lib/Template/Plugin/XML/Style.pm +++ /dev/null @@ -1,357 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::Style -# -# DESCRIPTION -# Template Toolkit plugin which performs some basic munging of XML -# to perform simple stylesheet like transformations. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2001 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. -# -# REVISION -# $Id: Style.pm,v 2.34 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::Style; - -require 5.004; - -use strict; -use Template::Plugin::Filter; - -use base qw( Template::Plugin::Filter ); -use vars qw( $VERSION $DYNAMIC $FILTER_NAME ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.34 $ =~ /(\d+)\.(\d+)/); -$DYNAMIC = 1; -$FILTER_NAME = 'xmlstyle'; - - -#------------------------------------------------------------------------ -# new($context, \%config) -#------------------------------------------------------------------------ - -sub init { - my $self = shift; - my $name = $self->{ _ARGS }->[0] || $FILTER_NAME; - $self->install_filter($name); - return $self; -} - - -sub filter { - my ($self, $text, $args, $config) = @_; - - # munge start tags - $text =~ s/ < ([\w\.\:]+) ( \s+ [^>]+ )? > - / $self->start_tag($1, $2, $config) - /gsex; - - # munge end tags - $text =~ s/ < \/ ([\w\.\:]+) > - / $self->end_tag($1, $config) - /gsex; - - return $text; - -} - - -sub start_tag { - my ($self, $elem, $textattr, $config) = @_; - $textattr ||= ''; - my ($pre, $post); - - # look for an element match in the stylesheet - my $match = $config->{ $elem } - || $self->{ _CONFIG }->{ $elem } - || return "<$elem$textattr>"; - - # merge element attributes into copy of stylesheet attributes - my $attr = { %{ $match->{ attributes } || { } } }; - while ($textattr =~ / \s* ([\w\.\:]+) = " ([^"]+) " /gsx ) { - $attr->{ $1 } = $2; - } - $textattr = join(' ', map { "$_=\"$attr->{$_}\"" } keys %$attr); - $textattr = " $textattr" if $textattr; - - $elem = $match->{ element } || $elem; - $pre = $match->{ pre_start } || ''; - $post = $match->{ post_start } || ''; - - return "$pre<$elem$textattr>$post"; -} - - -sub end_tag { - my ($self, $elem, $config) = @_; - my ($pre, $post); - - # look for an element match in the stylesheet - my $match = $config->{ $elem } - || $self->{ _CONFIG }->{ $elem } - || return "</$elem>"; - - $elem = $match->{ element } || $elem; - $pre = $match->{ pre_end } || ''; - $post = $match->{ post_end } || ''; - - return "$pre</$elem>$post"; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::Style - Simple XML stylesheet transfomations - -=head1 SYNOPSIS - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - cellspacing = 1 - } - } - %] - - [% FILTER xmlstyle %] - <table> - <tr> - <td>Foo</td> <td>Bar</td> <td>Baz</td> - </tr> - </table> - [% END %] - -=head1 DESCRIPTION - -This plugin defines a filter for performing simple stylesheet based -transformations of XML text. - -Named parameters are used to define those XML elements which require -transformation. These may be specified with the USE directive when -the plugin is loaded and/or with the FILTER directive when the plugin -is used. - -This example shows how the default attributes C<border="0"> and -C<cellpadding="4"> can be added to E<lt>tableE<gt> elements. - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - } - } - %] - - [% FILTER xmlstyle %] - <table> - ... - </table> - [% END %] - -This produces the output: - - <table border="0" cellpadding="4"> - ... - </table> - -Parameters specified within the USE directive are applied automatically each -time the C<xmlstyle> FILTER is used. Additional parameters passed to the -FILTER directive apply for only that block. - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - } - } - %] - - [% FILTER xmlstyle - tr = { - attributes = { - valign="top" - } - } - %] - <table> - <tr> - ... - </tr> - </table> - [% END %] - -Of course, you may prefer to define your stylesheet structures once and -simply reference them by name. Passing a hash reference of named parameters -is just the same as specifying the named parameters as far as the Template -Toolkit is concerned. - - [% style_one = { - table = { ... } - tr = { ... } - } - style_two = { - table = { ... } - td = { ... } - } - style_three = { - th = { ... } - tv = { ... } - } - %] - - [% USE xmlstyle style_one %] - - [% FILTER xmlstyle style_two %] - # style_one and style_two applied here - [% END %] - - [% FILTER xmlstyle style_three %] - # style_one and style_three applied here - [% END %] - -Any attributes defined within the source tags will override those specified -in the style sheet. - - [% USE xmlstyle - div = { attributes = { align = 'left' } } - %] - - - [% FILTER xmlstyle %] - <div>foo</div> - <div align="right">bar</div> - [% END %] - -The output produced is: - - <div align="left">foo</div> - <div align="right">bar</div> - -The filter can also be used to change the element from one type to another. - - [% FILTER xmlstyle - th = { - element = 'td' - attributes = { bgcolor='red' } - } - %] - <tr> - <th>Heading</th> - </tr> - <tr> - <td>Value</td> - </tr> - [% END %] - -The output here is as follows. Notice how the end tag C<E<lt>/thE<gt>> is -changed to C<E<lt>/tdE<gt>> as well as the start tag. - - <tr> - <td bgcolor="red">Heading</td> - </tr> - <tr> - <td>Value</td> - </tr> - -You can also define text to be added immediately before or after the -start or end tags. For example: - - [% FILTER xmlstyle - table = { - pre_start = '<div align="center">' - post_end = '</div>' - } - th = { - element = 'td' - attributes = { bgcolor='red' } - post_start = '<b>' - pre_end = '</b>' - } - %] - <table> - <tr> - <th>Heading</th> - </tr> - <tr> - <td>Value</td> - </tr> - </table> - [% END %] - -The output produced is: - - <div align="center"> - <table> - <tr> - <td bgcolor="red"><b>Heading</b></td> - </tr> - <tr> - <td>Value</td> - </tr> - </table> - </div> - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.34, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/XML/XPath.pm b/lib/Template/Plugin/XML/XPath.pm deleted file mode 100644 index adf9292..0000000 --- a/lib/Template/Plugin/XML/XPath.pm +++ /dev/null @@ -1,284 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::XPath -# -# DESCRIPTION -# -# Template Toolkit plugin interfacing to the XML::XPath.pm module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -#---------------------------------------------------------------------------- -# -# $Id: XPath.pm,v 2.69 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::XPath; - -require 5.004; - -use strict; -use Template::Exception; -use Template::Plugin; -use XML::XPath; - -use base qw( Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.69 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($context, \%config) -# -# Constructor method for XML::XPath plugin. Creates an XML::XPath -# object and initialises plugin configuration. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my ($content, $about); - - # determine the input source from a positional parameter (may be a - # filename or XML text if it contains a '<' character) or by using - # named parameters which may specify one of 'file', 'filename', 'text' - # or 'xml' - - if ($content = shift) { - if ($content =~ /\</) { - $about = 'xml text'; - $args->{ xml } = $content; - } - else { - $about = "xml file $content"; - $args->{ filename } = $content; - } - } - elsif ($content = $args->{ text } || $args->{ xml }) { - $about = 'xml text'; - $args->{ xml } = $content; - } - elsif ($content = $args->{ file } || $args->{ filename }) { - $about = "xml file $content"; - $args->{ filename } = $content; - } - else { - return $class->_throw('no filename or xml text specified'); - } - - return XML::XPath->new(%$args) - or $class->_throw("failed to create XML::XPath::Parser\n"); -} - - - -#------------------------------------------------------------------------ -# _throw($errmsg) -# -# Raise a Template::Exception of type XML.XPath via die(). -#------------------------------------------------------------------------ - -sub _throw { - my ($self, $error) = @_; -# print STDERR "about to throw $error\n"; - die (Template::Exception->new('XML.XPath', $error)); -} - - -#======================================================================== -package XML::XPath::Node::Element; -#======================================================================== - -#------------------------------------------------------------------------ -# present($view) -# -# Method to present an element node via a view. -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - $view->view($self->getName(), $self); -} - -sub content { - my ($self, $view) = @_; - my $output = ''; - foreach my $node (@{ $self->getChildNodes }) { - $output .= $node->present($view); - } - return $output; -} - -#---------------------------------------------------------------------- -# starttag(), endtag() -# -# Methods to output the start & end tag, e.g. <foo bar="baz"> & </foo> -#---------------------------------------------------------------------- - -sub starttag { - my ($self) = @_; - my $output = "<". $self->getName(); - foreach my $attr ($self->getAttributes()) - { - $output .= $attr->toString(); - } - $output .= ">"; - return $output; -} - -sub endtag { - my ($self) = @_; - return "</". $self->getName() . ">"; -} - -#======================================================================== -package XML::XPath::Node::Text; -#======================================================================== - -#------------------------------------------------------------------------ -# present($view) -# -# Method to present a text node via a view. -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - $view->view('text', $self->string_value); -} - - -#======================================================================== -package XML::XPath::Node::Comment; -#======================================================================== - -sub present { return ''; } -sub starttag { return ''; } -sub endtag { return ''; } - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::XPath - Plugin interface to XML::XPath - -=head1 SYNOPSIS - - # load plugin and specify XML file to parse - [% USE xpath = XML.XPath(xmlfile) %] - [% USE xpath = XML.XPath(file => xmlfile) %] - [% USE xpath = XML.XPath(filename => xmlfile) %] - - # load plugin and specify XML text to parse - [% USE xpath = XML.XPath(xmltext) %] - [% USE xpath = XML.XPath(xml => xmltext) %] - [% USE xpath = XML.XPath(text => xmltext) %] - - # then call any XPath methods (see XML::XPath docs) - [% FOREACH page = xpath.findnodes('/html/body/page') %] - [% page.getAttribute('title') %] - [% END %] - - # define VIEW to present node(s) - [% VIEW repview notfound='xmlstring' %] - # handler block for a <report>...</report> element - [% BLOCK report %] - [% item.content(view) %] - [% END %] - - # handler block for a <section title="...">...</section> element - [% BLOCK section %] - <h1>[% item.getAttribute('title') | html %]</h1> - [% item.content(view) %] - [% END %] - - # default template block passes tags through and renders - # out the children recursivly - [% BLOCK xmlstring; - item.starttag; item.content(view); item.endtag; - END %] - - # block to generate simple text - [% BLOCK text; item | html; END %] - [% END %] - - # now present node (and children) via view - [% repview.print(page) %] - - # or print node content via view - [% page.content(repview) %] - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser and XML::XPath modules be -installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -=head1 DESCRIPTION - -This is a Template Toolkit plugin interfacing to the XML::XPath module. - -All methods implemented by the XML::XPath modules are available. In -addition, the XML::XPath::Node::Element module implements -present($view) and content($view) methods method for seamless -integration with Template Toolkit VIEWs. The XML::XPath::Node::Text -module is also adorned with a present($view) method which presents -itself via the view using the 'text' template. - -To aid the reconstruction of XML, methods starttag and endtag are -added to XML::XPath::Node::Element which return the start and -end tag for that element. This means that you can easily do: - - [% item.starttag %][% item.content(view) %][% item.endtag %] - -To render out the start tag, followed by the content rendered in the -view "view", followed by the end tag. - -=head1 AUTHORS - -This plugin module was written by Andy Wardley E<lt>abw@wardley.orgE<gt>. - -The XML::XPath module is by Matt Sergeant E<lt>matt@sergeant.orgE<gt>. - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::XPath|XML::XPath>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugins.pm b/lib/Template/Plugins.pm deleted file mode 100644 index 1904efc..0000000 --- a/lib/Template/Plugins.pm +++ /dev/null @@ -1,1041 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugins -# -# DESCRIPTION -# Plugin provider which handles the loading of plugin modules and -# instantiation of plugin objects. -# -# AUTHORS -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Plugins.pm,v 2.70 2004/01/13 16:19:15 abw Exp $ -# -#============================================================================ - -package Template::Plugins; - -require 5.004; - -use strict; -use base qw( Template::Base ); -use vars qw( $VERSION $DEBUG $STD_PLUGINS ); -use Template::Constants; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.70 $ =~ /(\d+)\.(\d+)/); - -$STD_PLUGINS = { - 'autoformat' => 'Template::Plugin::Autoformat', - 'cgi' => 'Template::Plugin::CGI', - 'datafile' => 'Template::Plugin::Datafile', - 'date' => 'Template::Plugin::Date', - 'debug' => 'Template::Plugin::Debug', - 'directory' => 'Template::Plugin::Directory', - 'dbi' => 'Template::Plugin::DBI', - 'dumper' => 'Template::Plugin::Dumper', - 'file' => 'Template::Plugin::File', - 'format' => 'Template::Plugin::Format', - 'html' => 'Template::Plugin::HTML', - 'image' => 'Template::Plugin::Image', - 'iterator' => 'Template::Plugin::Iterator', - 'pod' => 'Template::Plugin::Pod', - 'table' => 'Template::Plugin::Table', - 'url' => 'Template::Plugin::URL', - 'view' => 'Template::Plugin::View', - 'wrap' => 'Template::Plugin::Wrap', - 'xmlstyle' => 'Template::Plugin::XML::Style', -}; - - -#======================================================================== -# -- PUBLIC METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# fetch($name, \@args, $context) -# -# General purpose method for requesting instantiation of a plugin -# object. The name of the plugin is passed as the first parameter. -# The internal FACTORY lookup table is consulted to retrieve the -# appropriate factory object or class name. If undefined, the _load() -# method is called to attempt to load the module and return a factory -# class/object which is then cached for subsequent use. A reference -# to the calling context should be passed as the third parameter. -# This is passed to the _load() class method. The new() method is -# then called against the factory class name or prototype object to -# instantiate a new plugin object, passing any arguments specified by -# list reference as the second parameter. e.g. where $factory is the -# class name 'MyClass', the new() method is called as a class method, -# $factory->new(...), equivalent to MyClass->new(...) . Where -# $factory is a prototype object, the new() method is called as an -# object method, $myobject->new(...). This latter approach allows -# plugins to act as Singletons, cache shared data, etc. -# -# Returns a reference to a plugin, (undef, STATUS_DECLINE) to decline -# the request or ($error, STATUS_ERROR) on error. -#------------------------------------------------------------------------ - -sub fetch { - my ($self, $name, $args, $context) = @_; - my ($factory, $plugin, $error); - - $self->debug("fetch($name, ", - defined $args ? ('[ ', join(', ', @$args), ' ]') : '<no args>', ', ', - defined $context ? $context : '<no context>', - ')') if $self->{ DEBUG }; - - # NOTE: - # the $context ref gets passed as the first parameter to all regular - # plugins, but not to those loaded via LOAD_PERL; to hack around - # this until we have a better implementation, we pass the $args - # reference to _load() and let it unshift the first args in the - # LOAD_PERL case - - $args ||= [ ]; - unshift @$args, $context; - - $factory = $self->{ FACTORY }->{ $name } ||= do { - ($factory, $error) = $self->_load($name, $context); - return ($factory, $error) if $error; ## RETURN - $factory; - }; - - # call the new() method on the factory object or class name - eval { - if (ref $factory eq 'CODE') { - defined( $plugin = &$factory(@$args) ) - || die "$name plugin failed\n"; - } - else { - defined( $plugin = $factory->new(@$args) ) - || die "$name plugin failed: ", $factory->error(), "\n"; - } - }; - if ($error = $@) { -# chomp $error; - return $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ($error, Template::Constants::STATUS_ERROR); - } - - return $plugin; -} - - - -#======================================================================== -# -- PRIVATE METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# _init(\%config) -# -# Private initialisation method. -#------------------------------------------------------------------------ - -sub _init { - my ($self, $params) = @_; - my ($pbase, $plugins, $factory) = - @$params{ qw( PLUGIN_BASE PLUGINS PLUGIN_FACTORY ) }; - - $plugins ||= { }; - if (ref $pbase ne 'ARRAY') { - $pbase = $pbase ? [ $pbase ] : [ ]; - } - push(@$pbase, 'Template::Plugin'); - - $self->{ PLUGIN_BASE } = $pbase; - $self->{ PLUGINS } = { %$STD_PLUGINS, %$plugins }; - $self->{ TOLERANT } = $params->{ TOLERANT } || 0; - $self->{ LOAD_PERL } = $params->{ LOAD_PERL } || 0; - $self->{ FACTORY } = $factory || { }; - $self->{ DEBUG } = ( $params->{ DEBUG } || 0 ) - & Template::Constants::DEBUG_PLUGINS; - - return $self; -} - - - -#------------------------------------------------------------------------ -# _load($name, $context) -# -# Private method which attempts to load a plugin module and determine the -# correct factory name or object by calling the load() class method in -# the loaded module. -#------------------------------------------------------------------------ - -sub _load { - my ($self, $name, $context) = @_; - my ($factory, $module, $base, $pkg, $file, $ok, $error); - - if ($module = $self->{ PLUGINS }->{ $name }) { - # plugin module name is explicitly stated in PLUGIN_NAME - $pkg = $module; - ($file = $module) =~ s|::|/|g; - $file =~ s|::|/|g; - $self->debug("loading $module.pm (PLUGIN_NAME)") - if $self->{ DEBUG }; - $ok = eval { require "$file.pm" }; - $error = $@; - } - else { - # try each of the PLUGIN_BASE values to build module name - ($module = $name) =~ s/\./::/g; - - foreach $base (@{ $self->{ PLUGIN_BASE } }) { - $pkg = $base . '::' . $module; - ($file = $pkg) =~ s|::|/|g; - - $self->debug("loading $file.pm (PLUGIN_BASE)") - if $self->{ DEBUG }; - - $ok = eval { require "$file.pm" }; - last unless $@; - - $error .= "$@\n" - unless ($@ =~ /^Can\'t locate $file\.pm/); - } - } - - if ($ok) { - $self->debug("calling $pkg->load()") if $self->{ DEBUG }; - - $factory = eval { $pkg->load($context) }; - $error = ''; - if ($@ || ! $factory) { - $error = $@ || 'load() returned a false value'; - } - } - elsif ($self->{ LOAD_PERL }) { - # fallback - is it a regular Perl module? - ($file = $module) =~ s|::|/|g; - eval { require "$file.pm" }; - if ($@) { - $error = $@; - } - else { - # this is a regular Perl module so the new() constructor - # isn't expecting a $context reference as the first argument; - # so we construct a closure which removes it before calling - # $module->new(@_); - $factory = sub { - shift; - $module->new(@_); - }; - $error = ''; - } - } - - if ($factory) { - $self->debug("$name => $factory") if $self->{ DEBUG }; - return $factory; - } - elsif ($error) { - return $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ($error, Template::Constants::STATUS_ERROR); - } - else { - return (undef, Template::Constants::STATUS_DECLINED); - } -} - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which constructs and returns text representing the current -# state of the object. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $output = "[Template::Plugins] {\n"; - my $format = " %-16s => %s\n"; - my $key; - - foreach $key (qw( TOLERANT LOAD_PERL )) { - $output .= sprintf($format, $key, $self->{ $key }); - } - - local $" = ', '; - my $fkeys = join(", ", keys %{$self->{ FACTORY }}); - my $plugins = $self->{ PLUGINS }; - $plugins = join('', map { - sprintf(" $format", $_, $plugins->{ $_ }); - } keys %$plugins); - $plugins = "{\n$plugins }"; - - $output .= sprintf($format, 'PLUGIN_BASE', "[ @{ $self->{ PLUGIN_BASE } } ]"); - $output .= sprintf($format, 'PLUGINS', $plugins); - $output .= sprintf($format, 'FACTORY', $fkeys); - $output .= '}'; - return $output; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugins - Plugin provider module - -=head1 SYNOPSIS - - use Template::Plugins; - - $plugin_provider = Template::Plugins->new(\%options); - - ($plugin, $error) = $plugin_provider->fetch($name, @args); - -=head1 DESCRIPTION - -The Template::Plugins module defines a provider class which can be used -to load and instantiate Template Toolkit plugin modules. - -=head1 METHODS - -=head2 new(\%params) - -Constructor method which instantiates and returns a reference to a -Template::Plugins object. A reference to a hash array of configuration -items may be passed as a parameter. These are described below. - -Note that the Template.pm front-end module creates a Template::Plugins -provider, passing all configuration items. Thus, the examples shown -below in the form: - - $plugprov = Template::Plugins->new({ - PLUGIN_BASE => 'MyTemplate::Plugin', - LOAD_PERL => 1, - ... - }); - -can also be used via the Template module as: - - $ttengine = Template->new({ - PLUGIN_BASE => 'MyTemplate::Plugin', - LOAD_PERL => 1, - ... - }); - -as well as the more explicit form of: - - $plugprov = Template::Plugins->new({ - PLUGIN_BASE => 'MyTemplate::Plugin', - LOAD_PERL => 1, - ... - }); - - $ttengine = Template->new({ - LOAD_PLUGINS => [ $plugprov ], - }); - -=head2 fetch($name, @args) - -Called to request that a plugin of a given name be provided. The relevant -module is first loaded (if necessary) and the load() class method called -to return the factory class name (usually the same package name) or a -factory object (a prototype). The new() method is then called as a -class or object method against the factory, passing all remaining -parameters. - -Returns a reference to a new plugin object or ($error, STATUS_ERROR) -on error. May also return (undef, STATUS_DECLINED) to decline to -serve the request. If TOLERANT is set then all errors will be -returned as declines. - -=head1 CONFIGURATION OPTIONS - -The following list details the configuration options that can be provided -to the Template::Plugins new() constructor. - -=over 4 - - - - -=item PLUGINS - -The PLUGINS options can be used to provide a reference to a hash array -that maps plugin names to Perl module names. A number of standard -plugins are defined (e.g. 'table', 'cgi', 'dbi', etc.) which map to -their corresponding Template::Plugin::* counterparts. These can be -redefined by values in the PLUGINS hash. - - my $plugins = Template::Plugins->new({ - PLUGINS => { - cgi => 'MyOrg::Template::Plugin::CGI', - foo => 'MyOrg::Template::Plugin::Foo', - bar => 'MyOrg::Template::Plugin::Bar', - }, - }); - -The USE directive is used to create plugin objects and does so by -calling the plugin() method on the current Template::Context object. -If the plugin name is defined in the PLUGINS hash then the -corresponding Perl module is loaded via require(). The context then -calls the load() class method which should return the class name -(default and general case) or a prototype object against which the -new() method can be called to instantiate individual plugin objects. - -If the plugin name is not defined in the PLUGINS hash then the PLUGIN_BASE -and/or LOAD_PERL options come into effect. - - - - - -=item PLUGIN_BASE - -If a plugin is not defined in the PLUGINS hash then the PLUGIN_BASE is used -to attempt to construct a correct Perl module name which can be successfully -loaded. - -The PLUGIN_BASE can be specified as a single value or as a reference -to an array of multiple values. The default PLUGIN_BASE value, -'Template::Plugin', is always added the the end of the PLUGIN_BASE -list (a single value is first converted to a list). Each value should -contain a Perl package name to which the requested plugin name is -appended. - -example 1: - - my $plugins = Template::Plugins->new({ - PLUGIN_BASE => 'MyOrg::Template::Plugin', - }); - - [% USE Foo %] # => MyOrg::Template::Plugin::Foo - or Template::Plugin::Foo - -example 2: - - my $plugins = Template::Plugins->new({ - PLUGIN_BASE => [ 'MyOrg::Template::Plugin', - 'YourOrg::Template::Plugin' ], - }); - - [% USE Foo %] # => MyOrg::Template::Plugin::Foo - or YourOrg::Template::Plugin::Foo - or Template::Plugin::Foo - - - - - - -=item LOAD_PERL - -If a plugin cannot be loaded using the PLUGINS or PLUGIN_BASE -approaches then the provider can make a final attempt to load the -module without prepending any prefix to the module path. This allows -regular Perl modules (i.e. those that don't reside in the -Template::Plugin or some other such namespace) to be loaded and used -as plugins. - -By default, the LOAD_PERL option is set to 0 and no attempt will be made -to load any Perl modules that aren't named explicitly in the PLUGINS -hash or reside in a package as named by one of the PLUGIN_BASE -components. - -Plugins loaded using the PLUGINS or PLUGIN_BASE receive a reference to -the current context object as the first argument to the new() -constructor. Modules loaded using LOAD_PERL are assumed to not -conform to the plugin interface. They must provide a new() class -method for instantiating objects but it will not receive a reference -to the context as the first argument. Plugin modules should provide a -load() class method (or inherit the default one from the -Template::Plugin base class) which is called the first time the plugin -is loaded. Regular Perl modules need not. In all other respects, -regular Perl objects and Template Toolkit plugins are identical. - -If a particular Perl module does not conform to the common, but not -unilateral, new() constructor convention then a simple plugin wrapper -can be written to interface to it. - - - - -=item TOLERANT - -The TOLERANT flag is used by the various Template Toolkit provider -modules (Template::Provider, Template::Plugins, Template::Filters) to -control their behaviour when errors are encountered. By default, any -errors are reported as such, with the request for the particular -resource (template, plugin, filter) being denied and an exception -raised. When the TOLERANT flag is set to any true values, errors will -be silently ignored and the provider will instead return -STATUS_DECLINED. This allows a subsequent provider to take -responsibility for providing the resource, rather than failing the -request outright. If all providers decline to service the request, -either through tolerated failure or a genuine disinclination to -comply, then a 'E<lt>resourceE<gt> not found' exception is raised. - - - - -=item DEBUG - -The DEBUG option can be used to enable debugging messages from the -Template::Plugins module by setting it to include the DEBUG_PLUGINS -value. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_FILTERS | DEBUG_PLUGINS, - }); - - - - -=back - - - -=head1 TEMPLATE TOOLKIT PLUGINS - -The following plugin modules are distributed with the Template -Toolkit. Some of the plugins interface to external modules (detailed -below) which should be downloaded from any CPAN site and installed -before using the plugin. - -=head2 Autoformat - -The Autoformat plugin is an interface to Damian Conway's Text::Autoformat -Perl module which provides advanced text wrapping and formatting. See -L<Template::Plugin::Autoformat> and L<Text::Autoformat> for further -details. - - [% USE autoformat(left=10, right=20) %] - [% autoformat(mytext) %] # call autoformat sub - [% mytext FILTER autoformat %] # or use autoformat filter - -The Text::Autoformat module is available from CPAN: - - http://www.cpan.org/modules/by-module/Text/ - -=head2 CGI - -The CGI plugin is a wrapper around Lincoln Stein's -E<lt>lstein@genome.wi.mit.eduE<gt> CGI.pm module. The plugin is -distributed with the Template Toolkit (see L<Template::Plugin::CGI>) -and the CGI module itself is distributed with recent versions Perl, -or is available from CPAN. - - [% USE CGI %] - [% CGI.param('param_name') %] - [% CGI.start_form %] - [% CGI.popup_menu( Name => 'color', - Values => [ 'Green', 'Brown' ] ) %] - [% CGI.end_form %] - -=head2 Datafile - -Provides an interface to data stored in a plain text file in a simple -delimited format. The first line in the file specifies field names -which should be delimiter by any non-word character sequence. -Subsequent lines define data using the same delimiter as int he first -line. Blank lines and comments (lines starting '#') are ignored. See -L<Template::Plugin::Datafile> for further details. - -/tmp/mydata: - - # define names for each field - id : email : name : tel - # here's the data - fred : fred@here.com : Fred Smith : 555-1234 - bill : bill@here.com : Bill White : 555-5678 - -example: - - [% USE userlist = datafile('/tmp/mydata') %] - - [% FOREACH user = userlist %] - [% user.name %] ([% user.id %]) - [% END %] - -=head2 Date - -The Date plugin provides an easy way to generate formatted time and date -strings by delegating to the POSIX strftime() routine. See -L<Template::Plugin::Date> and L<POSIX> for further details. - - [% USE date %] - [% date.format %] # current time/date - - File last modified: [% date.format(template.modtime) %] - -=head2 Directory - -The Directory plugin provides a simple interface to a directory and -the files within it. See L<Template::Plugin::Directory> for further -details. - - [% USE dir = Directory('/tmp') %] - [% FOREACH file = dir.files %] - # all the plain files in the directory - [% END %] - [% FOREACH file = dir.dirs %] - # all the sub-directories - [% END %] - -=head2 DBI - -The DBI plugin, developed by Simon Matthews -E<lt>sam@knowledgepool.comE<gt>, brings the full power of Tim Bunce's -E<lt>Tim.Bunce@ig.co.ukE<gt> database interface module (DBI) to your -templates. See L<Template::Plugin::DBI> and L<DBI> for further details. - - [% USE DBI('dbi:driver:database', 'user', 'pass') %] - - [% FOREACH user = DBI.query( 'SELECT * FROM users' ) %] - [% user.id %] [% user.name %] - [% END %] - -The DBI and relevant DBD modules are available from CPAN: - - http://www.cpan.org/modules/by-module/DBI/ - -=head2 Dumper - -The Dumper plugin provides an interface to the Data::Dumper module. See -L<Template::Plugin::Dumper> and L<Data::Dumper> for futher details. - - [% USE dumper(indent=0, pad="<br>") %] - [% dumper.dump(myvar, yourvar) %] - -=head2 File - -The File plugin provides a general abstraction for files and can be -used to fetch information about specific files within a filesystem. -See L<Template::Plugin::File> for further details. - - [% USE File('/tmp/foo.html') %] - [% File.name %] # foo.html - [% File.dir %] # /tmp - [% File.mtime %] # modification time - -=head2 Filter - -This module implements a base class plugin which can be subclassed -to easily create your own modules that define and install new filters. - - 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 %] - -See L<Template::Plugin::Filter> for further details. - -=head2 Format - -The Format plugin provides a simple way to format text according to a -printf()-like format. See L<Template::Plugin::Format> for further -details. - - [% USE bold = format('<b>%s</b>') %] - [% bold('Hello') %] - -=head2 GD::Image, GD::Polygon, GD::Constants - -These plugins provide access to the GD graphics library via Lincoln -D. Stein's GD.pm interface. These plugins allow PNG, JPEG and other -graphical formats to be generated. - - [% FILTER null; - USE im = GD.Image(100,100); - # allocate some colors - black = im.colorAllocate(0, 0, 0); - red = im.colorAllocate(255,0, 0); - blue = im.colorAllocate(0, 0, 255); - # Draw a blue oval - im.arc(50,50,95,75,0,360,blue); - # And fill it with red - im.fill(50,50,red); - # Output image in PNG format - im.png | stdout(1); - END; - -%] - -See L<Template::Plugin::GD::Image> for further details. - -=head2 GD::Text, GD::Text::Align, GD::Text::Wrap - -These plugins provide access to Martien Verbruggen's GD::Text, -GD::Text::Align and GD::Text::Wrap modules. These plugins allow the -layout, alignment and wrapping of text when drawing text in GD images. - - [% FILTER null; - USE gd = GD.Image(200,400); - USE gdc = GD.Constants; - black = gd.colorAllocate(0, 0, 0); - green = gd.colorAllocate(0, 255, 0); - txt = "This is some long text. " | repeat(10); - USE wrapbox = GD.Text.Wrap(gd, - line_space => 4, - color => green, - text => txt, - ); - wrapbox.set_font(gdc.gdMediumBoldFont); - wrapbox.set(align => 'center', width => 160); - wrapbox.draw(20, 20); - gd.png | stdout(1); - END; - -%] - -See L<Template::Plugin::GD::Text>, L<Template::Plugin::GD::Text::Align> -and L<Template::Plugin::GD::Text::Wrap> for further details. - -=head2 GD::Graph::lines, GD::Graph::bars, GD::Graph::points, GD::Graph::linespoin -ts, GD::Graph::area, GD::Graph::mixed, GD::Graph::pie - -These plugins provide access to Martien Verbruggen's GD::Graph module -that allows graphs, plots and charts to be created. These plugins allow -graphs, plots and charts to be generated in PNG, JPEG and other -graphical formats. - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th"], - [ 4, 2, 3, 4, 3, 3.5] - ]; - USE my_graph = GD.Graph.pie(250, 200); - my_graph.set( - title => 'A Pie Chart', - label => 'Label', - axislabelclr => 'black', - pie_height => 36, - transparent => 0, - ); - my_graph.plot(data).png | stdout(1); - END; - -%] - -See -L<Template::Plugin::GD::Graph::lines>, -L<Template::Plugin::GD::Graph::bars>, -L<Template::Plugin::GD::Graph::points>, -L<Template::Plugin::GD::Graph::linespoints>, -L<Template::Plugin::GD::Graph::area>, -L<Template::Plugin::GD::Graph::mixed>, -L<Template::Plugin::GD::Graph::pie>, and -L<GD::Graph>, -for more details. - -=head2 GD::Graph::bars3d, GD::Graph::lines3d, GD::Graph::pie3d - -These plugins provide access to Jeremy Wadsack's GD::Graph3d -module. This allows 3D bar charts and 3D lines plots to -be generated. - - [% FILTER null; - data = [ - ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"], - [ 1, 2, 5, 6, 3, 1.5, 1, 3, 4], - ]; - USE my_graph = GD.Graph.bars3d(); - my_graph.set( - x_label => 'X Label', - y_label => 'Y label', - title => 'A 3d Bar Chart', - y_max_value => 8, - y_tick_number => 8, - y_label_skip => 2, - # shadows - bar_spacing => 8, - shadow_depth => 4, - shadowclr => 'dred', - transparent => 0, - my_graph.plot(data).png | stdout(1); - END; - -%] - -See -L<Template::Plugin::GD::Graph::lines3d>, -L<Template::Plugin::GD::Graph::bars3d>, and -L<Template::Plugin::GD::Graph::pie3d> -for more details. - -=head2 HTML - -The HTML plugin is very new and very basic, implementing a few useful -methods for generating HTML. It is likely to be extended in the future -or integrated with a larger project to generate HTML elements in a generic -way (as discussed recently on the mod_perl mailing list). - - [% USE HTML %] - [% HTML.escape("if (a < b && c > d) ..." %] - [% HTML.attributes(border => 1, cellpadding => 2) %] - [% HTML.element(table => { border => 1, cellpadding => 2 }) %] - -See L<Template::Plugin::HTML> for further details. - -=head2 Iterator - -The Iterator plugin provides a way to create a Template::Iterator -object to iterate over a data set. An iterator is created -automatically by the FOREACH directive and is aliased to the 'loop' -variable. This plugin allows an iterator to be explicitly created -with a given name, or the default plugin name, 'iterator'. See -L<Template::Plugin::Iterator> for further details. - - [% USE iterator(list, args) %] - - [% FOREACH item = iterator %] - [% '<ul>' IF iterator.first %] - <li>[% item %] - [% '</ul>' IF iterator.last %] - [% END %] - -=head2 Pod - -This plugin provides an interface to the L<Pod::POM|Pod::POM> module -which parses POD documents into an internal object model which can -then be traversed and presented through the Template Toolkit. - - [% USE Pod(podfile) %] - - [% FOREACH head1 = Pod.head1; - FOREACH head2 = head1/head2; - ... - END; - END - %] - -=head2 String - -The String plugin implements an object-oriented interface for -manipulating strings. See L<Template::Plugin::String> for further -details. - - [% USE String 'Hello' %] - [% String.append(' World') %] - - [% msg = String.new('Another string') %] - [% msg.replace('string', 'text') %] - - The string "[% msg %]" is [% msg.length %] characters long. - -=head2 Table - -The Table plugin allows you to format a list of data items into a -virtual table by specifying a fixed number of rows or columns, with -an optional overlap. See L<Template::Plugin::Table> for further -details. - - [% USE table(list, rows=10, overlap=1) %] - - [% FOREACH item = table.col(3) %] - [% item %] - [% END %] - -=head2 URL - -The URL plugin provides a simple way of contructing URLs from a base -part and a variable set of parameters. See L<Template::Plugin::URL> -for further details. - - [% USE mycgi = url('/cgi-bin/bar.pl', debug=1) %] - - [% mycgi %] - # ==> /cgi/bin/bar.pl?debug=1 - - [% mycgi(mode='submit') %] - # ==> /cgi/bin/bar.pl?mode=submit&debug=1 - -=head2 Wrap - -The Wrap plugin uses the Text::Wrap module by David Muir Sharnoff -E<lt>muir@idiom.comE<gt> (with help from Tim Pierce and many many others) -to provide simple paragraph formatting. See L<Template::Plugin::Wrap> -and L<Text::Wrap> for further details. - - [% USE wrap %] - [% wrap(mytext, 40, '* ', ' ') %] # use wrap sub - [% mytext FILTER wrap(40) -%] # or wrap FILTER - -The Text::Wrap module is available from CPAN: - - http://www.cpan.org/modules/by-module/Text/ - -=head2 XML::DOM - -The XML::DOM plugin gives access to the XML Document Object Module via -Clark Cooper E<lt>cooper@sch.ge.comE<gt> and Enno Derksen's -E<lt>enno@att.comE<gt> XML::DOM module. See L<Template::Plugin::XML::DOM> -and L<XML::DOM> for further details. - - [% USE dom = XML.DOM %] - [% doc = dom.parse(filename) %] - - [% FOREACH node = doc.getElementsByTagName('CODEBASE') %] - * [% node.getAttribute('href') %] - [% END %] - -The plugin requires the XML::DOM module, available from CPAN: - - http://www.cpan.org/modules/by-module/XML/ - -=head2 XML::RSS - -The XML::RSS plugin is a simple interface to Jonathan Eisenzopf's -E<lt>eisen@pobox.comE<gt> XML::RSS module. A RSS (Rich Site Summary) -file is typically used to store short news 'headlines' describing -different links within a site. This plugin allows you to parse RSS -files and format the contents accordingly using templates. -See L<Template::Plugin::XML::RSS> and L<XML::RSS> for further details. - - [% USE news = XML.RSS(filename) %] - - [% FOREACH item = news.items %] - <a href="[% item.link %]">[% item.title %]</a> - [% END %] - -The XML::RSS module is available from CPAN: - - http://www.cpan.org/modules/by-module/XML/ - -=head2 XML::Simple - -This plugin implements an interface to the L<XML::Simple|XML::Simple> -module. - - [% USE xml = XML.Simple(xml_file_or_text) %] - - [% xml.head.title %] - -See L<Template::Plugin::XML::Simple> for further details. - -=head2 XML::Style - -This plugin defines a filter for performing simple stylesheet based -transformations of XML text. - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - cellspacing = 1 - } - } - %] - - [% FILTER xmlstyle %] - <table> - <tr> - <td>Foo</td> <td>Bar</td> <td>Baz</td> - </tr> - </table> - [% END %] - -See L<Template::Plugin::XML::Style> for further details. - -=head2 XML::XPath - -The XML::XPath plugin provides an interface to Matt Sergeant's -E<lt>matt@sergeant.orgE<gt> XML::XPath module. See -L<Template::Plugin::XML::XPath> and L<XML::XPath> for further details. - - [% USE xpath = XML.XPath(xmlfile) %] - [% FOREACH page = xpath.findnodes('/html/body/page') %] - [% page.getAttribute('title') %] - [% END %] - -The plugin requires the XML::XPath module, available from CPAN: - - http://www.cpan.org/modules/by-module/XML/ - - - - -=head1 BUGS / ISSUES - -=over 4 - -=item * - -It might be worthwhile being able to distinguish between absolute -module names and those which should be applied relative to PLUGIN_BASE -directories. For example, use 'MyNamespace::MyModule' to denote -absolute module names (e.g. LOAD_PERL), and 'MyNamespace.MyModule' to -denote relative to PLUGIN_BASE. - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.70, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Plugin|Template::Plugin>, L<Template::Context|Template::Context> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Provider.pm b/lib/Template/Provider.pm deleted file mode 100644 index 0826a18..0000000 --- a/lib/Template/Provider.pm +++ /dev/null @@ -1,1449 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Provider -# -# DESCRIPTION -# This module implements a class which handles the loading, compiling -# and caching of templates. Multiple Template::Provider objects can -# be stacked and queried in turn to effect a Chain-of-Command between -# them. A provider will attempt to return the requested template, -# an error (STATUS_ERROR) or decline to provide the template -# (STATUS_DECLINE), allowing subsequent providers to attempt to -# deliver it. See 'Design Patterns' for further details. -# -# AUTHOR -# Andy Wardley <abw@wardley.org> -# -# COPYRIGHT -# Copyright (C) 1996-2003 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. -# -# TODO: -# * optional provider prefix (e.g. 'http:') -# * fold ABSOLUTE and RELATIVE test cases into one regex? -# -#---------------------------------------------------------------------------- -# -# $Id: Provider.pm,v 2.79 2004/01/13 16:19:16 abw Exp $ -# -#============================================================================ - -package Template::Provider; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $ERROR $DOCUMENT $STAT_TTL $MAX_DIRS ); -use base qw( Template::Base ); -use Template::Config; -use Template::Constants; -use Template::Document; -use File::Basename; -use File::Spec; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.79 $ =~ /(\d+)\.(\d+)/); - -# name of document class -$DOCUMENT = 'Template::Document' unless defined $DOCUMENT; - -# maximum time between performing stat() on file to check staleness -$STAT_TTL = 1 unless defined $STAT_TTL; - -# maximum number of directories in an INCLUDE_PATH, to prevent runaways -$MAX_DIRS = 64 unless defined $MAX_DIRS; - -use constant PREV => 0; -use constant NAME => 1; -use constant DATA => 2; -use constant LOAD => 3; -use constant NEXT => 4; -use constant STAT => 5; - -$DEBUG = 0 unless defined $DEBUG; - -#======================================================================== -# -- PUBLIC METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# fetch($name) -# -# Returns a compiled template for the name specified by parameter. -# The template is returned from the internal cache if it exists, or -# loaded and then subsequently cached. The ABSOLUTE and RELATIVE -# configuration flags determine if absolute (e.g. '/something...') -# and/or relative (e.g. './something') paths should be honoured. The -# INCLUDE_PATH is otherwise used to find the named file. $name may -# also be a reference to a text string containing the template text, -# or a file handle from which the content is read. The compiled -# template is not cached in these latter cases given that there is no -# filename to cache under. A subsequent call to store($name, -# $compiled) can be made to cache the compiled template for future -# fetch() calls, if necessary. -# -# Returns a compiled template or (undef, STATUS_DECLINED) if the -# template could not be found. On error (e.g. the file was found -# but couldn't be read or parsed), the pair ($error, STATUS_ERROR) -# is returned. The TOLERANT configuration option can be set to -# downgrade any errors to STATUS_DECLINE. -#------------------------------------------------------------------------ - -sub fetch { - my ($self, $name) = @_; - my ($data, $error); - - if (ref $name) { - # $name can be a reference to a scalar, GLOB or file handle - ($data, $error) = $self->_load($name); - ($data, $error) = $self->_compile($data) - unless $error; - $data = $data->{ data } - unless $error; - } - elsif (File::Spec->file_name_is_absolute($name)) { - # absolute paths (starting '/') allowed if ABSOLUTE set - ($data, $error) = $self->{ ABSOLUTE } - ? $self->_fetch($name) - : $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ("$name: absolute paths are not allowed (set ABSOLUTE option)", - Template::Constants::STATUS_ERROR); - } - elsif ($name =~ m[^\.+/]) { - # anything starting "./" is relative to cwd, allowed if RELATIVE set - ($data, $error) = $self->{ RELATIVE } - ? $self->_fetch($name) - : $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ("$name: relative paths are not allowed (set RELATIVE option)", - Template::Constants::STATUS_ERROR); - } - else { - # otherwise, it's a file name relative to INCLUDE_PATH - ($data, $error) = $self->{ INCLUDE_PATH } - ? $self->_fetch_path($name) - : (undef, Template::Constants::STATUS_DECLINED); - } - -# $self->_dump_cache() -# if $DEBUG > 1; - - return ($data, $error); -} - - -#------------------------------------------------------------------------ -# store($name, $data) -# -# Store a compiled template ($data) in the cached as $name. -#------------------------------------------------------------------------ - -sub store { - my ($self, $name, $data) = @_; - $self->_store($name, { - data => $data, - load => 0, - }); -} - - -#------------------------------------------------------------------------ -# load($name) -# -# Load a template without parsing/compiling it, suitable for use with -# the INSERT directive. There's some duplication with fetch() and at -# some point this could be reworked to integrate them a little closer. -#------------------------------------------------------------------------ - -sub load { - my ($self, $name) = @_; - my ($data, $error); - my $path = $name; - - if (File::Spec->file_name_is_absolute($name)) { - # absolute paths (starting '/') allowed if ABSOLUTE set - $error = "$name: absolute paths are not allowed (set ABSOLUTE option)" - unless $self->{ ABSOLUTE }; - } - elsif ($name =~ m[^\.+/]) { - # anything starting "./" is relative to cwd, allowed if RELATIVE set - $error = "$name: relative paths are not allowed (set RELATIVE option)" - unless $self->{ RELATIVE }; - } - else { - INCPATH: { - # otherwise, it's a file name relative to INCLUDE_PATH - my $paths = $self->paths() - || return ($self->error(), Template::Constants::STATUS_ERROR); - - foreach my $dir (@$paths) { - $path = "$dir/$name"; - last INCPATH - if -f $path; - } - undef $path; # not found - } - } - - if (defined $path && ! $error) { - local $/ = undef; # slurp files in one go - local *FH; - if (open(FH, $path)) { - $data = <FH>; - close(FH); - } - else { - $error = "$name: $!"; - } - } - - if ($error) { - return $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ($error, Template::Constants::STATUS_ERROR); - } - elsif (! defined $path) { - return (undef, Template::Constants::STATUS_DECLINED); - } - else { - return ($data, Template::Constants::STATUS_OK); - } -} - - - -#------------------------------------------------------------------------ -# include_path(\@newpath) -# -# Accessor method for the INCLUDE_PATH setting. If called with an -# argument, this method will replace the existing INCLUDE_PATH with -# the new value. -#------------------------------------------------------------------------ - -sub include_path { - my ($self, $path) = @_; - $self->{ INCLUDE_PATH } = $path if $path; - return $self->{ INCLUDE_PATH }; -} - - -#------------------------------------------------------------------------ -# paths() -# -# Evaluates the INCLUDE_PATH list, ignoring any blank entries, and -# calling and subroutine or object references to return dynamically -# generated path lists. Returns a reference to a new list of paths -# or undef on error. -#------------------------------------------------------------------------ - -sub paths { - my $self = shift; - my @ipaths = @{ $self->{ INCLUDE_PATH } }; - my (@opaths, $dpaths, $dir); - my $count = $MAX_DIRS; - - while (@ipaths && --$count) { - $dir = shift @ipaths || next; - - # $dir can be a sub or object ref which returns a reference - # to a dynamically generated list of search paths. - - if (ref $dir eq 'CODE') { - eval { $dpaths = &$dir() }; - if ($@) { - chomp $@; - return $self->error($@); - } - unshift(@ipaths, @$dpaths); - next; - } - elsif (UNIVERSAL::can($dir, 'paths')) { - $dpaths = $dir->paths() - || return $self->error($dir->error()); - unshift(@ipaths, @$dpaths); - next; - } - else { - push(@opaths, $dir); - } - } - return $self->error("INCLUDE_PATH exceeds $MAX_DIRS directories") - if @ipaths; - - return \@opaths; -} - - -#------------------------------------------------------------------------ -# DESTROY -# -# The provider cache is implemented as a doubly linked list which Perl -# cannot free by itself due to the circular references between NEXT <=> -# PREV items. This cleanup method walks the list deleting all the NEXT/PREV -# references, allowing the proper cleanup to occur and memory to be -# repooled. -#------------------------------------------------------------------------ - -sub DESTROY { - my $self = shift; - my ($slot, $next); - - $slot = $self->{ HEAD }; - while ($slot) { - $next = $slot->[ NEXT ]; - undef $slot->[ PREV ]; - undef $slot->[ NEXT ]; - $slot = $next; - } - undef $self->{ HEAD }; - undef $self->{ TAIL }; -} - - - - -#======================================================================== -# -- PRIVATE METHODS -- -#======================================================================== - -#------------------------------------------------------------------------ -# _init() -# -# Initialise the cache. -#------------------------------------------------------------------------ - -sub _init { - my ($self, $params) = @_; - my $size = $params->{ CACHE_SIZE }; - my $path = $params->{ INCLUDE_PATH } || '.'; - my $cdir = $params->{ COMPILE_DIR } || ''; - my $dlim = $params->{ DELIMITER }; - my $debug; - - # tweak delim to ignore C:/ - unless (defined $dlim) { - $dlim = ($^O eq 'MSWin32') ? ':(?!\\/)' : ':'; - } - - # coerce INCLUDE_PATH to an array ref, if not already so - $path = [ split(/$dlim/, $path) ] - unless ref $path eq 'ARRAY'; - - # don't allow a CACHE_SIZE 1 because it breaks things and the - # additional checking isn't worth it - $size = 2 - if defined $size && ($size == 1 || $size < 0); - - if (defined ($debug = $params->{ DEBUG })) { - $self->{ DEBUG } = $debug & ( Template::Constants::DEBUG_PROVIDER - | Template::Constants::DEBUG_FLAGS ); - } - else { - $self->{ DEBUG } = $DEBUG; - } - - if ($self->{ DEBUG }) { - local $" = ', '; - $self->debug("creating cache of ", - defined $size ? $size : 'unlimited', - " slots for [ @$path ]"); - } - - # create COMPILE_DIR and sub-directories representing each INCLUDE_PATH - # element in which to store compiled files - if ($cdir) { - -# Stas' hack -# # this is a hack to solve the problem with INCLUDE_PATH using -# # relative dirs -# my $segments = 0; -# for (@$path) { -# my $c = 0; -# $c++ while m|\.\.|g; -# $segments = $c if $c > $segments; -# } -# $cdir .= "/".join "/",('hack') x $segments if $segments; -# - - require File::Path; - foreach my $dir (@$path) { - next if ref $dir; - my $wdir = $dir; - $wdir =~ s[:][]g if $^O eq 'MSWin32'; - $wdir =~ /(.*)/; # untaint - &File::Path::mkpath(File::Spec->catfile($cdir, $1)); - } - } - - $self->{ LOOKUP } = { }; - $self->{ SLOTS } = 0; - $self->{ SIZE } = $size; - $self->{ INCLUDE_PATH } = $path; - $self->{ DELIMITER } = $dlim; - $self->{ COMPILE_DIR } = $cdir; - $self->{ COMPILE_EXT } = $params->{ COMPILE_EXT } || ''; - $self->{ ABSOLUTE } = $params->{ ABSOLUTE } || 0; - $self->{ RELATIVE } = $params->{ RELATIVE } || 0; - $self->{ TOLERANT } = $params->{ TOLERANT } || 0; - $self->{ DOCUMENT } = $params->{ DOCUMENT } || $DOCUMENT; - $self->{ PARSER } = $params->{ PARSER }; - $self->{ DEFAULT } = $params->{ DEFAULT }; -# $self->{ PREFIX } = $params->{ PREFIX }; - $self->{ PARAMS } = $params; - - return $self; -} - - -#------------------------------------------------------------------------ -# _fetch($name) -# -# Fetch a file from cache or disk by specification of an absolute or -# relative filename. No search of the INCLUDE_PATH is made. If the -# file is found and loaded, it is compiled and cached. -#------------------------------------------------------------------------ - -sub _fetch { - my ($self, $name) = @_; - my $size = $self->{ SIZE }; - my ($slot, $data, $error); - - $self->debug("_fetch($name)") if $self->{ DEBUG }; - - my $compiled = $self->_compiled_filename($name); - - if (defined $size && ! $size) { - # caching disabled so load and compile but don't cache - if ($compiled && -f $compiled - && (stat($name))[9] <= (stat($compiled))[9]) { - $data = $self->_load_compiled($compiled); - $error = $self->error() unless $data; - } - else { - ($data, $error) = $self->_load($name); - ($data, $error) = $self->_compile($data, $compiled) - unless $error; - $data = $data->{ data } - unless $error; - } - } - elsif ($slot = $self->{ LOOKUP }->{ $name }) { - # cached entry exists, so refresh slot and extract data - ($data, $error) = $self->_refresh($slot); - $data = $slot->[ DATA ] - unless $error; - } - else { - # nothing in cache so try to load, compile and cache - if ($compiled && -f $compiled - && (stat($name))[9] <= (stat($compiled))[9]) { - $data = $self->_load_compiled($compiled); - $error = $self->error() unless $data; - $self->store($name, $data) unless $error; - } - else { - ($data, $error) = $self->_load($name); - ($data, $error) = $self->_compile($data, $compiled) - unless $error; - $data = $self->_store($name, $data) - unless $error; - } - } - - return ($data, $error); -} - - -#------------------------------------------------------------------------ -# _fetch_path($name) -# -# Fetch a file from cache or disk by specification of an absolute cache -# name (e.g. 'header') or filename relative to one of the INCLUDE_PATH -# directories. If the file isn't already cached and can be found and -# loaded, it is compiled and cached under the full filename. -#------------------------------------------------------------------------ - -sub _fetch_path { - my ($self, $name) = @_; - my ($size, $compext, $compdir) = - @$self{ qw( SIZE COMPILE_EXT COMPILE_DIR ) }; - my ($dir, $paths, $path, $compiled, $slot, $data, $error); - local *FH; - - $self->debug("_fetch_path($name)") if $self->{ DEBUG }; - - # caching is enabled if $size is defined and non-zero or undefined - my $caching = (! defined $size || $size); - - INCLUDE: { - - # the template may have been stored using a non-filename name - if ($caching && ($slot = $self->{ LOOKUP }->{ $name })) { - # cached entry exists, so refresh slot and extract data - ($data, $error) = $self->_refresh($slot); - $data = $slot->[ DATA ] - unless $error; - last INCLUDE; - } - - $paths = $self->paths() || do { - $error = Template::Constants::STATUS_ERROR; - $data = $self->error(); - last INCLUDE; - }; - - # search the INCLUDE_PATH for the file, in cache or on disk - foreach $dir (@$paths) { - $path = File::Spec->catfile($dir, $name); - - $self->debug("searching path: $path\n") if $self->{ DEBUG }; - - if ($caching && ($slot = $self->{ LOOKUP }->{ $path })) { - # cached entry exists, so refresh slot and extract data - ($data, $error) = $self->_refresh($slot); - $data = $slot->[ DATA ] - unless $error; - last INCLUDE; - } - elsif (-f $path) { - $compiled = $self->_compiled_filename($path) - if $compext || $compdir; - - if ($compiled && -f $compiled - && (stat($path))[9] <= (stat($compiled))[9]) { - if ($data = $self->_load_compiled($compiled)) { - # store in cache - $data = $self->store($path, $data); - $error = Template::Constants::STATUS_OK; - last INCLUDE; - } - else { - warn($self->error(), "\n"); - } - } - # $compiled is set if an attempt to write the compiled - # template to disk should be made - - ($data, $error) = $self->_load($path, $name); - ($data, $error) = $self->_compile($data, $compiled) - unless $error; - $data = $self->_store($path, $data) - unless $error || ! $caching; - $data = $data->{ data } if ! $caching; - # all done if $error is OK or ERROR - last INCLUDE if ! $error - || $error == Template::Constants::STATUS_ERROR; - } - } - # template not found, so look for a DEFAULT template - my $default; - if (defined ($default = $self->{ DEFAULT }) && $name ne $default) { - $name = $default; - redo INCLUDE; - } - ($data, $error) = (undef, Template::Constants::STATUS_DECLINED); - } # INCLUDE - - return ($data, $error); -} - - - -sub _compiled_filename { - my ($self, $file) = @_; - my ($compext, $compdir) = @$self{ qw( COMPILE_EXT COMPILE_DIR ) }; - my ($path, $compiled); - - return undef - unless $compext || $compdir; - - $path = $file; - $path =~ /^(.+)$/s or die "invalid filename: $path"; - $path =~ s[:][]g if $^O eq 'MSWin32'; - - $compiled = "$path$compext"; - $compiled = File::Spec->catfile($compdir, $compiled) if length $compdir; - - return $compiled; -} - - -sub _load_compiled { - my ($self, $file) = @_; - my $compiled; - - # load compiled template via require(); we zap any - # %INC entry to ensure it is reloaded (we don't - # want 1 returned by require() to say it's in memory) - delete $INC{ $file }; - eval { $compiled = require $file; }; - return $@ - ? $self->error("compiled template $compiled: $@") - : $compiled; -} - - - -#------------------------------------------------------------------------ -# _load($name, $alias) -# -# Load template text from a string ($name = scalar ref), GLOB or file -# handle ($name = ref), or from an absolute filename ($name = scalar). -# Returns a hash array containing the following items: -# name filename or $alias, if provided, or 'input text', etc. -# text template text -# time modification time of file, or current time for handles/strings -# load time file was loaded (now!) -# -# On error, returns ($error, STATUS_ERROR), or (undef, STATUS_DECLINED) -# if TOLERANT is set. -#------------------------------------------------------------------------ - -sub _load { - my ($self, $name, $alias) = @_; - my ($data, $error); - my $tolerant = $self->{ TOLERANT }; - my $now = time; - local $/ = undef; # slurp files in one go - local *FH; - - $alias = $name unless defined $alias or ref $name; - - $self->debug("_load($name, ", defined $alias ? $alias : '<no alias>', - ')') if $self->{ DEBUG }; - - LOAD: { - if (ref $name eq 'SCALAR') { - # $name can be a SCALAR reference to the input text... - $data = { - name => defined $alias ? $alias : 'input text', - text => $$name, - time => $now, - load => 0, - }; - } - elsif (ref $name) { - # ...or a GLOB or file handle... - my $text = <$name>; - $data = { - name => defined $alias ? $alias : 'input file handle', - text => $text, - time => $now, - load => 0, - }; - } - elsif (-f $name) { - if (open(FH, $name)) { - my $text = <FH>; - $data = { - name => $alias, - path => $name, - text => $text, - time => (stat $name)[9], - load => $now, - }; - } - elsif ($tolerant) { - ($data, $error) = (undef, Template::Constants::STATUS_DECLINED); - } - else { - $data = "$alias: $!"; - $error = Template::Constants::STATUS_ERROR; - } - } - else { - ($data, $error) = (undef, Template::Constants::STATUS_DECLINED); - } - } - - $data->{ path } = $data->{ name } - if $data and ! defined $data->{ path }; - - return ($data, $error); -} - - -#------------------------------------------------------------------------ -# _refresh(\@slot) -# -# Private method called to mark a cache slot as most recently used. -# A reference to the slot array should be passed by parameter. The -# slot is relocated to the head of the linked list. If the file from -# which the data was loaded has been upated since it was compiled, then -# it is re-loaded from disk and re-compiled. -#------------------------------------------------------------------------ - -sub _refresh { - my ($self, $slot) = @_; - my ($head, $file, $data, $error); - - - $self->debug("_refresh([ ", - join(', ', map { defined $_ ? $_ : '<undef>' } @$slot), - '])') if $self->{ DEBUG }; - - # if it's more than $STAT_TTL seconds since we last performed a - # stat() on the file then we need to do it again and see if the file - # time has changed - if ( (time - $slot->[ STAT ]) > $STAT_TTL && stat $slot->[ NAME ] ) { - $slot->[ STAT ] = time; - - if ( (stat(_))[9] != $slot->[ LOAD ]) { - - $self->debug("refreshing cache file ", $slot->[ NAME ]) - if $self->{ DEBUG }; - - ($data, $error) = $self->_load($slot->[ NAME ], - $slot->[ DATA ]->{ name }); - ($data, $error) = $self->_compile($data) - unless $error; - - unless ($error) { - $slot->[ DATA ] = $data->{ data }; - $slot->[ LOAD ] = $data->{ time }; - } - } - } - - unless( $self->{ HEAD } == $slot ) { - # remove existing slot from usage chain... - if ($slot->[ PREV ]) { - $slot->[ PREV ]->[ NEXT ] = $slot->[ NEXT ]; - } - else { - $self->{ HEAD } = $slot->[ NEXT ]; - } - if ($slot->[ NEXT ]) { - $slot->[ NEXT ]->[ PREV ] = $slot->[ PREV ]; - } - else { - $self->{ TAIL } = $slot->[ PREV ]; - } - - # ..and add to start of list - $head = $self->{ HEAD }; - $head->[ PREV ] = $slot if $head; - $slot->[ PREV ] = undef; - $slot->[ NEXT ] = $head; - $self->{ HEAD } = $slot; - } - - return ($data, $error); -} - - -#------------------------------------------------------------------------ -# _store($name, $data) -# -# Private method called to add a data item to the cache. If the cache -# size limit has been reached then the oldest entry at the tail of the -# list is removed and its slot relocated to the head of the list and -# reused for the new data item. If the cache is under the size limit, -# or if no size limit is defined, then the item is added to the head -# of the list. -#------------------------------------------------------------------------ - -sub _store { - my ($self, $name, $data, $compfile) = @_; - my $size = $self->{ SIZE }; - my ($slot, $head); - - # extract the load time and compiled template from the data -# my $load = $data->{ load }; - my $load = (stat($name))[9]; - $data = $data->{ data }; - - $self->debug("_store($name, $data)") if $self->{ DEBUG }; - - if (defined $size && $self->{ SLOTS } >= $size) { - # cache has reached size limit, so reuse oldest entry - - $self->debug("reusing oldest cache entry (size limit reached: $size)\nslots: $self->{ SLOTS }") if $self->{ DEBUG }; - - # remove entry from tail of list - $slot = $self->{ TAIL }; - $slot->[ PREV ]->[ NEXT ] = undef; - $self->{ TAIL } = $slot->[ PREV ]; - - # remove name lookup for old node - delete $self->{ LOOKUP }->{ $slot->[ NAME ] }; - - # add modified node to head of list - $head = $self->{ HEAD }; - $head->[ PREV ] = $slot if $head; - @$slot = ( undef, $name, $data, $load, $head, time ); - $self->{ HEAD } = $slot; - - # add name lookup for new node - $self->{ LOOKUP }->{ $name } = $slot; - } - else { - # cache is under size limit, or none is defined - - $self->debug("adding new cache entry") if $self->{ DEBUG }; - - # add new node to head of list - $head = $self->{ HEAD }; - $slot = [ undef, $name, $data, $load, $head, time ]; - $head->[ PREV ] = $slot if $head; - $self->{ HEAD } = $slot; - $self->{ TAIL } = $slot unless $self->{ TAIL }; - - # add lookup from name to slot and increment nslots - $self->{ LOOKUP }->{ $name } = $slot; - $self->{ SLOTS }++; - } - - return $data; -} - - -#------------------------------------------------------------------------ -# _compile($data) -# -# Private method called to parse the template text and compile it into -# a runtime form. Creates and delegates a Template::Parser object to -# handle the compilation, or uses a reference passed in PARSER. On -# success, the compiled template is stored in the 'data' item of the -# $data hash and returned. On error, ($error, STATUS_ERROR) is returned, -# or (undef, STATUS_DECLINED) if the TOLERANT flag is set. -# The optional $compiled parameter may be passed to specify -# the name of a compiled template file to which the generated Perl -# code should be written. Errors are (for now...) silently -# ignored, assuming that failures to open a file for writing are -# intentional (e.g directory write permission). -#------------------------------------------------------------------------ - -sub _compile { - my ($self, $data, $compfile) = @_; - my $text = $data->{ text }; - my ($parsedoc, $error); - - $self->debug("_compile($data, ", - defined $compfile ? $compfile : '<no compfile>', ')') - if $self->{ DEBUG }; - - my $parser = $self->{ PARSER } - ||= Template::Config->parser($self->{ PARAMS }) - || return (Template::Config->error(), Template::Constants::STATUS_ERROR); - - # discard the template text - we don't need it any more - delete $data->{ text }; - - # call parser to compile template into Perl code - if ($parsedoc = $parser->parse($text, $data)) { - - $parsedoc->{ METADATA } = { - 'name' => $data->{ name }, - 'modtime' => $data->{ time }, - %{ $parsedoc->{ METADATA } }, - }; - - # write the Perl code to the file $compfile, if defined - if ($compfile) { - my $basedir = &File::Basename::dirname($compfile); - $basedir =~ /(.*)/; - $basedir = $1; - &File::Path::mkpath($basedir) unless -d $basedir; - - my $docclass = $self->{ DOCUMENT }; - $error = 'cache failed to write ' - . &File::Basename::basename($compfile) - . ': ' . $docclass->error() - unless $docclass->write_perl_file($compfile, $parsedoc); - - # set atime and mtime of newly compiled file, don't bother - # if time is undef - if (!defined($error) && defined $data->{ time }) { - my ($cfile) = $compfile =~ /^(.+)$/s or do { - return("invalid filename: $compfile", - Template::Constants::STATUS_ERROR); - }; - - my ($ctime) = $data->{ time } =~ /^(\d+)$/; - unless ($ctime || $ctime eq 0) { - return("invalid time: $ctime", - Template::Constants::STATUS_ERROR); - } - utime($ctime, $ctime, $cfile); - } - } - - unless ($error) { - return $data ## RETURN ## - if $data->{ data } = $DOCUMENT->new($parsedoc); - $error = $Template::Document::ERROR; - } - } - else { - $error = Template::Exception->new( 'parse', "$data->{ name } " . - $parser->error() ); - } - - # return STATUS_ERROR, or STATUS_DECLINED if we're being tolerant - return $self->{ TOLERANT } - ? (undef, Template::Constants::STATUS_DECLINED) - : ($error, Template::Constants::STATUS_ERROR) -} - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which returns a string representing the internal object -# state. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $size = $self->{ SIZE }; - my $parser = $self->{ PARSER }; - $parser = $parser ? $parser->_dump() : '<no parser>'; - $parser =~ s/\n/\n /gm; - $size = 'unlimited' unless defined $size; - - my $output = "[Template::Provider] {\n"; - my $format = " %-16s => %s\n"; - my $key; - - $output .= sprintf($format, 'INCLUDE_PATH', - '[ ' . join(', ', @{ $self->{ INCLUDE_PATH } }) . ' ]'); - $output .= sprintf($format, 'CACHE_SIZE', $size); - - foreach $key (qw( ABSOLUTE RELATIVE TOLERANT DELIMITER - COMPILE_EXT COMPILE_DIR )) { - $output .= sprintf($format, $key, $self->{ $key }); - } - $output .= sprintf($format, 'PARSER', $parser); - - - local $" = ', '; - my $lookup = $self->{ LOOKUP }; - $lookup = join('', map { - sprintf(" $format", $_, defined $lookup->{ $_ } - ? ('[ ' . join(', ', map { defined $_ ? $_ : '<undef>' } - @{ $lookup->{ $_ } }) . ' ]') : '<undef>'); - } sort keys %$lookup); - $lookup = "{\n$lookup }"; - - $output .= sprintf($format, LOOKUP => $lookup); - - $output .= '}'; - return $output; -} - - -#------------------------------------------------------------------------ -# _dump_cache() -# -# Debug method which prints the current state of the cache to STDERR. -#------------------------------------------------------------------------ - -sub _dump_cache { - my $self = shift; - my ($node, $lut, $count); - - $count = 0; - if ($node = $self->{ HEAD }) { - while ($node) { - $lut->{ $node } = $count++; - $node = $node->[ NEXT ]; - } - $node = $self->{ HEAD }; - print STDERR "CACHE STATE:\n"; - print STDERR " HEAD: ", $self->{ HEAD }->[ NAME ], "\n"; - print STDERR " TAIL: ", $self->{ TAIL }->[ NAME ], "\n"; - while ($node) { - my ($prev, $name, $data, $load, $next) = @$node; -# $name = '...' . substr($name, -10) if length $name > 10; - $prev = $prev ? "#$lut->{ $prev }<-": '<undef>'; - $next = $next ? "->#$lut->{ $next }": '<undef>'; - print STDERR " #$lut->{ $node } : [ $prev, $name, $data, $load, $next ]\n"; - $node = $node->[ NEXT ]; - } - } -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Provider - Provider module for loading/compiling templates - -=head1 SYNOPSIS - - $provider = Template::Provider->new(\%options); - - ($template, $error) = $provider->fetch($name); - -=head1 DESCRIPTION - -The Template::Provider is used to load, parse, compile and cache template -documents. This object may be sub-classed to provide more specific -facilities for loading, or otherwise providing access to templates. - -The Template::Context objects maintain a list of Template::Provider -objects which are polled in turn (via fetch()) to return a requested -template. Each may return a compiled template, raise an error, or -decline to serve the reqest, giving subsequent providers a chance to -do so. - -This is the "Chain of Responsiblity" pattern. See 'Design Patterns' for -further information. - -This documentation needs work. - -=head1 PUBLIC METHODS - -=head2 new(\%options) - -Constructor method which instantiates and returns a new Template::Provider -object. The optional parameter may be a hash reference containing any of -the following items: - -=over 4 - - - - -=item INCLUDE_PATH - -The INCLUDE_PATH is used to specify one or more directories in which -template files are located. When a template is requested that isn't -defined locally as a BLOCK, each of the INCLUDE_PATH directories is -searched in turn to locate the template file. Multiple directories -can be specified as a reference to a list or as a single string where -each directory is delimited by ':'. - - my $provider = Template::Provider->new({ - INCLUDE_PATH => '/usr/local/templates', - }); - - my $provider = Template::Provider->new({ - INCLUDE_PATH => '/usr/local/templates:/tmp/my/templates', - }); - - my $provider = Template::Provider->new({ - INCLUDE_PATH => [ '/usr/local/templates', - '/tmp/my/templates' ], - }); - -On Win32 systems, a little extra magic is invoked, ignoring delimiters -that have ':' followed by a '/' or '\'. This avoids confusion when using -directory names like 'C:\Blah Blah'. - -When specified as a list, the INCLUDE_PATH path can contain elements -which dynamically generate a list of INCLUDE_PATH directories. These -generator elements can be specified as a reference to a subroutine or -an object which implements a paths() method. - - my $provider = Template::Provider->new({ - INCLUDE_PATH => [ '/usr/local/templates', - \&incpath_generator, - My::IncPath::Generator->new( ... ) ], - }); - -Each time a template is requested and the INCLUDE_PATH examined, the -subroutine or object method will be called. A reference to a list of -directories should be returned. Generator subroutines should report -errors using die(). Generator objects should return undef and make an -error available via its error() method. - -For example: - - sub incpath_generator { - - # ...some code... - - if ($all_is_well) { - return \@list_of_directories; - } - else { - die "cannot generate INCLUDE_PATH...\n"; - } - } - -or: - - package My::IncPath::Generator; - - # Template::Base (or Class::Base) provides error() method - use Template::Base; - use base qw( Template::Base ); - - sub paths { - my $self = shift; - - # ...some code... - - if ($all_is_well) { - return \@list_of_directories; - } - else { - return $self->error("cannot generate INCLUDE_PATH...\n"); - } - } - - 1; - - - - - -=item DELIMITER - -Used to provide an alternative delimiter character sequence for -separating paths specified in the INCLUDE_PATH. The default -value for DELIMITER is ':'. - - # tolerate Silly Billy's file system conventions - my $provider = Template::Provider->new({ - DELIMITER => '; ', - INCLUDE_PATH => 'C:/HERE/NOW; D:/THERE/THEN', - }); - - # better solution: install Linux! :-) - -On Win32 systems, the default delimiter is a little more intelligent, -splitting paths only on ':' characters that aren't followed by a '/'. -This means that the following should work as planned, splitting the -INCLUDE_PATH into 2 separate directories, C:/foo and C:/bar. - - # on Win32 only - my $provider = Template::Provider->new({ - INCLUDE_PATH => 'C:/Foo:C:/Bar' - }); - -However, if you're using Win32 then it's recommended that you -explicitly set the DELIMITER character to something else (e.g. ';') -rather than rely on this subtle magic. - - - - -=item ABSOLUTE - -The ABSOLUTE flag is used to indicate if templates specified with -absolute filenames (e.g. '/foo/bar') should be processed. It is -disabled by default and any attempt to load a template by such a -name will cause a 'file' exception to be raised. - - my $provider = Template::Provider->new({ - ABSOLUTE => 1, - }); - - # this is why it's disabled by default - [% INSERT /etc/passwd %] - -On Win32 systems, the regular expression for matching absolute -pathnames is tweaked slightly to also detect filenames that start -with a driver letter and colon, such as: - - C:/Foo/Bar - - - - - - -=item RELATIVE - -The RELATIVE flag is used to indicate if templates specified with -filenames relative to the current directory (e.g. './foo/bar' or -'../../some/where/else') should be loaded. It is also disabled by -default, and will raise a 'file' error if such template names are -encountered. - - my $provider = Template::Provider->new({ - RELATIVE => 1, - }); - - [% INCLUDE ../logs/error.log %] - - - - - -=item DEFAULT - -The DEFAULT option can be used to specify a default template which should -be used whenever a specified template can't be found in the INCLUDE_PATH. - - my $provider = Template::Provider->new({ - DEFAULT => 'notfound.html', - }); - -If a non-existant template is requested through the Template process() -method, or by an INCLUDE, PROCESS or WRAPPER directive, then the -DEFAULT template will instead be processed, if defined. Note that the -DEFAULT template is not used when templates are specified with -absolute or relative filenames, or as a reference to a input file -handle or text string. - - - - - -=item CACHE_SIZE - -The Template::Provider module caches compiled templates to avoid the need -to re-parse template files or blocks each time they are used. The CACHE_SIZE -option is used to limit the number of compiled templates that the module -should cache. - -By default, the CACHE_SIZE is undefined and all compiled templates are -cached. When set to any positive value, the cache will be limited to -storing no more than that number of compiled templates. When a new -template is loaded and compiled and the cache is full (i.e. the number -of entries == CACHE_SIZE), the least recently used compiled template -is discarded to make room for the new one. - -The CACHE_SIZE can be set to 0 to disable caching altogether. - - my $provider = Template::Provider->new({ - CACHE_SIZE => 64, # only cache 64 compiled templates - }); - - my $provider = Template::Provider->new({ - CACHE_SIZE => 0, # don't cache any compiled templates - }); - - - - - - -=item COMPILE_EXT - -From version 2 onwards, the Template Toolkit has the ability to -compile templates to Perl code and save them to disk for subsequent -use (i.e. cache persistence). The COMPILE_EXT option may be -provided to specify a filename extension for compiled template files. -It is undefined by default and no attempt will be made to read or write -any compiled template files. - - my $provider = Template::Provider->new({ - COMPILE_EXT => '.ttc', - }); - -If COMPILE_EXT is defined (and COMPILE_DIR isn't, see below) then compiled -template files with the COMPILE_EXT extension will be written to the same -directory from which the source template files were loaded. - -Compiling and subsequent reuse of templates happens automatically -whenever the COMPILE_EXT or COMPILE_DIR options are set. The Template -Toolkit will automatically reload and reuse compiled files when it -finds them on disk. If the corresponding source file has been modified -since the compiled version as written, then it will load and re-compile -the source and write a new compiled version to disk. - -This form of cache persistence offers significant benefits in terms of -time and resources required to reload templates. Compiled templates can -be reloaded by a simple call to Perl's require(), leaving Perl to handle -all the parsing and compilation. This is a Good Thing. - -=item COMPILE_DIR - -The COMPILE_DIR option is used to specify an alternate directory root -under which compiled template files should be saved. - - my $provider = Template::Provider->new({ - COMPILE_DIR => '/tmp/ttc', - }); - -The COMPILE_EXT option may also be specified to have a consistent file -extension added to these files. - - my $provider1 = Template::Provider->new({ - COMPILE_DIR => '/tmp/ttc', - COMPILE_EXT => '.ttc1', - }); - - my $provider2 = Template::Provider->new({ - COMPILE_DIR => '/tmp/ttc', - COMPILE_EXT => '.ttc2', - }); - - -When COMPILE_EXT is undefined, the compiled template files have the -same name as the original template files, but reside in a different -directory tree. - -Each directory in the INCLUDE_PATH is replicated in full beneath the -COMPILE_DIR directory. This example: - - my $provider = Template::Provider->new({ - COMPILE_DIR => '/tmp/ttc', - INCLUDE_PATH => '/home/abw/templates:/usr/share/templates', - }); - -would create the following directory structure: - - /tmp/ttc/home/abw/templates/ - /tmp/ttc/usr/share/templates/ - -Files loaded from different INCLUDE_PATH directories will have their -compiled forms save in the relevant COMPILE_DIR directory. - -On Win32 platforms a filename may by prefixed by a drive letter and -colon. e.g. - - C:/My Templates/header - -The colon will be silently stripped from the filename when it is added -to the COMPILE_DIR value(s) to prevent illegal filename being generated. -Any colon in COMPILE_DIR elements will be left intact. For example: - - # Win32 only - my $provider = Template::Provider->new({ - DELIMITER => ';', - COMPILE_DIR => 'C:/TT2/Cache', - INCLUDE_PATH => 'C:/TT2/Templates;D:/My Templates', - }); - -This would create the following cache directories: - - C:/TT2/Cache/C/TT2/Templates - C:/TT2/Cache/D/My Templates - - - - -=item TOLERANT - -The TOLERANT flag is used by the various Template Toolkit provider -modules (Template::Provider, Template::Plugins, Template::Filters) to -control their behaviour when errors are encountered. By default, any -errors are reported as such, with the request for the particular -resource (template, plugin, filter) being denied and an exception -raised. When the TOLERANT flag is set to any true values, errors will -be silently ignored and the provider will instead return -STATUS_DECLINED. This allows a subsequent provider to take -responsibility for providing the resource, rather than failing the -request outright. If all providers decline to service the request, -either through tolerated failure or a genuine disinclination to -comply, then a 'E<lt>resourceE<gt> not found' exception is raised. - - - - - - -=item PARSER - -The Template::Parser module implements a parser object for compiling -templates into Perl code which can then be executed. A default object -of this class is created automatically and then used by the -Template::Provider whenever a template is loaded and requires -compilation. The PARSER option can be used to provide a reference to -an alternate parser object. - - my $provider = Template::Provider->new({ - PARSER => MyOrg::Template::Parser->new({ ... }), - }); - - - -=item DEBUG - -The DEBUG option can be used to enable debugging messages from the -Template::Provider module by setting it to include the DEBUG_PROVIDER -value. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_PROVIDER, - }); - - - -=back - -=head2 fetch($name) - -Returns a compiled template for the name specified. If the template -cannot be found then (undef, STATUS_DECLINED) is returned. If an error -occurs (e.g. read error, parse error) then ($error, STATUS_ERROR) is -returned, where $error is the error message generated. If the TOLERANT -flag is set the the method returns (undef, STATUS_DECLINED) instead of -returning an error. - -=head2 store($name, $template) - -Stores the compiled template, $template, in the cache under the name, -$name. Susbequent calls to fetch($name) will return this template in -preference to any disk-based file. - -=head2 include_path(\@newpath)) - -Accessor method for the INCLUDE_PATH setting. If called with an -argument, this method will replace the existing INCLUDE_PATH with -the new value. - -=head2 paths() - -This method generates a copy of the INCLUDE_PATH list. Any elements in the -list which are dynamic generators (e.g. references to subroutines or objects -implementing a paths() method) will be called and the list of directories -returned merged into the output list. - -It is possible to provide a generator which returns itself, thus sending -this method into an infinite loop. To detect and prevent this from happening, -the C<$MAX_DIRS> package variable, set to 64 by default, limits the maximum -number of paths that can be added to, or generated for the output list. If -this number is exceeded then the method will immediately return an error -reporting as much. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.79, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Parser|Template::Parser>, L<Template::Context|Template::Context> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Service.pm b/lib/Template/Service.pm deleted file mode 100644 index fb5590a..0000000 --- a/lib/Template/Service.pm +++ /dev/null @@ -1,775 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Service -# -# DESCRIPTION -# Module implementing a template processing service which wraps a -# template within PRE_PROCESS and POST_PROCESS templates and offers -# ERROR recovery. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Service.pm,v 2.75 2004/01/13 16:19:16 abw Exp $ -# -#============================================================================ - -package Template::Service; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $ERROR ); -use base qw( Template::Base ); -use Template::Base; -use Template::Config; -use Template::Exception; -use Template::Constants; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.75 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; - - -#======================================================================== -# ----- PUBLIC METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# process($template, \%params) -# -# Process a template within a service framework. A service may encompass -# PRE_PROCESS and POST_PROCESS templates and an ERROR hash which names -# templates to be substituted for the main template document in case of -# error. Each service invocation begins by resetting the state of the -# context object via a call to reset(). The AUTO_RESET option may be set -# to 0 (default: 1) to bypass this step. -#------------------------------------------------------------------------ - -sub process { - my ($self, $template, $params) = @_; - my $context = $self->{ CONTEXT }; - my ($name, $output, $procout, $error); - $output = ''; - - $self->debug("process($template, ", - defined $params ? $params : '<no params>', - ')') if $self->{ DEBUG }; - - $context->reset() - if $self->{ AUTO_RESET }; - - # pre-request compiled template from context so that we can alias it - # in the stash for pre-processed templates to reference - eval { $template = $context->template($template) }; - return $self->error($@) - if $@; - - # localise the variable stash with any parameters passed - # and set the 'template' variable - $params ||= { }; - $params->{ template } = $template - unless ref $template eq 'CODE'; - $context->localise($params); - - SERVICE: { - # PRE_PROCESS - eval { - foreach $name (@{ $self->{ PRE_PROCESS } }) { - $self->debug("PRE_PROCESS: $name") if $self->{ DEBUG }; - $output .= $context->process($name); - } - }; - last SERVICE if ($error = $@); - - # PROCESS - eval { - foreach $name (@{ $self->{ PROCESS } || [ $template ] }) { - $self->debug("PROCESS: $name") if $self->{ DEBUG }; - $procout .= $context->process($name); - } - }; - if ($error = $@) { - last SERVICE - unless defined ($procout = $self->_recover(\$error)); - } - - if (defined $procout) { - # WRAPPER - eval { - foreach $name (reverse @{ $self->{ WRAPPER } }) { - $self->debug("WRAPPER: $name") if $self->{ DEBUG }; - $procout = $context->process($name, { content => $procout }); - } - }; - last SERVICE if ($error = $@); - $output .= $procout; - } - - # POST_PROCESS - eval { - foreach $name (@{ $self->{ POST_PROCESS } }) { - $self->debug("POST_PROCESS: $name") if $self->{ DEBUG }; - $output .= $context->process($name); - } - }; - last SERVICE if ($error = $@); - } - - $context->delocalise(); - delete $params->{ template }; - - if ($error) { -# $error = $error->as_string if ref $error; - return $self->error($error); - } - - return $output; -} - - -#------------------------------------------------------------------------ -# context() -# -# Returns the internal CONTEXT reference. -#------------------------------------------------------------------------ - -sub context { - return $_[0]->{ CONTEXT }; -} - - -#======================================================================== -# -- PRIVATE METHODS -- -#======================================================================== - -sub _init { - my ($self, $config) = @_; - my ($item, $data, $context, $block, $blocks); - my $delim = $config->{ DELIMITER }; - $delim = ':' unless defined $delim; - - # coerce PRE_PROCESS, PROCESS and POST_PROCESS to arrays if necessary, - # by splitting on non-word characters - foreach $item (qw( PRE_PROCESS PROCESS POST_PROCESS WRAPPER )) { - $data = $config->{ $item }; - $self->{ $item } = [ ], next unless (defined $data); - $data = [ split($delim, $data || '') ] - unless ref $data eq 'ARRAY'; - $self->{ $item } = $data; - } - # unset PROCESS option unless explicitly specified in config - $self->{ PROCESS } = undef - unless defined $config->{ PROCESS }; - - $self->{ ERROR } = $config->{ ERROR } || $config->{ ERRORS }; - $self->{ AUTO_RESET } = defined $config->{ AUTO_RESET } - ? $config->{ AUTO_RESET } : 1; - $self->{ DEBUG } = ( $config->{ DEBUG } || 0 ) - & Template::Constants::DEBUG_SERVICE; - - $context = $self->{ CONTEXT } = $config->{ CONTEXT } - || Template::Config->context($config) - || return $self->error(Template::Config->error); - - return $self; -} - - -#------------------------------------------------------------------------ -# _recover(\$exception) -# -# Examines the internal ERROR hash array to find a handler suitable -# for the exception object passed by reference. Selecting the handler -# is done by delegation to the exception's select_handler() method, -# passing the set of handler keys as arguments. A 'default' handler -# may also be provided. The handler value represents the name of a -# template which should be processed. -#------------------------------------------------------------------------ - -sub _recover { - my ($self, $error) = @_; - my $context = $self->{ CONTEXT }; - my ($hkey, $handler, $output); - - # there shouldn't ever be a non-exception object received at this - # point... unless a module like CGI::Carp messes around with the - # DIE handler. - return undef - unless (ref $$error); - - # a 'stop' exception is thrown by [% STOP %] - we return the output - # buffer stored in the exception object - return $$error->text() - if $$error->type() eq 'stop'; - - my $handlers = $self->{ ERROR } - || return undef; ## RETURN - - if (ref $handlers eq 'HASH') { - if ($hkey = $$error->select_handler(keys %$handlers)) { - $handler = $handlers->{ $hkey }; - $self->debug("using error handler for $hkey") if $self->{ DEBUG }; - } - elsif ($handler = $handlers->{ default }) { - # use default handler - $self->debug("using default error handler") if $self->{ DEBUG }; - } - else { - return undef; ## RETURN - } - } - else { - $handler = $handlers; - $self->debug("using default error handler") if $self->{ DEBUG }; - } - - eval { $handler = $context->template($handler) }; - if ($@) { - $$error = $@; - return undef; ## RETURN - }; - - $context->stash->set('error', $$error); - eval { - $output .= $context->process($handler); - }; - if ($@) { - $$error = $@; - return undef; ## RETURN - } - - return $output; -} - - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which return a string representing the internal object -# state. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $context = $self->{ CONTEXT }->_dump(); - $context =~ s/\n/\n /gm; - - my $error = $self->{ ERROR }; - $error = join('', - "{\n", - (map { " $_ => $error->{ $_ }\n" } - keys %$error), - "}\n") - if ref $error; - - local $" = ', '; - return <<EOF; -$self -PRE_PROCESS => [ @{ $self->{ PRE_PROCESS } } ] -POST_PROCESS => [ @{ $self->{ POST_PROCESS } } ] -ERROR => $error -CONTEXT => $context -EOF -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Service - General purpose template processing service - -=head1 SYNOPSIS - - use Template::Service; - - my $service = Template::Service->new({ - PRE_PROCESS => [ 'config', 'header' ], - POST_PROCESS => 'footer', - ERROR => { - user => 'user/index.html', - dbi => 'error/database', - default => 'error/default', - }, - }); - - my $output = $service->process($template_name, \%replace) - || die $service->error(), "\n"; - -=head1 DESCRIPTION - -The Template::Service module implements an object class for providing -a consistent template processing service. - -Standard header (PRE_PROCESS) and footer (POST_PROCESS) templates may -be specified which are prepended and appended to all templates -processed by the service (but not any other templates or blocks -INCLUDEd or PROCESSed from within). An ERROR hash may be specified -which redirects the service to an alternate template file in the case -of uncaught exceptions being thrown. This allows errors to be -automatically handled by the service and a guaranteed valid response -to be generated regardless of any processing problems encountered. - -A default Template::Service object is created by the Template module. -Any Template::Service options may be passed to the Template new() -constructor method and will be forwarded to the Template::Service -constructor. - - use Template; - - my $template = Template->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - }); - -Similarly, the Template::Service constructor will forward all configuration -parameters onto other default objects (e.g. Template::Context) that it may -need to instantiate. - -A Template::Service object (or subclass/derivative) can be explicitly -instantiated and passed to the Template new() constructor method as -the SERVICE item. - - use Template; - use Template::Service; - - my $service = Template::Service->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - }); - - my $template = Template->new({ - SERVICE => $service, - }); - -The Template::Service module can be sub-classed to create custom service -handlers. - - use Template; - use MyOrg::Template::Service; - - my $service = MyOrg::Template::Service->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - COOL_OPTION => 'enabled in spades', - }); - - my $template = Template->new({ - SERVICE => $service, - }); - -The Template module uses the Template::Config service() factory method -to create a default service object when required. The -$Template::Config::SERVICE package variable may be set to specify an -alternate service module. This will be loaded automatically and its -new() constructor method called by the service() factory method when -a default service object is required. Thus the previous example could -be written as: - - use Template; - - $Template::Config::SERVICE = 'MyOrg::Template::Service'; - - my $template = Template->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - COOL_OPTION => 'enabled in spades', - }); - -=head1 METHODS - -=head2 new(\%config) - -The new() constructor method is called to instantiate a Template::Service -object. Configuration parameters may be specified as a HASH reference or -as a list of (name =E<gt> value) pairs. - - my $service1 = Template::Service->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - }); - - my $service2 = Template::Service->new( ERROR => 'error.html' ); - -The new() method returns a Template::Service object (or sub-class) or -undef on error. In the latter case, a relevant error message can be -retrieved by the error() class method or directly from the -$Template::Service::ERROR package variable. - - my $service = Template::Service->new(\%config) - || die Template::Service->error(); - - my $service = Template::Service->new(\%config) - || die $Template::Service::ERROR; - -The following configuration items may be specified: - -=over 4 - - - - -=item PRE_PROCESS, POST_PROCESS - -These values may be set to contain the name(s) of template files -(relative to INCLUDE_PATH) which should be processed immediately -before and/or after each template. These do not get added to -templates processed into a document via directives such as INCLUDE, -PROCESS, WRAPPER etc. - - my $service = Template::Service->new({ - PRE_PROCESS => 'header', - POST_PROCESS => 'footer', - }; - -Multiple templates may be specified as a reference to a list. Each is -processed in the order defined. - - my $service = Template::Service->new({ - PRE_PROCESS => [ 'config', 'header' ], - POST_PROCESS => 'footer', - }; - -Alternately, multiple template may be specified as a single string, -delimited by ':'. This delimiter string can be changed via the -DELIMITER option. - - my $service = Template::Service->new({ - PRE_PROCESS => 'config:header', - POST_PROCESS => 'footer', - }; - -The PRE_PROCESS and POST_PROCESS templates are evaluated in the same -variable context as the main document and may define or update -variables for subsequent use. - -config: - - [% # set some site-wide variables - bgcolor = '#ffffff' - version = 2.718 - %] - -header: - - [% DEFAULT title = 'My Funky Web Site' %] - <html> - <head> - <title>[% title %]</title> - </head> - <body bgcolor="[% bgcolor %]"> - -footer: - - <hr> - Version [% version %] - </body> - </html> - -The Template::Document object representing the main template being processed -is available within PRE_PROCESS and POST_PROCESS templates as the 'template' -variable. Metadata items defined via the META directive may be accessed -accordingly. - - $service->process('mydoc.html', $vars); - -mydoc.html: - - [% META title = 'My Document Title' %] - blah blah blah - ... - -header: - - <html> - <head> - <title>[% template.title %]</title></head> - <body bgcolor="[% bgcolor %]"> - - - - - - - - - - - - - - -=item PROCESS - -The PROCESS option may be set to contain the name(s) of template files -(relative to INCLUDE_PATH) which should be processed instead of the -main template passed to the Template::Service process() method. This can -be used to apply consistent wrappers around all templates, similar to -the use of PRE_PROCESS and POST_PROCESS templates. - - my $service = Template::Service->new({ - PROCESS => 'content', - }; - - # processes 'content' instead of 'foo.html' - $service->process('foo.html'); - -A reference to the original template is available in the 'template' -variable. Metadata items can be inspected and the template can be -processed by specifying it as a variable reference (i.e. prefixed by -'$') to an INCLUDE, PROCESS or WRAPPER directive. - -content: - - <html> - <head> - <title>[% template.title %]</title> - </head> - - <body> - [% PROCESS $template %] - <hr> - © Copyright [% template.copyright %] - </body> - </html> - -foo.html: - - [% META - title = 'The Foo Page' - author = 'Fred Foo' - copyright = '2000 Fred Foo' - %] - <h1>[% template.title %]</h1> - Welcome to the Foo Page, blah blah blah - -output: - - <html> - <head> - <title>The Foo Page</title> - </head> - - <body> - <h1>The Foo Page</h1> - Welcome to the Foo Page, blah blah blah - <hr> - © Copyright 2000 Fred Foo - </body> - </html> - - - - - - - -=item ERROR - -The ERROR (or ERRORS if you prefer) configuration item can be used to -name a single template or specify a hash array mapping exception types -to templates which should be used for error handling. If an uncaught -exception is raised from within a template then the appropriate error -template will instead be processed. - -If specified as a single value then that template will be processed -for all uncaught exceptions. - - my $service = Template::Service->new({ - ERROR => 'error.html' - }); - -If the ERROR item is a hash reference the keys are assumed to be -exception types and the relevant template for a given exception will -be selected. A 'default' template may be provided for the general -case. Note that 'ERROR' can be pluralised to 'ERRORS' if you find -it more appropriate in this case. - - my $service = Template::Service->new({ - ERRORS => { - user => 'user/index.html', - dbi => 'error/database', - default => 'error/default', - }, - }); - -In this example, any 'user' exceptions thrown will cause the -'user/index.html' template to be processed, 'dbi' errors are handled -by 'error/database' and all others by the 'error/default' template. -Any PRE_PROCESS and/or POST_PROCESS templates will also be applied -to these error templates. - -Note that exception types are hierarchical and a 'foo' handler will -catch all 'foo.*' errors (e.g. foo.bar, foo.bar.baz) if a more -specific handler isn't defined. Be sure to quote any exception types -that contain periods to prevent Perl concatenating them into a single -string (i.e. C<user.passwd> is parsed as 'user'.'passwd'). - - my $service = Template::Service->new({ - ERROR => { - 'user.login' => 'user/login.html', - 'user.passwd' => 'user/badpasswd.html', - 'user' => 'user/index.html', - 'default' => 'error/default', - }, - }); - -In this example, any template processed by the $service object, or -other templates or code called from within, can raise a 'user.login' -exception and have the service redirect to the 'user/login.html' -template. Similarly, a 'user.passwd' exception has a specific -handling template, 'user/badpasswd.html', while all other 'user' or -'user.*' exceptions cause a redirection to the 'user/index.html' page. -All other exception types are handled by 'error/default'. - - -Exceptions can be raised in a template using the THROW directive, - - [% THROW user.login 'no user id: please login' %] - -or by calling the throw() method on the current Template::Context object, - - $context->throw('user.passwd', 'Incorrect Password'); - $context->throw('Incorrect Password'); # type 'undef' - -or from Perl code by calling die() with a Template::Exception object, - - die (Template::Exception->new('user.denied', 'Invalid User ID')); - -or by simply calling die() with an error string. This is -automagically caught and converted to an exception of 'undef' -type which can then be handled in the usual way. - - die "I'm sorry Dave, I can't do that"; - - - - - - - -=item AUTO_RESET - -The AUTO_RESET option is set by default and causes the local BLOCKS -cache for the Template::Context object to be reset on each call to the -Template process() method. This ensures that any BLOCKs defined -within a template will only persist until that template is finished -processing. This prevents BLOCKs defined in one processing request -from interfering with other independent requests subsequently -processed by the same context object. - -The BLOCKS item may be used to specify a default set of block definitions -for the Template::Context object. Subsequent BLOCK definitions in templates -will over-ride these but they will be reinstated on each reset if AUTO_RESET -is enabled (default), or if the Template::Context reset() method is called. - - - - - - - -=item DEBUG - -The DEBUG option can be used to enable debugging messages from the -Template::Service module by setting it to include the DEBUG_SERVICE -value. - - use Template::Constants qw( :debug ); - - my $template = Template->new({ - DEBUG => DEBUG_SERVICE, - }); - - - - -=back - -=head2 process($input, \%replace) - -The process() method is called to process a template specified as the first -parameter, $input. This may be a file name, file handle (e.g. GLOB or IO::Handle) -or a reference to a text string containing the template text. An additional -hash reference may be passed containing template variable definitions. - -The method processes the template, adding any PRE_PROCESS or POST_PROCESS -templates defined, and returns the output text. An uncaught exception thrown -by the template will be handled by a relevant ERROR handler if defined. -Errors that occur in the PRE_PROCESS or POST_PROCESS templates, or those that -occur in the main input template and aren't handled, cause the method to -return undef to indicate failure. The appropriate error message can be -retrieved via the error() method. - - $service->process('myfile.html', { title => 'My Test File' }) - || die $service->error(); - - -=head2 context() - -Returns a reference to the internal context object which is, by default, an -instance of the Template::Context class. - -=head2 error() - -Returns the most recent error message. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.79, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Context|Template::Context> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Stash.pm b/lib/Template/Stash.pm deleted file mode 100644 index 64553fe..0000000 --- a/lib/Template/Stash.pm +++ /dev/null @@ -1,1040 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Stash -# -# DESCRIPTION -# Definition of an object class which stores and manages access to -# variables for the Template Toolkit. -# -# AUTHOR -# Andy Wardley <abw@wardley.org> -# -# COPYRIGHT -# Copyright (C) 1996-2003 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Stash.pm,v 2.85 2004/01/30 17:51:01 abw Exp $ -# -#============================================================================ - -package Template::Stash; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $ROOT_OPS $SCALAR_OPS $HASH_OPS $LIST_OPS ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.85 $ =~ /(\d+)\.(\d+)/); - - -#======================================================================== -# -- PACKAGE VARIABLES AND SUBS -- -#======================================================================== - -#------------------------------------------------------------------------ -# Definitions of various pseudo-methods. ROOT_OPS are merged into all -# new Template::Stash objects, and are thus default global functions. -# SCALAR_OPS are methods that can be called on a scalar, and ditto -# respectively for LIST_OPS and HASH_OPS -#------------------------------------------------------------------------ - -$ROOT_OPS = { - 'inc' => sub { local $^W = 0; my $item = shift; ++$item }, - 'dec' => sub { local $^W = 0; my $item = shift; --$item }, -# import => \&hash_import, - defined $ROOT_OPS ? %$ROOT_OPS : (), -}; - -$SCALAR_OPS = { - 'item' => sub { $_[0] }, - 'list' => sub { [ $_[0] ] }, - 'hash' => sub { { value => $_[0] } }, - 'length' => sub { length $_[0] }, - 'size' => sub { return 1 }, - 'defined' => sub { return 1 }, - 'repeat' => sub { - my ($str, $count) = @_; - $str = '' unless defined $str; - return '' unless $count; - $count ||= 1; - return $str x $count; - }, - 'search' => sub { - my ($str, $pattern) = @_; - return $str unless defined $str and defined $pattern; - return $str =~ /$pattern/; - }, - 'replace' => sub { - my ($str, $search, $replace) = @_; - $replace = '' unless defined $replace; - return $str unless defined $str and defined $search; - $str =~ s/$search/$replace/g; -# print STDERR "s [ $search ] [ $replace ] g\n"; -# eval "\$str =~ s$search$replaceg"; - return $str; - }, - 'match' => sub { - my ($str, $search) = @_; - return $str unless defined $str and defined $search; - my @matches = ($str =~ /$search/); - return @matches ? \@matches : ''; - }, - 'split' => sub { - my ($str, $split, @args) = @_; - $str = '' unless defined $str; - return [ defined $split ? split($split, $str, @args) - : split(' ', $str, @args) ]; - }, - 'chunk' => sub { - my ($string, $size) = @_; - my @list; - $size ||= 1; - if ($size < 0) { - # sexeger! It's faster to reverse the string, search - # it from the front and then reverse the output than to - # search it from the end, believe it nor not! - $string = reverse $string; - $size = -$size; - unshift(@list, scalar reverse $1) - while ($string =~ /((.{$size})|(.+))/g); - } - else { - push(@list, $1) while ($string =~ /((.{$size})|(.+))/g); - } - return \@list; - }, - - - defined $SCALAR_OPS ? %$SCALAR_OPS : (), -}; - -$HASH_OPS = { - 'item' => sub { - my ($hash, $item) = @_; - $item = '' unless defined $item; - return if $item =~ /^[_.]/; - $hash->{ $item }; - }, - 'hash' => sub { $_[0] }, - 'size' => sub { scalar keys %{$_[0]} }, - 'keys' => sub { [ keys %{ $_[0] } ] }, - 'values' => sub { [ values %{ $_[0] } ] }, - 'each' => sub { [ %{ $_[0] } ] }, - 'list' => sub { - my ($hash, $what) = @_; $what ||= ''; - return ($what eq 'keys') ? [ keys %$hash ] - : ($what eq 'values') ? [ values %$hash ] - : ($what eq 'each') ? [ %$hash ] - : [ map { { key => $_ , value => $hash->{ $_ } } } - keys %$hash ]; - }, - 'exists' => sub { exists $_[0]->{ $_[1] } }, - 'defined' => sub { defined $_[0]->{ $_[1] } }, - 'import' => \&hash_import, - 'sort' => sub { - my ($hash) = @_; - [ sort { lc $hash->{$a} cmp lc $hash->{$b} } (keys %$hash) ]; - }, - 'nsort' => sub { - my ($hash) = @_; - [ sort { $hash->{$a} <=> $hash->{$b} } (keys %$hash) ]; - }, - defined $HASH_OPS ? %$HASH_OPS : (), -}; - -$LIST_OPS = { - 'item' => sub { $_[0]->[ $_[1] || 0 ] }, - 'list' => sub { $_[0] }, - 'hash' => sub { my $list = shift; my $n = 0; - return { map { ($n++, $_) } @$list }; }, - 'push' => sub { my $list = shift; push(@$list, shift); return '' }, - 'pop' => sub { my $list = shift; pop(@$list) }, - 'unshift' => sub { my $list = shift; unshift(@$list, shift); return '' }, - 'shift' => sub { my $list = shift; shift(@$list) }, - 'max' => sub { local $^W = 0; my $list = shift; $#$list; }, - 'size' => sub { local $^W = 0; my $list = shift; $#$list + 1; }, - 'first' => sub { - my $list = shift; - return $list->[0] unless @_; - return [ @$list[0..$_[0]-1] ]; - }, - 'last' => sub { - my $list = shift; - return $list->[-1] unless @_; - return [ @$list[-$_[0]..-1] ]; - }, - 'reverse' => sub { my $list = shift; [ reverse @$list ] }, - 'grep' => sub { - my ($list, $pattern) = @_; - $pattern ||= ''; - return [ grep /$pattern/, @$list ]; - }, - 'join' => sub { - my ($list, $joint) = @_; - join(defined $joint ? $joint : ' ', - map { defined $_ ? $_ : '' } @$list) - }, - 'sort' => sub { - $^W = 0; - my ($list, $field) = @_; - return $list unless @$list > 1; # no need to sort 1 item lists - return $field # Schwartzian Transform - ? map { $_->[0] } # for case insensitivity - sort { $a->[1] cmp $b->[1] } - map { [ $_, lc(ref($_) eq 'HASH' - ? $_->{ $field } : - UNIVERSAL::can($_, $field) - ? $_->$field() : $_) ] } - @$list - : map { $_->[0] } - sort { $a->[1] cmp $b->[1] } - map { [ $_, lc $_ ] } - @$list - }, - 'nsort' => sub { - my ($list, $field) = @_; - return $list unless $#$list; # no need to sort 1 item lists - return $field # Schwartzian Transform - ? map { $_->[0] } # for case insensitivity - sort { $a->[1] <=> $b->[1] } - map { [ $_, lc(ref($_) eq 'HASH' - ? $_->{ $field } : - UNIVERSAL::can($_, $field) - ? $_->$field() : $_) ] } - @$list - : map { $_->[0] } - sort { $a->[1] <=> $b->[1] } - map { [ $_, lc $_ ] } - @$list - }, - 'unique' => sub { my %u; [ grep { ++$u{$_} == 1 } @{$_[0]} ] }, - 'merge' => sub { - my $list = shift; - return [ @$list, grep defined, map ref eq 'ARRAY' ? @$_ : undef, @_ ]; - }, - 'slice' => sub { - my ($list, $from, $to) = @_; - $from ||= 0; - $to = $#$list unless defined $to; - return [ @$list[$from..$to] ]; - }, - 'splice' => sub { - my ($list, $offset, $length, @replace) = @_; - if (@replace) { - # @replace can contain a list of multiple replace items, or - # be a single reference to a list - @replace = @{ $replace[0] } - if @replace == 1 && ref $replace[0] eq 'ARRAY'; - return [ splice @$list, $offset, $length, @replace ]; - } - elsif (defined $length) { - return [ splice @$list, $offset, $length ]; - } - elsif (defined $offset) { - return [ splice @$list, $offset ]; - } - else { - return [ splice(@$list) ]; - } - }, - - defined $LIST_OPS ? %$LIST_OPS : (), -}; - -sub hash_import { - my ($hash, $imp) = @_; - $imp = {} unless ref $imp eq 'HASH'; - @$hash{ keys %$imp } = values %$imp; - return ''; -} - - -#------------------------------------------------------------------------ -# define_vmethod($type, $name, \&sub) -# -# Defines a virtual method of type $type (SCALAR, HASH, or LIST), with -# name $name, that invokes &sub when called. It is expected that &sub -# be able to handle the type that it will be called upon. -#------------------------------------------------------------------------ - -sub define_vmethod { - my ($class, $type, $name, $sub) = @_; - my $op; - $type = lc $type; - - if ($type =~ /^scalar|item$/) { - $op = $SCALAR_OPS; - } - elsif ($type eq 'hash') { - $op = $HASH_OPS; - } - elsif ($type =~ /^list|array$/) { - $op = $LIST_OPS; - } - else { - die "invalid vmethod type: $type\n"; - } - - $op->{ $name } = $sub; - - return 1; -} - - -#======================================================================== -# ----- CLASS METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# new(\%params) -# -# Constructor method which creates a new Template::Stash object. -# An optional hash reference may be passed containing variable -# definitions that will be used to initialise the stash. -# -# Returns a reference to a newly created Template::Stash. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $params = ref $_[0] eq 'HASH' ? shift(@_) : { @_ }; - - my $self = { - global => { }, - %$params, - %$ROOT_OPS, - '_PARENT' => undef, - }; - - bless $self, $class; -} - - -#======================================================================== -# ----- PUBLIC OBJECT METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# clone(\%params) -# -# Creates a copy of the current stash object to effect localisation -# of variables. The new stash is blessed into the same class as the -# parent (which may be a derived class) and has a '_PARENT' member added -# which contains a reference to the parent stash that created it -# ($self). This member is used in a successive declone() method call to -# return the reference to the parent. -# -# A parameter may be provided which should reference a hash of -# variable/values which should be defined in the new stash. The -# update() method is called to define these new variables in the cloned -# stash. -# -# Returns a reference to a cloned Template::Stash. -#------------------------------------------------------------------------ - -sub clone { - my ($self, $params) = @_; - $params ||= { }; - - # look out for magical 'import' argument which imports another hash - my $import = $params->{ import }; - if (defined $import && UNIVERSAL::isa($import, 'HASH')) { - delete $params->{ import }; - } - else { - undef $import; - } - - my $clone = bless { - %$self, # copy all parent members - %$params, # copy all new data - '_PARENT' => $self, # link to parent - }, ref $self; - - # perform hash import if defined - &{ $HASH_OPS->{ import }}($clone, $import) - if defined $import; - - return $clone; -} - - -#------------------------------------------------------------------------ -# declone($export) -# -# Returns a reference to the PARENT stash. When called in the following -# manner: -# $stash = $stash->declone(); -# the reference count on the current stash will drop to 0 and be "freed" -# and the caller will be left with a reference to the parent. This -# contains the state of the stash before it was cloned. -#------------------------------------------------------------------------ - -sub declone { - my $self = shift; - $self->{ _PARENT } || $self; -} - - -#------------------------------------------------------------------------ -# get($ident) -# -# Returns the value for an variable stored in the stash. The variable -# may be specified as a simple string, e.g. 'foo', or as an array -# reference representing compound variables. In the latter case, each -# pair of successive elements in the list represent a node in the -# compound variable. The first is the variable name, the second a -# list reference of arguments or 0 if undefined. So, the compound -# variable [% foo.bar('foo').baz %] would be represented as the list -# [ 'foo', 0, 'bar', ['foo'], 'baz', 0 ]. Returns the value of the -# identifier or an empty string if undefined. Errors are thrown via -# die(). -#------------------------------------------------------------------------ - -sub get { - my ($self, $ident, $args) = @_; - my ($root, $result); - $root = $self; - - if (ref $ident eq 'ARRAY' - || ($ident =~ /\./) - && ($ident = [ map { s/\(.*$//; ($_, 0) } split(/\./, $ident) ])) { - my $size = $#$ident; - - # if $ident is a list reference, then we evaluate each item in the - # identifier against the previous result, using the root stash - # ($self) as the first implicit 'result'... - - foreach (my $i = 0; $i <= $size; $i += 2) { - $result = $self->_dotop($root, @$ident[$i, $i+1]); - last unless defined $result; - $root = $result; - } - } - else { - $result = $self->_dotop($root, $ident, $args); - } - - return defined $result ? $result : $self->undefined($ident, $args); -} - - -#------------------------------------------------------------------------ -# set($ident, $value, $default) -# -# Updates the value for a variable in the stash. The first parameter -# should be the variable name or array, as per get(). The second -# parameter should be the intended value for the variable. The third, -# optional parameter is a flag which may be set to indicate 'default' -# mode. When set true, the variable will only be updated if it is -# currently undefined or has a false value. The magical 'IMPORT' -# variable identifier may be used to indicate that $value is a hash -# reference whose values should be imported. Returns the value set, -# or an empty string if not set (e.g. default mode). In the case of -# IMPORT, returns the number of items imported from the hash. -#------------------------------------------------------------------------ - -sub set { - my ($self, $ident, $value, $default) = @_; - my ($root, $result, $error); - - $root = $self; - - ELEMENT: { - if (ref $ident eq 'ARRAY' - || ($ident =~ /\./) - && ($ident = [ map { s/\(.*$//; ($_, 0) } - split(/\./, $ident) ])) { - - # a compound identifier may contain multiple elements (e.g. - # foo.bar.baz) and we must first resolve all but the last, - # using _dotop() with the $lvalue flag set which will create - # intermediate hashes if necessary... - my $size = $#$ident; - foreach (my $i = 0; $i < $size - 2; $i += 2) { - $result = $self->_dotop($root, @$ident[$i, $i+1], 1); - last ELEMENT unless defined $result; - $root = $result; - } - - # then we call _assign() to assign the value to the last element - $result = $self->_assign($root, @$ident[$size-1, $size], - $value, $default); - } - else { - $result = $self->_assign($root, $ident, 0, $value, $default); - } - } - - return defined $result ? $result : ''; -} - - -#------------------------------------------------------------------------ -# getref($ident) -# -# Returns a "reference" to a particular item. This is represented as a -# closure which will return the actual stash item when called. -# WARNING: still experimental! -#------------------------------------------------------------------------ - -sub getref { - my ($self, $ident, $args) = @_; - my ($root, $item, $result); - $root = $self; - - if (ref $ident eq 'ARRAY') { - my $size = $#$ident; - - foreach (my $i = 0; $i <= $size; $i += 2) { - ($item, $args) = @$ident[$i, $i + 1]; - last if $i >= $size - 2; # don't evaluate last node - last unless defined - ($root = $self->_dotop($root, $item, $args)); - } - } - else { - $item = $ident; - } - - if (defined $root) { - return sub { my @args = (@{$args||[]}, @_); - $self->_dotop($root, $item, \@args); - } - } - else { - return sub { '' }; - } -} - - - - -#------------------------------------------------------------------------ -# update(\%params) -# -# Update multiple variables en masse. No magic is performed. Simple -# variable names only. -#------------------------------------------------------------------------ - -sub update { - my ($self, $params) = @_; - - # look out for magical 'import' argument to import another hash - my $import = $params->{ import }; - if (defined $import && UNIVERSAL::isa($import, 'HASH')) { - @$self{ keys %$import } = values %$import; - delete $params->{ import }; - } - - @$self{ keys %$params } = values %$params; -} - - -#------------------------------------------------------------------------ -# undefined($ident, $args) -# -# Method called when a get() returns an undefined value. Can be redefined -# in a subclass to implement alternate handling. -#------------------------------------------------------------------------ - -sub undefined { - my ($self, $ident, $args); - return ''; -} - - -#======================================================================== -# ----- PRIVATE OBJECT METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# _dotop($root, $item, \@args, $lvalue) -# -# This is the core 'dot' operation method which evaluates elements of -# variables against their root. All variables have an implicit root -# which is the stash object itself (a hash). Thus, a non-compound -# variable 'foo' is actually '(stash.)foo', the compound 'foo.bar' is -# '(stash.)foo.bar'. The first parameter is a reference to the current -# root, initially the stash itself. The second parameter contains the -# name of the variable element, e.g. 'foo'. The third optional -# parameter is a reference to a list of any parenthesised arguments -# specified for the variable, which are passed to sub-routines, object -# methods, etc. The final parameter is an optional flag to indicate -# if this variable is being evaluated on the left side of an assignment -# (e.g. foo.bar.baz = 10). When set true, intermediated hashes will -# be created (e.g. bar) if necessary. -# -# Returns the result of evaluating the item against the root, having -# performed any variable "magic". The value returned can then be used -# as the root of the next _dotop() in a compound sequence. Returns -# undef if the variable is undefined. -#------------------------------------------------------------------------ - -sub _dotop { - my ($self, $root, $item, $args, $lvalue) = @_; - my $rootref = ref $root; - my $atroot = ($root eq $self); - my ($value, @result); - - $args ||= [ ]; - $lvalue ||= 0; - -# print STDERR "_dotop(root=$root, item=$item, args=[@$args])\n" -# if $DEBUG; - - # return undef without an error if either side of the dot is unviable - # or if an attempt is made to access a private member, starting _ or . - return undef - unless defined($root) and defined($item) and $item !~ /^[\._]/; - - if ($atroot || $rootref eq 'HASH') { - # if $root is a regular HASH or a Template::Stash kinda HASH (the - # *real* root of everything). We first lookup the named key - # in the hash, or create an empty hash in its place if undefined - # and the $lvalue flag is set. Otherwise, we check the HASH_OPS - # pseudo-methods table, calling the code if found, or return undef. - - if (defined($value = $root->{ $item })) { - return $value unless ref $value eq 'CODE'; ## RETURN - @result = &$value(@$args); ## @result - } - elsif ($lvalue) { - # we create an intermediate hash if this is an lvalue - return $root->{ $item } = { }; ## RETURN - } - # ugly hack: only allow import vmeth to be called on root stash - elsif (($value = $HASH_OPS->{ $item }) - && ! $atroot || $item eq 'import') { - @result = &$value($root, @$args); ## @result - } - elsif ( ref $item eq 'ARRAY' ) { - # hash slice - return [@$root{@$item}]; ## RETURN - } - } - elsif ($rootref eq 'ARRAY') { - # if root is an ARRAY then we check for a LIST_OPS pseudo-method - # (except for l-values for which it doesn't make any sense) - # or return the numerical index into the array, or undef - - if (($value = $LIST_OPS->{ $item }) && ! $lvalue) { - @result = &$value($root, @$args); ## @result - } - elsif ($item =~ /^-?\d+$/) { - $value = $root->[$item]; - return $value unless ref $value eq 'CODE'; ## RETURN - @result = &$value(@$args); ## @result - } - elsif ( ref $item eq 'ARRAY' ) { - # array slice - return [@$root[@$item]]; ## RETURN - } - } - - # NOTE: we do the can-can because UNIVSERAL::isa($something, 'UNIVERSAL') - # doesn't appear to work with CGI, returning true for the first call - # and false for all subsequent calls. - - elsif (ref($root) && UNIVERSAL::can($root, 'can')) { - - # if $root is a blessed reference (i.e. inherits from the - # UNIVERSAL object base class) then we call the item as a method. - # If that fails then we try to fallback on HASH behaviour if - # possible. - eval { @result = $root->$item(@$args); }; - - if ($@) { - # temporary hack - required to propogate errors thrown - # by views; if $@ is a ref (e.g. Template::Exception - # object then we assume it's a real error that needs - # real throwing - - die $@ if ref($@) || ($@ !~ /Can't locate object method/); - - # failed to call object method, so try some fallbacks -# patch from Stephen Howard -# -- remove from here... -- - if (UNIVERSAL::isa($root, 'HASH') - && defined($value = $root->{ $item })) { - return $value unless ref $value eq 'CODE'; ## RETURN - @result = &$value(@$args); - } -# -- and replace with this... -- -# if (UNIVERSAL::isa($root, 'HASH') ) { -# if( defined($value = $root->{ $item })) { -# return $value unless ref $value eq 'CODE'; ## RETURN -# @result = &$value(@$args); -# } -# elsif ($value = $HASH_OPS->{ $item }) { -# @result = &$value($root, @$args); -# } -# } -# -- remove from here... -- - elsif (UNIVERSAL::isa($root, 'ARRAY') - && ($value = $LIST_OPS->{ $item })) { - @result = &$value($root, @$args); - } -# -- and replace with this... -- -# elsif (UNIVERSAL::isa($root, 'ARRAY') ) { -# if( $value = $LIST_OPS->{ $item }) { -# @result = &$value($root, @$args); -# } -# elsif( $item =~ /^-?\d+$/ ) { -# $value = $root->[$item]; -# return $value unless ref $value eq 'CODE'; ## RETURN -# @result = &$value(@$args); ## @result -# } -# elsif ( ref $item eq 'ARRAY' ) { -# # array slice -# return [@$root[@$item]]; ## RETURN -# } -# } -# -- end -- - elsif ($value = $SCALAR_OPS->{ $item }) { - @result = &$value($root, @$args); - } - elsif ($value = $LIST_OPS->{ $item }) { - @result = &$value([$root], @$args); - } - elsif ($self->{ _DEBUG }) { - @result = (undef, $@); - } - } - } - elsif (($value = $SCALAR_OPS->{ $item }) && ! $lvalue) { - # at this point, it doesn't look like we've got a reference to - # anything we know about, so we try the SCALAR_OPS pseudo-methods - # table (but not for l-values) - @result = &$value($root, @$args); ## @result - } - elsif (($value = $LIST_OPS->{ $item }) && ! $lvalue) { - # last-ditch: can we promote a scalar to a one-element - # list and apply a LIST_OPS virtual method? - @result = &$value([$root], @$args); - } - elsif ($self->{ _DEBUG }) { - die "don't know how to access [ $root ].$item\n"; ## DIE - } - else { - @result = (); - } - - # fold multiple return items into a list unless first item is undef - if (defined $result[0]) { - return ## RETURN - scalar @result > 1 ? [ @result ] : $result[0]; - } - elsif (defined $result[1]) { - die $result[1]; ## DIE - } - elsif ($self->{ _DEBUG }) { - die "$item is undefined\n"; ## DIE - } - - return undef; -} - - -#------------------------------------------------------------------------ -# _assign($root, $item, \@args, $value, $default) -# -# Similar to _dotop() above, but assigns a value to the given variable -# instead of simply returning it. The first three parameters are the -# root item, the item and arguments, as per _dotop(), followed by the -# value to which the variable should be set and an optional $default -# flag. If set true, the variable will only be set if currently false -# (undefined/zero) -#------------------------------------------------------------------------ - -sub _assign { - my ($self, $root, $item, $args, $value, $default) = @_; - my $rootref = ref $root; - my $atroot = ($root eq $self); - my $result; - $args ||= [ ]; - $default ||= 0; - -# print(STDERR "_assign(root=$root, item=$item, args=[@$args], \n", -# "value=$value, default=$default)\n") -# if $DEBUG; - - # return undef without an error if either side of the dot is unviable - # or if an attempt is made to update a private member, starting _ or . - return undef ## RETURN - unless $root and defined $item and $item !~ /^[\._]/; - - if ($rootref eq 'HASH' || $atroot) { -# if ($item eq 'IMPORT' && UNIVERSAL::isa($value, 'HASH')) { -# # import hash entries into root hash -# @$root{ keys %$value } = values %$value; -# return ''; ## RETURN -# } - # if the root is a hash we set the named key - return ($root->{ $item } = $value) ## RETURN - unless $default && $root->{ $item }; - } - elsif ($rootref eq 'ARRAY' && $item =~ /^-?\d+$/) { - # or set a list item by index number - return ($root->[$item] = $value) ## RETURN - unless $default && $root->{ $item }; - } - elsif (UNIVERSAL::isa($root, 'UNIVERSAL')) { - # try to call the item as a method of an object - - return $root->$item(@$args, $value) ## RETURN - unless $default && $root->$item(); - -# 2 issues: -# - method call should be wrapped in eval { } -# - fallback on hash methods if object method not found -# -# eval { $result = $root->$item(@$args, $value); }; -# -# if ($@) { -# die $@ if ref($@) || ($@ !~ /Can't locate object method/); -# -# # failed to call object method, so try some fallbacks -# if (UNIVERSAL::isa($root, 'HASH') && exists $root->{ $item }) { -# $result = ($root->{ $item } = $value) -# unless $default && $root->{ $item }; -# } -# } -# return $result; ## RETURN - - } - else { - die "don't know how to assign to [$root].[$item]\n"; ## DIE - } - - return undef; -} - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which returns a string representing the internal state -# of the object. The method calls itself recursively to dump sub-hashes. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - return "[Template::Stash] " . $self->_dump_frame(2); -} - -sub _dump_frame { - my ($self, $indent) = @_; - $indent ||= 1; - my $buffer = ' '; - my $pad = $buffer x $indent; - my $text = "{\n"; - local $" = ', '; - - my ($key, $value); - - return $text . "...excessive recursion, terminating\n" - if $indent > 32; - - foreach $key (keys %$self) { - $value = $self->{ $key }; - $value = '<undef>' unless defined $value; - next if $key =~ /^\./; - if (ref($value) eq 'ARRAY') { - $value = '[ ' . join(', ', map { defined $_ ? $_ : '<undef>' } - @$value) . ' ]'; - } - elsif (ref $value eq 'HASH') { - $value = _dump_frame($value, $indent + 1); - } - - $text .= sprintf("$pad%-16s => $value\n", $key); - } - $text .= $buffer x ($indent - 1) . '}'; - return $text; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Stash - Magical storage for template variables - -=head1 SYNOPSIS - - use Template::Stash; - - my $stash = Template::Stash->new(\%vars); - - # get variable values - $value = $stash->get($variable); - $value = $stash->get(\@compound); - - # set variable value - $stash->set($variable, $value); - $stash->set(\@compound, $value); - - # default variable value - $stash->set($variable, $value, 1); - $stash->set(\@compound, $value, 1); - - # set variable values en masse - $stash->update(\%new_vars) - - # methods for (de-)localising variables - $stash = $stash->clone(\%new_vars); - $stash = $stash->declone(); - -=head1 DESCRIPTION - -The Template::Stash module defines an object class which is used to store -variable values for the runtime use of the template processor. Variable -values are stored internally in a hash reference (which itself is blessed -to create the object) and are accessible via the get() and set() methods. - -Variables may reference hash arrays, lists, subroutines and objects -as well as simple values. The stash automatically performs the right -magic when dealing with variables, calling code or object methods, -indexing into lists, hashes, etc. - -The stash has clone() and declone() methods which are used by the -template processor to make temporary copies of the stash for -localising changes made to variables. - -=head1 PUBLIC METHODS - -=head2 new(\%params) - -The new() constructor method creates and returns a reference to a new -Template::Stash object. - - my $stash = Template::Stash->new(); - -A hash reference may be passed to provide variables and values which -should be used to initialise the stash. - - my $stash = Template::Stash->new({ var1 => 'value1', - var2 => 'value2' }); - -=head2 get($variable) - -The get() method retrieves the variable named by the first parameter. - - $value = $stash->get('var1'); - -Dotted compound variables can be retrieved by specifying the variable -elements by reference to a list. Each node in the variable occupies -two entries in the list. The first gives the name of the variable -element, the second is a reference to a list of arguments for that -element, or 0 if none. - - [% foo.bar(10).baz(20) %] - - $stash->get([ 'foo', 0, 'bar', [ 10 ], 'baz', [ 20 ] ]); - -=head2 set($variable, $value, $default) - -The set() method sets the variable name in the first parameter to the -value specified in the second. - - $stash->set('var1', 'value1'); - -If the third parameter evaluates to a true value, the variable is -set only if it did not have a true value before. - - $stash->set('var2', 'default_value', 1); - -Dotted compound variables may be specified as per get() above. - - [% foo.bar = 30 %] - - $stash->set([ 'foo', 0, 'bar', 0 ], 30); - -The magical variable 'IMPORT' can be specified whose corresponding -value should be a hash reference. The contents of the hash array are -copied (i.e. imported) into the current namespace. - - # foo.bar = baz, foo.wiz = waz - $stash->set('foo', { 'bar' => 'baz', 'wiz' => 'waz' }); - - # import 'foo' into main namespace: foo = baz, wiz = waz - $stash->set('IMPORT', $stash->get('foo')); - -=head2 clone(\%params) - -The clone() method creates and returns a new Template::Stash object which -represents a localised copy of the parent stash. Variables can be -freely updated in the cloned stash and when declone() is called, the -original stash is returned with all its members intact and in the -same state as they were before clone() was called. - -For convenience, a hash of parameters may be passed into clone() which -is used to update any simple variable (i.e. those that don't contain any -namespace elements like 'foo' and 'bar' but not 'foo.bar') variables while -cloning the stash. For adding and updating complex variables, the set() -method should be used after calling clone(). This will correctly resolve -and/or create any necessary namespace hashes. - -A cloned stash maintains a reference to the stash that it was copied -from in its '_PARENT' member. - -=head2 declone() - -The declone() method returns the '_PARENT' reference and can be used to -restore the state of a stash as described above. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.85, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template>, L<Template::Context|Template::Context> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Stash/Context.pm b/lib/Template/Stash/Context.pm deleted file mode 100644 index 975dc79..0000000 --- a/lib/Template/Stash/Context.pm +++ /dev/null @@ -1,791 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Stash::Context -# -# DESCRIPTION -# This is an alternate stash object which includes a patch from -# Craig Barratt to implement various new virtual methods to allow -# dotted template variable to denote if object methods and subroutines -# should be called in scalar or list context. It adds a little overhead -# to each stash call and I'm a little wary of doing that. So for now, -# it's implemented as a separate stash module which will allow us to -# test it out, benchmark it and switch it in or out as we require. -# -# This is what Craig has to say about it: -# -# Here's a better set of features for the core. Attached is a new version -# of Stash.pm (based on TT2.02) that: -# -# - supports the special op "scalar" that forces scalar context on -# function calls, eg: -# -# cgi.param("foo").scalar -# -# calls cgi.param("foo") in scalar context (unlike my wimpy -# scalar op from last night). Array context is the default. -# -# With non-function operands, scalar behaves like the perl -# version (eg: no-op for scalar, size for arrays, etc). -# -# - supports the special op "ref" that behaves like the perl ref. -# If applied to a function the function is not called. Eg: -# -# cgi.param("foo").ref -# -# does *not* call cgi.param and evaluates to "CODE". Similarly, -# HASH.ref, ARRAY.ref return what you expect. -# -# - adds a new scalar and list op called "array" that is a no-op for -# arrays and promotes scalars to one-element arrays. -# -# - allows scalar ops to be applied to arrays and hashes in place, -# eg: ARRAY.repeat(3) repeats each element in place. -# -# - allows list ops to be applied to scalars by promoting the scalars -# to one-element arrays (like an implicit "array"). So you can -# do things like SCALAR.size, SCALAR.join and get a useful result. -# -# This also means you can now use x.0 to safely get the first element -# whether x is an array or scalar. -# -# The new Stash.pm passes the TT2.02 test suite. But I haven't tested the -# new features very much. One nagging implementation problem is that the -# "scalar" and "ref" ops have higher precedence than user variable names. -# -# AUTHORS -# Andy Wardley <abw@kfs.org> -# Craig Barratt <craig@arraycomm.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Context.pm,v 1.58 2004/01/13 16:21:52 abw Exp $ -# -#============================================================================ - -package Template::Stash::Context; - -require 5.004; - -use strict; -use Template::Stash; -use vars qw( $VERSION $DEBUG $ROOT_OPS $SCALAR_OPS $HASH_OPS $LIST_OPS ); - -$VERSION = sprintf("%d.%02d", q$Revision: 1.58 $ =~ /(\d+)\.(\d+)/); - - -#======================================================================== -# -- PACKAGE VARIABLES AND SUBS -- -#======================================================================== - -#------------------------------------------------------------------------ -# copy virtual methods from those in the regular Template::Stash -#------------------------------------------------------------------------ - -$ROOT_OPS = { - %$Template::Stash::ROOT_OPS, - defined $ROOT_OPS ? %$ROOT_OPS : (), -}; - -$SCALAR_OPS = { - %$Template::Stash::SCALAR_OPS, - 'array' => sub { return [$_[0]] }, - defined $SCALAR_OPS ? %$SCALAR_OPS : (), -}; - -$LIST_OPS = { - %$Template::Stash::LIST_OPS, - 'array' => sub { return $_[0] }, - defined $LIST_OPS ? %$LIST_OPS : (), -}; - -$HASH_OPS = { - %$Template::Stash::HASH_OPS, - defined $HASH_OPS ? %$HASH_OPS : (), -}; - - - -#======================================================================== -# ----- CLASS METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# new(\%params) -# -# Constructor method which creates a new Template::Stash object. -# An optional hash reference may be passed containing variable -# definitions that will be used to initialise the stash. -# -# Returns a reference to a newly created Template::Stash. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $params = ref $_[0] eq 'HASH' ? shift(@_) : { @_ }; - - my $self = { - global => { }, - %$params, - %$ROOT_OPS, - '_PARENT' => undef, - }; - - bless $self, $class; -} - - -#======================================================================== -# ----- PUBLIC OBJECT METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# clone(\%params) -# -# Creates a copy of the current stash object to effect localisation -# of variables. The new stash is blessed into the same class as the -# parent (which may be a derived class) and has a '_PARENT' member added -# which contains a reference to the parent stash that created it -# ($self). This member is used in a successive declone() method call to -# return the reference to the parent. -# -# A parameter may be provided which should reference a hash of -# variable/values which should be defined in the new stash. The -# update() method is called to define these new variables in the cloned -# stash. -# -# Returns a reference to a cloned Template::Stash. -#------------------------------------------------------------------------ - -sub clone { - my ($self, $params) = @_; - $params ||= { }; - - # look out for magical 'import' argument which imports another hash - my $import = $params->{ import }; - if (defined $import && UNIVERSAL::isa($import, 'HASH')) { - delete $params->{ import }; - } - else { - undef $import; - } - - my $clone = bless { - %$self, # copy all parent members - %$params, # copy all new data - '_PARENT' => $self, # link to parent - }, ref $self; - - # perform hash import if defined - &{ $HASH_OPS->{ import }}($clone, $import) - if defined $import; - - return $clone; -} - - -#------------------------------------------------------------------------ -# declone($export) -# -# Returns a reference to the PARENT stash. When called in the following -# manner: -# $stash = $stash->declone(); -# the reference count on the current stash will drop to 0 and be "freed" -# and the caller will be left with a reference to the parent. This -# contains the state of the stash before it was cloned. -#------------------------------------------------------------------------ - -sub declone { - my $self = shift; - $self->{ _PARENT } || $self; -} - - -#------------------------------------------------------------------------ -# get($ident) -# -# Returns the value for an variable stored in the stash. The variable -# may be specified as a simple string, e.g. 'foo', or as an array -# reference representing compound variables. In the latter case, each -# pair of successive elements in the list represent a node in the -# compound variable. The first is the variable name, the second a -# list reference of arguments or 0 if undefined. So, the compound -# variable [% foo.bar('foo').baz %] would be represented as the list -# [ 'foo', 0, 'bar', ['foo'], 'baz', 0 ]. Returns the value of the -# identifier or an empty string if undefined. Errors are thrown via -# die(). -#------------------------------------------------------------------------ - -sub get { - my ($self, $ident, $args) = @_; - my ($root, $result); - $root = $self; - - if (ref $ident eq 'ARRAY' - || ($ident =~ /\./) - && ($ident = [ map { s/\(.*$//; ($_, 0) } split(/\./, $ident) ])) { - my $size = $#$ident; - - # if $ident is a list reference, then we evaluate each item in the - # identifier against the previous result, using the root stash - # ($self) as the first implicit 'result'... - - foreach (my $i = 0; $i <= $size; $i += 2) { - if ( $i + 2 <= $size && ($ident->[$i+2] eq "scalar" - || $ident->[$i+2] eq "ref") ) { - $result = $self->_dotop($root, @$ident[$i, $i+1], 0, - $ident->[$i+2]); - $i += 2; - } else { - $result = $self->_dotop($root, @$ident[$i, $i+1]); - } - last unless defined $result; - $root = $result; - } - } - else { - $result = $self->_dotop($root, $ident, $args); - } - - return defined $result ? $result : ''; -} - - -#------------------------------------------------------------------------ -# set($ident, $value, $default) -# -# Updates the value for a variable in the stash. The first parameter -# should be the variable name or array, as per get(). The second -# parameter should be the intended value for the variable. The third, -# optional parameter is a flag which may be set to indicate 'default' -# mode. When set true, the variable will only be updated if it is -# currently undefined or has a false value. The magical 'IMPORT' -# variable identifier may be used to indicate that $value is a hash -# reference whose values should be imported. Returns the value set, -# or an empty string if not set (e.g. default mode). In the case of -# IMPORT, returns the number of items imported from the hash. -#------------------------------------------------------------------------ - -sub set { - my ($self, $ident, $value, $default) = @_; - my ($root, $result, $error); - - $root = $self; - - ELEMENT: { - if (ref $ident eq 'ARRAY' - || ($ident =~ /\./) - && ($ident = [ map { s/\(.*$//; ($_, 0) } - split(/\./, $ident) ])) { - - # a compound identifier may contain multiple elements (e.g. - # foo.bar.baz) and we must first resolve all but the last, - # using _dotop() with the $lvalue flag set which will create - # intermediate hashes if necessary... - my $size = $#$ident; - foreach (my $i = 0; $i < $size - 2; $i += 2) { - $result = $self->_dotop($root, @$ident[$i, $i+1], 1); - last ELEMENT unless defined $result; - $root = $result; - } - - # then we call _assign() to assign the value to the last element - $result = $self->_assign($root, @$ident[$size-1, $size], - $value, $default); - } - else { - $result = $self->_assign($root, $ident, 0, $value, $default); - } - } - - return defined $result ? $result : ''; -} - - -#------------------------------------------------------------------------ -# getref($ident) -# -# Returns a "reference" to a particular item. This is represented as a -# closure which will return the actual stash item when called. -# WARNING: still experimental! -#------------------------------------------------------------------------ - -sub getref { - my ($self, $ident, $args) = @_; - my ($root, $item, $result); - $root = $self; - - if (ref $ident eq 'ARRAY') { - my $size = $#$ident; - - foreach (my $i = 0; $i <= $size; $i += 2) { - ($item, $args) = @$ident[$i, $i + 1]; - last if $i >= $size - 2; # don't evaluate last node - last unless defined - ($root = $self->_dotop($root, $item, $args)); - } - } - else { - $item = $ident; - } - - if (defined $root) { - return sub { my @args = (@{$args||[]}, @_); - $self->_dotop($root, $item, \@args); - } - } - else { - return sub { '' }; - } -} - - - - -#------------------------------------------------------------------------ -# update(\%params) -# -# Update multiple variables en masse. No magic is performed. Simple -# variable names only. -#------------------------------------------------------------------------ - -sub update { - my ($self, $params) = @_; - - # look out for magical 'import' argument to import another hash - my $import = $params->{ import }; - if (defined $import && UNIVERSAL::isa($import, 'HASH')) { - @$self{ keys %$import } = values %$import; - delete $params->{ import }; - } - - @$self{ keys %$params } = values %$params; -} - - -#======================================================================== -# ----- PRIVATE OBJECT METHODS ----- -#======================================================================== - -#------------------------------------------------------------------------ -# _dotop($root, $item, \@args, $lvalue, $nextItem) -# -# This is the core 'dot' operation method which evaluates elements of -# variables against their root. All variables have an implicit root -# which is the stash object itself (a hash). Thus, a non-compound -# variable 'foo' is actually '(stash.)foo', the compound 'foo.bar' is -# '(stash.)foo.bar'. The first parameter is a reference to the current -# root, initially the stash itself. The second parameter contains the -# name of the variable element, e.g. 'foo'. The third optional -# parameter is a reference to a list of any parenthesised arguments -# specified for the variable, which are passed to sub-routines, object -# methods, etc. The final parameter is an optional flag to indicate -# if this variable is being evaluated on the left side of an assignment -# (e.g. foo.bar.baz = 10). When set true, intermediated hashes will -# be created (e.g. bar) if necessary. -# -# Returns the result of evaluating the item against the root, having -# performed any variable "magic". The value returned can then be used -# as the root of the next _dotop() in a compound sequence. Returns -# undef if the variable is undefined. -#------------------------------------------------------------------------ - -sub _dotop { - my ($self, $root, $item, $args, $lvalue, $nextItem) = @_; - my $rootref = ref $root; - my ($value, @result, $ret, $retVal); - $nextItem ||= ""; - my $scalarContext = 1 if ( $nextItem eq "scalar" ); - my $returnRef = 1 if ( $nextItem eq "ref" ); - - $args ||= [ ]; - $lvalue ||= 0; - -# print STDERR "_dotop(root=$root, item=$item, args=[@$args])\n" -# if $DEBUG; - - # return undef without an error if either side of the dot is unviable - # or if an attempt is made to access a private member, starting _ or . - return undef - unless defined($root) and defined($item) and $item !~ /^[\._]/; - - if (ref(\$root) eq "SCALAR" && !$lvalue && - (($value = $LIST_OPS->{ $item }) || $item =~ /^-?\d+$/) ) { - # - # Promote scalar to one element list, to be processed below. - # - $rootref = 'ARRAY'; - $root = [$root]; - } - if ($rootref eq __PACKAGE__ || $rootref eq 'HASH') { - - # if $root is a regular HASH or a Template::Stash kinda HASH (the - # *real* root of everything). We first lookup the named key - # in the hash, or create an empty hash in its place if undefined - # and the $lvalue flag is set. Otherwise, we check the HASH_OPS - # pseudo-methods table, calling the code if found, or return undef. - - if (defined($value = $root->{ $item })) { - ($ret, $retVal, @result) = _dotop_return($value, $args, $returnRef, - $scalarContext); - return $retVal if ( $ret ); ## RETURN - } - elsif ($lvalue) { - # we create an intermediate hash if this is an lvalue - return $root->{ $item } = { }; ## RETURN - } - elsif ($value = $HASH_OPS->{ $item }) { - @result = &$value($root, @$args); ## @result - } - elsif (ref $item eq 'ARRAY') { - # hash slice - return [@$root{@$item}]; ## RETURN - } - elsif ($value = $SCALAR_OPS->{ $item }) { - # - # Apply scalar ops to every hash element, in place. - # - foreach my $key ( keys %$root ) { - $root->{$key} = &$value($root->{$key}, @$args); - } - } - } - elsif ($rootref eq 'ARRAY') { - - # if root is an ARRAY then we check for a LIST_OPS pseudo-method - # (except for l-values for which it doesn't make any sense) - # or return the numerical index into the array, or undef - - if (($value = $LIST_OPS->{ $item }) && ! $lvalue) { - @result = &$value($root, @$args); ## @result - } - elsif (($value = $SCALAR_OPS->{ $item }) && ! $lvalue) { - # - # Apply scalar ops to every array element, in place. - # - for ( my $i = 0 ; $i < @$root ; $i++ ) { - $root->[$i] = &$value($root->[$i], @$args); ## @result - } - } - elsif ($item =~ /^-?\d+$/) { - $value = $root->[$item]; - ($ret, $retVal, @result) = _dotop_return($value, $args, $returnRef, - $scalarContext); - return $retVal if ( $ret ); ## RETURN - } - elsif (ref $item eq 'ARRAY' ) { - # array slice - return [@$root[@$item]]; ## RETURN - } - } - - # NOTE: we do the can-can because UNIVSERAL::isa($something, 'UNIVERSAL') - # doesn't appear to work with CGI, returning true for the first call - # and false for all subsequent calls. - - elsif (ref($root) && UNIVERSAL::can($root, 'can')) { - - # if $root is a blessed reference (i.e. inherits from the - # UNIVERSAL object base class) then we call the item as a method. - # If that fails then we try to fallback on HASH behaviour if - # possible. - return ref $root->can($item) if ( $returnRef ); ## RETURN - eval { - @result = $scalarContext ? scalar $root->$item(@$args) - : $root->$item(@$args); ## @result - }; - - if ($@) { - # failed to call object method, so try some fallbacks - if (UNIVERSAL::isa($root, 'HASH') - && defined($value = $root->{ $item })) { - ($ret, $retVal, @result) = _dotop_return($value, $args, - $returnRef, $scalarContext); - return $retVal if ( $ret ); ## RETURN - } - elsif (UNIVERSAL::isa($root, 'ARRAY') - && ($value = $LIST_OPS->{ $item })) { - @result = &$value($root, @$args); - } - else { - @result = (undef, $@); - } - } - } - elsif (($value = $SCALAR_OPS->{ $item }) && ! $lvalue) { - - # at this point, it doesn't look like we've got a reference to - # anything we know about, so we try the SCALAR_OPS pseudo-methods - # table (but not for l-values) - - @result = &$value($root, @$args); ## @result - } - elsif ($self->{ _DEBUG }) { - die "don't know how to access [ $root ].$item\n"; ## DIE - } - else { - @result = (); - } - - # fold multiple return items into a list unless first item is undef - if (defined $result[0]) { - return ref(@result > 1 ? [ @result ] : $result[0]) - if ( $returnRef ); ## RETURN - if ( $scalarContext ) { - return scalar @result if ( @result > 1 ); ## RETURN - return scalar(@{$result[0]}) if ( ref $result[0] eq "ARRAY" ); - return scalar(%{$result[0]}) if ( ref $result[0] eq "HASH" ); - return $result[0]; ## RETURN - } else { - return @result > 1 ? [ @result ] : $result[0]; ## RETURN - } - } - elsif (defined $result[1]) { - die $result[1]; ## DIE - } - elsif ($self->{ _DEBUG }) { - die "$item is undefined\n"; ## DIE - } - - return undef; -} - -#------------------------------------------------------------------------ -# ($ret, $retVal, @result) = _dotop_return($value, $args, $returnRef, -# $scalarContext); -# -# Handle the various return processing for _dotop -#------------------------------------------------------------------------ -sub _dotop_return -{ - my($value, $args, $returnRef, $scalarContext) = @_; - my(@result); - - return (1, ref $value) if ( $returnRef ); ## RETURN - if ( $scalarContext ) { - return (1, scalar(@$value)) if ref $value eq 'ARRAY'; ## RETURN - return (1, scalar(%$value)) if ref $value eq 'HASH'; ## RETURN - return (1, scalar($value)) unless ref $value eq 'CODE'; ## RETURN; - @result = scalar &$value(@$args) ## @result; - } else { - return (1, $value) unless ref $value eq 'CODE'; ## RETURN - @result = &$value(@$args); ## @result - } - return (0, undef, @result); -} - - -#------------------------------------------------------------------------ -# _assign($root, $item, \@args, $value, $default) -# -# Similar to _dotop() above, but assigns a value to the given variable -# instead of simply returning it. The first three parameters are the -# root item, the item and arguments, as per _dotop(), followed by the -# value to which the variable should be set and an optional $default -# flag. If set true, the variable will only be set if currently false -# (undefined/zero) -#------------------------------------------------------------------------ - -sub _assign { - my ($self, $root, $item, $args, $value, $default) = @_; - my $rootref = ref $root; - my $result; - $args ||= [ ]; - $default ||= 0; - -# print(STDERR "_assign(root=$root, item=$item, args=[@$args], \n", -# "value=$value, default=$default)\n") -# if $DEBUG; - - # return undef without an error if either side of the dot is unviable - # or if an attempt is made to update a private member, starting _ or . - return undef ## RETURN - unless $root and defined $item and $item !~ /^[\._]/; - - if ($rootref eq 'HASH' || $rootref eq __PACKAGE__) { -# if ($item eq 'IMPORT' && UNIVERSAL::isa($value, 'HASH')) { -# # import hash entries into root hash -# @$root{ keys %$value } = values %$value; -# return ''; ## RETURN -# } - # if the root is a hash we set the named key - return ($root->{ $item } = $value) ## RETURN - unless $default && $root->{ $item }; - } - elsif ($rootref eq 'ARRAY' && $item =~ /^-?\d+$/) { - # or set a list item by index number - return ($root->[$item] = $value) ## RETURN - unless $default && $root->{ $item }; - } - elsif (UNIVERSAL::isa($root, 'UNIVERSAL')) { - # try to call the item as a method of an object - return $root->$item(@$args, $value); ## RETURN - } - else { - die "don't know how to assign to [$root].[$item]\n"; ## DIE - } - - return undef; -} - - -#------------------------------------------------------------------------ -# _dump() -# -# Debug method which returns a string representing the internal state -# of the object. The method calls itself recursively to dump sub-hashes. -#------------------------------------------------------------------------ - -sub _dump { - my $self = shift; - my $indent = shift || 1; - my $buffer = ' '; - my $pad = $buffer x $indent; - my $text = ''; - local $" = ', '; - - my ($key, $value); - - - return $text . "...excessive recursion, terminating\n" - if $indent > 32; - - foreach $key (keys %$self) { - - $value = $self->{ $key }; - $value = '<undef>' unless defined $value; - - if (ref($value) eq 'ARRAY') { - $value = "$value [@$value]"; - } - $text .= sprintf("$pad%-8s => $value\n", $key); - next if $key =~ /^\./; - if (UNIVERSAL::isa($value, 'HASH')) { - $text .= _dump($value, $indent + 1); - } - } - $text; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Stash::Context - Experimetal stash allowing list/scalar context definition - -=head1 SYNOPSIS - - use Template; - use Template::Stash::Context; - - my $stash = Template::Stash::Context->new(\%vars); - my $tt2 = Template->new({ STASH => $stash }); - -=head1 DESCRIPTION - -This is an alternate stash object which includes a patch from -Craig Barratt to implement various new virtual methods to allow -dotted template variable to denote if object methods and subroutines -should be called in scalar or list context. It adds a little overhead -to each stash call and I'm a little wary of applying that to the core -default stash without investigating the effects first. So for now, -it's implemented as a separate stash module which will allow us to -test it out, benchmark it and switch it in or out as we require. - -This is what Craig has to say about it: - -Here's a better set of features for the core. Attached is a new version -of Stash.pm (based on TT2.02) that: - -* supports the special op "scalar" that forces scalar context on -function calls, eg: - - cgi.param("foo").scalar - -calls cgi.param("foo") in scalar context (unlike my wimpy -scalar op from last night). Array context is the default. - -With non-function operands, scalar behaves like the perl -version (eg: no-op for scalar, size for arrays, etc). - -* supports the special op "ref" that behaves like the perl ref. -If applied to a function the function is not called. Eg: - - cgi.param("foo").ref - -does *not* call cgi.param and evaluates to "CODE". Similarly, -HASH.ref, ARRAY.ref return what you expect. - -* adds a new scalar and list op called "array" that is a no-op for -arrays and promotes scalars to one-element arrays. - -* allows scalar ops to be applied to arrays and hashes in place, -eg: ARRAY.repeat(3) repeats each element in place. - -* allows list ops to be applied to scalars by promoting the scalars -to one-element arrays (like an implicit "array"). So you can -do things like SCALAR.size, SCALAR.join and get a useful result. - -This also means you can now use x.0 to safely get the first element -whether x is an array or scalar. - -The new Stash.pm passes the TT2.02 test suite. But I haven't tested the -new features very much. One nagging implementation problem is that the -"scalar" and "ref" ops have higher precedence than user variable names. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -1.58, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template::Stash|Template::Stash> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Stash/XS.pm b/lib/Template/Stash/XS.pm deleted file mode 100644 index 2cfb543..0000000 --- a/lib/Template/Stash/XS.pm +++ /dev/null @@ -1,176 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Stash::XS -# -# DESCRIPTION -# -# Perl bootstrap for XS module. Inherits methods from -# Template::Stash when not implemented in the XS module. -# -#======================================================================== - -package Template::Stash::XS; - -use Template; -use Template::Stash; - -BEGIN { - require DynaLoader; - @Template::Stash::XS::ISA = qw( DynaLoader Template::Stash ); - - eval { - bootstrap Template::Stash::XS $Template::VERSION; - }; - if ($@) { - die "Couldn't load Template::Stash::XS $Template::VERSION:\n\n$@\n"; - } -} - - -sub DESTROY { - # no op - 1; -} - - -# catch missing method calls here so perl doesn't barf -# trying to load *.al files -sub AUTOLOAD { - my ($self, @args) = @_; - my @c = caller(0); - my $auto = $AUTOLOAD; - - $auto =~ s/.*:://; - $self =~ s/=.*//; - - die "Can't locate object method \"$auto\"" . - " via package \"$self\" at $c[1] line $c[2]\n"; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Stash::XS - Experimetal high-speed stash written in XS - -=head1 SYNOPSIS - - use Template; - use Template::Stash::XS; - - my $stash = Template::Stash::XS->new(\%vars); - my $tt2 = Template->new({ STASH => $stash }); - -=head1 DESCRIPTION - -This module loads the XS version of Template::Stash::XS. It should -behave very much like the old one, but run about twice as fast. -See the synopsis above for usage information. - -Only a few methods (such as get and set) have been implemented in XS. -The others are inherited from Template::Stash. - -=head1 NOTE - -To always use the XS version of Stash, modify the Template/Config.pm -module near line 45: - - $STASH = 'Template::Stash::XS'; - -If you make this change, then there is no need to explicitly create -an instance of Template::Stash::XS as seen in the SYNOPSIS above. Just -use Template as normal. - -Alternatively, in your code add this line before creating a Template -object: - - $Template::Config::STASH = 'Template::Stash::XS'; - -To use the original, pure-perl version restore this line in -Template/Config.pm: - - $STASH = 'Template::Stash'; - -Or in your code: - - $Template::Config::STASH = 'Template::Stash'; - -You can elect to have this performed once for you at installation -time by answering 'y' or 'n' to the question that asks if you want -to make the XS Stash the default. - -=head1 BUGS - -Please report bugs to the Template Toolkit mailing list -templates@template-toolkit.org - -As of version 2.05 of the Template Toolkit, use of the XS Stash is -known to have 2 potentially troublesome side effects. The first -problem is that accesses to tied hashes (e.g. Apache::Session) may not -work as expected. This should be fixed in an imminent release. If -you are using tied hashes then it is suggested that you use the -regular Stash by default, or write a thin wrapper around your tied -hashes to enable the XS Stash to access items via regular method -calls. - -The second potential problem is that enabling the XS Stash causes all -the Template Toolkit modules to be installed in an architecture -dependant library, e.g. in - - /usr/lib/perl5/site_perl/5.6.0/i386-linux/Template - -instead of - - /usr/lib/perl5/site_perl/5.6.0/Template - -At the time of writing, we're not sure why this is happening but it's -likely that this is either a bug or intentional feature in the Perl -ExtUtils::MakeMaker module. As far as I know, Perl always checks the -architecture dependant directories before the architecture independant -ones. Therefore, a newer version of the Template Toolkit installed -with the XS Stash enabled should be used by Perl in preference to any -existing version using the regular stash. However, if you install a -future version of the Template Toolkit with the XS Stash disabled, you -may find that Perl continues to use the older version with XS Stash -enabled in preference. - -=head1 AUTHORS - -Andy Wardley E<lt>abw@tt2.orgE<gt> - -Doug Steinwand E<lt>dsteinwand@citysearch.comE<gt> - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=head1 SEE ALSO - -L<Template::Stash|Template::Stash> - diff --git a/lib/Template/Test.pm b/lib/Template/Test.pm deleted file mode 100644 index 9413d68..0000000 --- a/lib/Template/Test.pm +++ /dev/null @@ -1,711 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Test -# -# DESCRIPTION -# Module defining a test harness which processes template input and -# then compares the output against pre-define expected output. -# Generates test output compatible with Test::Harness. This was -# originally the t/texpect.pl script. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# 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. -# -#---------------------------------------------------------------------------- -# -# $Id: Test.pm,v 2.69 2004/01/13 16:19:16 abw Exp $ -# -#============================================================================ - -package Template::Test; - -require 5.004; - -use strict; -use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS - $VERSION $DEBUG $EXTRA $PRESERVE $REASON $NO_FLUSH - $loaded %callsign); -use Template qw( :template ); -use Exporter; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.69 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0; -@ISA = qw( Exporter ); -@EXPORT = qw( ntests ok is match flush skip_all test_expect callsign banner ); -@EXPORT_OK = ( 'assert' ); -%EXPORT_TAGS = ( all => [ @EXPORT_OK, @EXPORT ] ); -$| = 1; - -$REASON = 'not applicable on this platform'; -$NO_FLUSH = 0; -$EXTRA = 0; # any extra tests to come after test_expect() -$PRESERVE = 0 # don't mangle newlines in output/expect - unless defined $PRESERVE; - -# always set binmode on Win32 machines so that any output generated -# is true to what we expect -$Template::BINMODE = ($^O eq 'MSWin32') ? 1 : 0; - -my @results = (); -my ($ntests, $ok_count); -*is = \&match; - -END { - # ensure flush() is called to print any cached results - flush(); -} - - -#------------------------------------------------------------------------ -# ntests($n) -# -# Declare how many (more) tests are expected to come. If ok() is called -# before ntests() then the results are cached instead of being printed -# to STDOUT. When ntests() is called, the total number of tests -# (including any cached) is known and the "1..$ntests" line can be -# printed along with the cached results. After that, calls to ok() -# generated printed output immediately. -#------------------------------------------------------------------------ - -sub ntests { - $ntests = shift; - # add any pre-declared extra tests, or pre-stored test @results, to - # the grand total of tests - $ntests += $EXTRA + scalar @results; - $ok_count = 1; - print $ntests ? "1..$ntests\n" : "1..$ntests # skipped: $REASON\n"; - # flush cached results - foreach my $pre_test (@results) { - ok(@$pre_test); - } -} - - -#------------------------------------------------------------------------ -# ok($truth, $msg) -# -# Tests the value passed for truth and generates an "ok $n" or "not ok $n" -# line accordingly. If ntests() hasn't been called then we cached -# results for later, instead. -#------------------------------------------------------------------------ - -sub ok { - my ($ok, $msg) = @_; - - # cache results if ntests() not yet called - unless ($ok_count) { - push(@results, [ $ok, $msg ]); - return $ok; - } - - $msg = defined $msg ? " - $msg" : ''; - if ($ok) { - print "ok ", $ok_count++, "$msg\n"; - } - else { - print STDERR "FAILED $ok_count: $msg\n" if defined $msg; - print "not ok ", $ok_count++, "$msg\n"; - } -} - - - -#------------------------------------------------------------------------ -# assert($truth, $error) -# -# Test value for truth, die if false. -#------------------------------------------------------------------------ - -sub assert { - my ($ok, $err) = @_; - return ok(1) if $ok; - - # failed - my ($pkg, $file, $line) = caller(); - $err ||= "assert failed"; - $err .= " at $file line $line\n"; - ok(0); - die $err; -} - -#------------------------------------------------------------------------ -# match( $result, $expect ) -#------------------------------------------------------------------------ - -sub match { - my ($result, $expect, $msg) = @_; - my $count = $ok_count ? $ok_count : scalar @results + 1; - - # force stringification of $result to avoid 'no eq method' overload errors - $result = "$result" if ref $result; - - if ($result eq $expect) { - return ok(1, $msg); - } - else { - print STDERR "FAILED $count:\n expect: [$expect]\n result: [$result]\n"; - return ok(0, $msg); - } -} - - -#------------------------------------------------------------------------ -# flush() -# -# Flush any tests results. -#------------------------------------------------------------------------ - -sub flush { - ntests(0) - unless $ok_count || $NO_FLUSH; -} - - -#------------------------------------------------------------------------ -# skip_all($reason) -# -# Skip all tests, setting $REASON to contain any message passed. Calls -# exit(0) which triggers flush() which generates a "1..0 # $REASON" -# string to keep to test harness happy. -#------------------------------------------------------------------------ - -sub skip_all { - $REASON = join('', @_); - exit(0); -} - - -#------------------------------------------------------------------------ -# test_expect($input, $template, \%replace) -# -# This is the main testing sub-routine. The $input parameter should be a -# text string or a filehandle reference (e.g. GLOB or IO::Handle) from -# which the input text can be read. The input should contain a number -# of tests which are split up and processed individually, comparing the -# generated output against the expected output. Tests should be defined -# as follows: -# -# -- test -- -# test input -# -- expect -- -# expected output -# -# -- test -- -# etc... -# -# The number of tests is determined and ntests() is called to generate -# the "0..$n" line compatible with Test::Harness. Each test input is -# then processed by the Template object passed as the second parameter, -# $template. This may also be a hash reference containing configuration -# which are used to instantiate a Template object, or may be left -# undefined in which case a default Template object will be instantiated. -# The third parameter, also optional, may be a reference to a hash array -# defining template variables. This is passed to the template process() -# method. -#------------------------------------------------------------------------ - -sub test_expect { - my ($src, $tproc, $params) = @_; - my ($input, @tests); - my ($output, $expect, $match); - my $count = 0; - my $ttprocs; - - # read input text - eval { - local $/ = undef; - $input = ref $src ? <$src> : $src; - }; - if ($@) { - ntests(1); ok(0); - warn "Cannot read input text from $src\n"; - return undef; - } - - # remove any comment lines - $input =~ s/^#.*?\n//gm; - - # remove anything before '-- start --' and/or after '-- stop --' - $input = $' if $input =~ /\s*--\s*start\s*--\s*/; - $input = $` if $input =~ /\s*--\s*stop\s*--\s*/; - - @tests = split(/^\s*--\s*test\s*--\s*\n/im, $input); - - # if the first line of the file was '--test--' (optional) then the - # first test will be empty and can be discarded - shift(@tests) if $tests[0] =~ /^\s*$/; - - ntests(3 + scalar(@tests) * 2); - - # first test is that Template loaded OK, which it did - ok(1, 'running test_expect()'); - - # optional second param may contain a Template reference or a HASH ref - # of constructor options, or may be undefined - if (ref($tproc) eq 'HASH') { - # create Template object using hash of config items - $tproc = Template->new($tproc) - || die Template->error(), "\n"; - } - elsif (ref($tproc) eq 'ARRAY') { - # list of [ name => $tproc, name => $tproc ], use first $tproc - $ttprocs = { @$tproc }; - $tproc = $tproc->[1]; - } - elsif (! ref $tproc) { - $tproc = Template->new() - || die Template->error(), "\n"; - } - # otherwise, we assume it's a Template reference - - # test: template processor created OK - ok($tproc, 'template processor is engaged'); - - # third test is that the input read ok, which it did - ok(1, 'input read and split into ' . scalar @tests . ' tests'); - - # the remaining tests are defined in @tests... - foreach $input (@tests) { - $count++; - my $name = ''; - - if ($input =~ s/^\s*-- name:? (.*?) --\s*\n//im) { - $name = $1; - } - else { - $name = "template text $count"; - } - - # split input by a line like "-- expect --" - ($input, $expect) = - split(/^\s*--\s*expect\s*--\s*\n/im, $input); - $expect = '' - unless defined $expect; - - $output = ''; - - # input text may be prefixed with "-- use name --" to indicate a - # Template object in the $ttproc hash which we should use - if ($input =~ s/^\s*--\s*use\s+(\S+)\s*--\s*\n//im) { - my $ttname = $1; - my $ttlookup; - if ($ttlookup = $ttprocs->{ $ttname }) { - $tproc = $ttlookup; - } - else { - warn "no such template object to use: $ttname\n"; - } - } - - # process input text - $tproc->process(\$input, $params, \$output) || do { - warn "Template process failed: ", $tproc->error(), "\n"; - # report failure and automatically fail the expect match - ok(0, "$name process FAILED: " . subtext($input)); - ok(0, '(obviously did not match expected)'); - next; - }; - - # processed OK - ok(1, "$name processed OK: " . subtext($input)); - - # another hack: if the '-- expect --' section starts with - # '-- process --' then we process the expected output - # before comparing it with the generated output. This is - # slightly twisted but it makes it possible to run tests - # where the expected output isn't static. See t/date.t for - # an example. - - if ($expect =~ s/^\s*--+\s*process\s*--+\s*\n//im) { - my $out; - $tproc->process(\$expect, $params, \$out) || do { - warn("Template process failed (expect): ", - $tproc->error(), "\n"); - # report failure and automatically fail the expect match - ok(0, "failed to process expected output [" - . subtext($expect) . ']'); - next; - }; - $expect = $out; - }; - - # strip any trailing blank lines from expected and real output - foreach ($expect, $output) { - s/\n*\Z//mg; - } - - $match = ($expect eq $output) ? 1 : 0; - if (! $match || $DEBUG) { - print "MATCH FAILED\n" - unless $match; - - my ($copyi, $copye, $copyo) = ($input, $expect, $output); - unless ($PRESERVE) { - foreach ($copyi, $copye, $copyo) { - s/\n/\\n/g; - } - } - printf(" input: [%s]\nexpect: [%s]\noutput: [%s]\n", - $copyi, $copye, $copyo); - } - - ok($match, $match ? "$name matched expected" : "$name did not match expected"); - }; -} - -#------------------------------------------------------------------------ -# callsign() -# -# Returns a hash array mapping lower a..z to their phonetic alphabet -# equivalent. -#------------------------------------------------------------------------ - -sub callsign { - my %callsign; - @callsign{ 'a'..'z' } = qw( - alpha bravo charlie delta echo foxtrot golf hotel india - juliet kilo lima mike november oscar papa quebec romeo - sierra tango umbrella victor whisky x-ray yankee zulu ); - return \%callsign; -} - - -#------------------------------------------------------------------------ -# banner($text) -# -# Prints a banner with the specified text if $DEBUG is set. -#------------------------------------------------------------------------ - -sub banner { - return unless $DEBUG; - my $text = join('', @_); - my $count = $ok_count ? $ok_count - 1 : scalar @results; - print "-" x 72, "\n$text ($count tests completed)\n", "-" x 72, "\n"; -} - - -sub subtext { - my $text = shift; - $text =~ s/\s*$//sg; - $text = substr($text, 0, 32) . '...' if length $text > 32; - $text =~ s/\n/\\n/g; - return $text; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Test - Module for automating TT2 test scripts - -=head1 SYNOPSIS - - use Template::Test; - - $Template::Test::DEBUG = 0; # set this true to see each test running - $Template::Test::EXTRA = 2; # 2 extra tests follow test_expect()... - - # ok() can be called any number of times before test_expect - ok( $true_or_false ) - - # test_expect() splits $input into individual tests, processes each - # and compares generated output against expected output - test_expect($input, $template, \%replace ); - - # $input is text or filehandle (e.g. DATA section after __END__) - test_expect( $text ); - test_expect( \*DATA ); - - # $template is a Template object or configuration hash - my $template_cfg = { ... }; - test_expect( $input, $template_cfg ); - my $template_obj = Template->new($template_cfg); - test_expect( $input, $template_obj ); - - # $replace is a hash reference of template variables - my $replace = { - a => 'alpha', - b => 'bravo' - }; - test_expect( $input, $template, $replace ); - - # ok() called after test_expect should be declared in $EXTRA (2) - ok( $true_or_false ) - ok( $true_or_false ) - -=head1 DESCRIPTION - -The Template::Test module defines the test_expect() and other related -subroutines which can be used to automate test scripts for the -Template Toolkit. See the numerous tests in the 't' sub-directory of -the distribution for examples of use. - -The test_expect() subroutine splits an input document into a number -of separate tests, processes each one using the Template Toolkit and -then compares the generated output against an expected output, also -specified in the input document. It generates the familiar "ok/not -ok" output compatible with Test::Harness. - -The test input should be specified as a text string or a reference to -a filehandle (e.g. GLOB or IO::Handle) from which it can be read. In -particular, this allows the test input to be placed after the __END__ -marker and read via the DATA filehandle. - - use Template::Test; - - test_expect(\*DATA); - - __END__ - # this is the first test (this is a comment) - -- test -- - blah blah blah [% foo %] - -- expect -- - blah blah blah value_of_foo - - # here's the second test (no surprise, so is this) - -- test -- - more blah blah [% bar %] - -- expect -- - more blah blah value_of_bar - -Blank lines between test sections are generally ignored. Any line starting -with '#' is treated as a comment and is ignored. - -The second and third parameters to test_expect() are optional. The second -may be either a reference to a Template object which should be used to -process the template fragments, or a reference to a hash array containing -configuration values which should be used to instantiate a new Template -object. - - # pass reference to config hash - my $config = { - INCLUDE_PATH => '/here/there:/every/where', - POST_CHOMP => 1, - }; - test_expect(\*DATA, $config); - - # or create Template object explicitly - my $template = Template->new($config); - test_expect(\*DATA, $template); - - -The third parameter may be used to reference a hash array of template -variable which should be defined when processing the tests. This is -passed to the Template process() method. - - my $replace = { - a => 'alpha', - b => 'bravo', - }; - - test_expect(\*DATA, $config, $replace); - -The second parameter may be left undefined to specify a default Template -configuration. - - test_expect(\*DATA, undef, $replace); - -For testing the output of different Template configurations, a -reference to a list of named Template objects also may be passed as -the second parameter. - - my $tt1 = Template->new({ ... }); - my $tt2 = Template->new({ ... }); - my @tts = [ one => $tt1, two => $tt1 ]; - -The first object in the list is used by default. Other objects may be -switched in with the '-- use $name --' marker. This should immediately -follow a '-- test --' line. That object will then be used for the rest -of the test, or until a different object is selected. - - -- test -- - -- use one -- - [% blah %] - -- expect -- - blah, blah - - -- test -- - still using one... - -- expect -- - ... - - -- test -- - -- use two -- - [% blah %] - -- expect -- - blah, blah, more blah - -The test_expect() sub counts the number of tests, and then calls ntests() -to generate the familiar "1..$ntests\n" test harness line. Each -test defined generates two test numbers. The first indicates -that the input was processed without error, and the second that the -output matches that expected. - -Additional test may be run before test_expect() by calling ok(). -These test results are cached until ntests() is called and the final -number of tests can be calculated. Then, the "1..$ntests" line is -output, along with "ok $n" / "not ok $n" lines for each of the cached -test result. Subsequent calls to ok() then generate an output line -immediately. - - my $something = SomeObject->new(); - ok( $something ); - - my $other = AnotherThing->new(); - ok( $other ); - - test_expect(\*DATA); - -If any tests are to follow after test_expect() is called then these -should be pre-declared by setting the $EXTRA package variable. This -value (default: 0) is added to the grand total calculated by ntests(). -The results of the additional tests are also registered by calling ok(). - - $Template::Test::EXTRA = 2; - - # can call ok() any number of times before test_expect() - ok( $did_that_work ); - ok( $make_sure ); - ok( $dead_certain ); - - # <some> number of tests... - test_expect(\*DATA, $config, $replace); - - # here's those $EXTRA tests - ok( defined $some_result && ref $some_result eq 'ARRAY' ); - ok( $some_result->[0] eq 'some expected value' ); - -If you don't want to call test_expect() at all then you can call -ntests($n) to declare the number of tests and generate the test -header line. After that, simply call ok() for each test passing -a true or false values to indicate that the test passed or failed. - - ntests(2); - ok(1); - ok(0); - -If you're really lazy, you can just call ok() and not bother declaring -the number of tests at all. All tests results will be cached until the -end of the script and then printed in one go before the program exits. - - ok( $x ); - ok( $y ); - -You can identify only a specific part of the input file for testing -using the '-- start --' and '-- stop --' markers. Anything before the -first '-- start --' is ignored, along with anything after the next -'-- stop --' marker. - - -- test -- - this is test 1 (not performed) - -- expect -- - this is test 1 (not performed) - - -- start -- - - -- test -- - this is test 2 - -- expect -- - this is test 2 - - -- stop -- - - ... - -For historical reasons and general utility, the module also defines a -'callsign' subroutine which returns a hash mapping a..z to their phonetic -alphabet equivalent (e.g. radio callsigns). This is used by many -of the test scripts as a "known source" of variable values. - - test_expect(\*DATA, $config, callsign()); - -A banner() subroutine is also provided which prints a simple banner -including any text passed as parameters, if $DEBUG is set. - - banner('Testing something-or-other'); - -example output: - - #------------------------------------------------------------ - # Testing something-or-other (27 tests completed) - #------------------------------------------------------------ - -The $DEBUG package variable can be set to enable debugging mode. - -The $PRESERVE package variable can be set to stop the test_expect() -from converting newlines in the output and expected output into -the literal strings '\n'. - -=head1 HISTORY - -This module started its butt-ugly life as the t/texpect.pl script. It -was cleaned up to became the Template::Test module some time around -version 0.29. It underwent further cosmetic surgery for version 2.00 -but still retains some rear-end resemblances. - -=head1 BUGS / KNOWN "FEATURES" - -Imports all methods by default. This is generally a Bad Thing, but -this module is only used in test scripts (i.e. at build time) so a) we -don't really care and b) it saves typing. - -The line splitter may be a bit dumb, especially if it sees lines like --- this -- that aren't supposed to be special markers. So don't do that. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<Template|Template> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Tools/tpage.pod b/lib/Template/Tools/tpage.pod deleted file mode 100644 index e2b20fa..0000000 --- a/lib/Template/Tools/tpage.pod +++ /dev/null @@ -1,76 +0,0 @@ - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tools::tpage - Process templates from command line - -=head1 USAGE - - tpage [ --define var=value ] file(s) - -=head1 DESCRIPTION - -The B<tpage> script is a simple wrapper around the Template Toolkit processor. -Files specified by name on the command line are processed in turn by the -template processor and the resulting output is sent to STDOUT and can be -redirected accordingly. e.g. - - tpage myfile > myfile.out - tpage header myfile footer > myfile.html - -If no file names are specified on the command line then B<tpage> will read -STDIN for input. - -The C<--define> option can be used to set the values of template variables. -e.g. - - tpage --define author="Andy Wardley" skeleton.pm > MyModule.pm - -See L<Template> for general information about the Perl Template -Toolkit and the template language and features. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<ttree|Template::Tools::ttree> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Tools/ttree.pod b/lib/Template/Tools/ttree.pod deleted file mode 100644 index 8984c51..0000000 --- a/lib/Template/Tools/ttree.pod +++ /dev/null @@ -1,332 +0,0 @@ - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tools::ttree - Process entire directory trees of templates - -=head1 SYNOPSIS - - ttree [options] [files] - -=head1 DESCRIPTION - -The F<ttree> script is used to process entire directory trees containing -template files. The resulting output from processing each file is then -written to a corresponding file in a destination directory. The script -compares the modification times of source and destination files (where -they already exist) and processes only those files that have been modified. -In other words, it is the equivalent of 'make' for the Template Toolkit. - -It supports a number of options which can be used to configure -behaviour, define locations and set Template Toolkit options. The -script first reads the F<.ttreerc> configuration file in the HOME -directory, or an alternative file specified in the TTREERC environment -variable. Then, it processes any command line arguments, including -any additional configuration files specified via the C<-f> (file) -option. - -=head2 The F<.ttreerc> Configuration File - -When you run F<ttree> for the first time it will ask you if you want -it to create a F<.ttreerc> file for you. This will be created in your -home directory. - - $ ttree - Do you want me to create a sample '.ttreerc' file for you? - (file: /home/abw/.ttreerc) [y/n]: y - /home/abw/.ttreerc created. Please edit accordingly and re-run ttree - -The purpose of this file is to set any I<global> configuration options -that you want applied I<every> time F<ttree> is run. For example, you -can use the C<ignore> and C<copy> option to provide regular expressions -that specify which files should be ignored and which should be copied -rather than being processed as templates. You may also want to set -flags like C<verbose> and C<recurse> according to your preference. - -A minimal F<.ttreerc>: - - # ignore these files - ignore = \b(CVS|RCS)\b - ignore = ^# - ignore = ~$ - - # copy these files - copy = \.(gif|png|jpg|pdf)$ - - # recurse into directories - recurse - - # provide info about what's going on - verbose - -In most cases, you'll want to create a different F<ttree> configuration -file for each project you're working on. The C<cfg> option allows you -to specify a directory where F<ttree> can find further configuration -files. - - cfg = /home/abw/.ttree - -The C<-f> command line option can be used to specify which configuration -file should be used. You can specify a filename using an absolute or -relative path: - - $ ttree -f /home/abw/web/example/etc/ttree.cfg - $ ttree -f ./etc/ttree.cfg - $ ttree -f ../etc/ttree.cfg - -If the configuration file does not begin with C</> or C<.> or something -that looks like a MS-DOS absolute path (e.g. C<C:\\etc\\ttree.cfg>) then -F<ttree> will look for it in the directory specified by the C<cfg> option. - - $ ttree -f test1 # /home/abw/.ttree/test1 - -The C<cfg> option can only be used in the F<.ttreerc> file. All the -other options can be used in the F<.ttreerc> or any other F<ttree> -configuration file. They can all also be specified as command line -options. - -Remember that F<.ttreerc> is always processed I<before> any -configuration file specified with the C<-f> option. Certain options -like C<lib> can be used any number of times and accumulate their values. - -For example, consider the following configuration files: - -F</home/abw/.ttreerc>: - - cfg = /home/abw/.ttree - lib = /usr/local/tt2/templates - -F</home/abw/.ttree/myconfig>: - - lib = /home/abw/web/example/templates/lib - -When F<ttree> is invoked as follows: - - $ ttree -f myconfig - -the C<lib> option will be set to the following directories: - - /usr/local/tt2/templates - /home/abw/web/example/templates/lib - -Any templates located under F</usr/local/tt2/templates> will be used -in preference to those located under -F</home/abw/web/example/templates/lib>. This may be what you want, -but then again, it might not. For this reason, it is good practice to -keep the F<.ttreerc> as simple as possible and use different -configuration files for each F<ttree> project. - -=head2 Directory Options - -The C<src> option is used to define the directory containing the -source templates to be processed. It can be provided as a command -line option or in a configuration file as shown here: - - src = /home/abw/web/example/templates/src - -Each template in this directory typically corresponds to a single -web page or other document. - -The C<dest> option is used to specify the destination directory for the -generated output. - - dest = /home/abw/web/example/html - -The C<lib> option is used to define one or more directories containing -additional library templates. These templates are not documents in -their own right and typically comprise of smaller, modular components -like headers, footers and menus that are incorporated into pages templates. - - lib = /home/abw/web/example/templates/lib - lib = /usr/local/tt2/templates - -The C<lib> option can be used repeatedly to add further directories to -the search path. - -A list of templates can be passed to F<ttree> as command line arguments. - - $ ttree foo.html bar.html - -It looks for these templates in the C<src> directory and processes them -through the Template Toolkit, using any additional template components -from the C<lib> directories. The generated output is then written to -the corresponding file in the C<dest> directory. - -If F<ttree> is invoked without explicitly specifying any templates -to be processed then it will process every file in the C<src> directory. -If the C<-r> (recurse) option is set then it will additionally iterate -down through sub-directories and process and other template files it finds -therein. - - $ ttree -r - -If a template has been processed previously, F<ttree> will compare the -modification times of the source and destination files. If the source -template (or one it is dependant on) has not been modified more -recently than the generated output file then F<ttree> will not process -it. The F<-a> (all) option can be used to force F<ttree> to process -all files regardless of modification time. - - $ tree -a - -Any templates explicitly named as command line argument are always -processed and the modification time checking is bypassed. - -=head2 File Options - -The C<ignore>, C<copy> and C<accept> options are used to specify Perl -regexen to filter file names. Files that match any of the C<ignore> -options will not be processed. Remaining files that match any of the -C<copy> regexen will be copied to the destination directory. Remaining -files that then match any of the C<accept> criteria are then processed -via the Template Toolkit. If no C<accept> parameter is specified then -all files will be accepted for processing if not already copied or -ignored. - - # ignore these files - ignore = \b(CVS|RCS)\b - ignore = ^# - ignore = ~$ - - # copy these files - copy = \.(gif|png|jpg|pdf)$ - - # accept only .tt2 templates - accept = \.tt2$ - -The C<suffix> option is used to define mappings between the file -extensions for source templates and the generated output files. The -following example specifies that source templates with a C<.tt2> -suffix should be output as C<.html> files: - - suffix tt2=html - -Or on the command line, - - --suffix tt2=html - -You can provide any number of different suffix mappings by repeating -this option. - -=head2 Template Dependencies - -The C<depend> and C<depend_file> options allow you to specify -how any given template file depends on another file or group of files. -The C<depend> option is used to express a single dependency. - - $ ttree --depend foo=bar,baz - -This command line example shows the C<--depend> option being used to -specify that the F<foo> file is dependant on the F<bar> and F<baz> -templates. This option can be used many time on the command line: - - $ ttree --depend foo=bar,baz --depend crash=bang,wallop - -or in a configuration file: - - depend foo=bar,baz - depend crash=bang,wallop - -The file appearing on the left of the C<=> is specified relative to -the C<src> or C<lib> directories. The file(s) appearing on the right -can be specified relative to any of these directories or as absolute -file paths. - -For example: - - $ ttree --depend foo=bar,/tmp/baz - -To define a dependency that applies to all files, use C<*> on the -left of the C<=>. - - $ ttree --depend *=header,footer - -or in a configuration file: - - depend *=header,footer - -Any templates that are defined in the C<pre_process>, C<post_process>, -C<process> or C<wrapper> options will automatically be added to the -list of global dependencies that apply to all templates. - -The C<depend_file> option can be used to specify a file that contains -dependency information. - - $ ttree --depend_file=/home/abw/web/example/etc/ttree.dep - -Here is an example of a dependency file: - - # This is a comment. It is ignored. - - index.html: header footer menubar - - header: titlebar hotlinks - - menubar: menuitem - - # spanning multiple lines with the backslash - another.html: header footer menubar \ - sidebar searchform - -Lines beginning with the C<#> character are comments and are ignored. -Blank lines are also ignored. All other lines should provide a -filename followed by a colon and then a list of dependant files -separated by whitespace, commas or both. Whitespace around the colon -is also optional. Lines ending in the C<\> character are continued -onto the following line. - -Files that contain spaces can be quoted. That is only necessary -for files after the colon (':'). The file before the colon may be -quoted if it contains a colon. - -As with the command line options, the C<*> character can be used -as a wildcard to specify a dependency for all templates. - - * : config,header - -=head2 Template Toolkit Options - -F<ttree> also provides access to the usual range of Template Toolkit -options. For example, the C<--pre_chomp> and C<--post_chomp> F<ttree> -options correspond to the C<PRE_CHOMP> and C<POST_CHOMP> options. - -Run C<ttree -h> for a summary of the options available. - -=head1 AUTHORS - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - -With contributions from Dylan William Hardison (support for -dependencies), Bryce Harrington (C<absolute> and C<relative> options), -Mark Anderson (C<suffix> and C<debug> options), Harald Joerg and Leon -Brocard who gets everywhere, it seems. - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - -=head1 SEE ALSO - -L<tpage|Template::Tools::tpage> - diff --git a/lib/Template/Tutorial.pod b/lib/Template/Tutorial.pod deleted file mode 100644 index b6c894f..0000000 --- a/lib/Template/Tutorial.pod +++ /dev/null @@ -1,109 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Tutorial -# -# DESCRIPTION -# This section includes tutorials on using the Template Toolkit. -# Subjects currently include an general overview of the Template -# Toolkit, showing users how to get quickly up to speed building web -# content, and a tutorial on generating and using data files, with -# particular reference to XML. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tutorial - Template Toolkit Tutorials - -=head1 DESCRIPTION - -This section includes tutorials on using the Template Toolkit. Subjects -currently include an general overview of the Template Toolkit, showing -users how to get quickly up to speed building web content, and a -tutorial on generating and using data files, with particular reference -to XML. - -=over 4 - -=item L<Template::Tutorial::Web|Template::Tutorial::Web> - -Generating Web Content Using the Template Toolkit - -This tutorial provides an introduction to the Template Toolkit and a -"quick start" guide to getting up to speed. Its primarily focus is on -using the Template Toolkit to build web content and it covers 4 basic -areas: using tpage and ttree; using the Template.pm module in CGI -scripts; writing Apache/mod_perl handlers; and extending the toolkit by -writing plugins. - -=item L<Template::Tutorial::Datafile|Template::Tutorial::Datafile> - -Creating Data Output Files Using the Template Toolkit - -This tutorial gives an overview of the Template Toolkit, showing in -particular how to use it to read and write data files in various -different formats and styles. It was written by Dave Cross and first -appeared as a lead article at http://www.perl.com/ earlier in the year -(2001). - - - -=back - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Tutorial/Datafile.pod b/lib/Template/Tutorial/Datafile.pod deleted file mode 100644 index 652f79d..0000000 --- a/lib/Template/Tutorial/Datafile.pod +++ /dev/null @@ -1,461 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Tutorial::Datafile -# -# DESCRIPTION -# This tutorial gives an overview of the Template Toolkit, showing in -# particular how to use it to read and write data files in various -# different formats and styles. It was written by Dave Cross and -# first appeared as a lead article at http://www.perl.com/ earlier in -# the year (2001). -# -# AUTHOR -# Dave Cross <dave@dave.org.uk> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tutorial::Datafile - Creating Data Output Files Using the Template Toolkit - -=head1 DESCRIPTION - -This tutorial gives an overview of the Template Toolkit, showing in -particular how to use it to read and write data files in various -different formats and styles. It was written by Dave Cross and first -appeared as a lead article at http://www.perl.com/ earlier in the year -(2001). - -=head1 Introducing the Template Toolkit - -There are a number of Perl modules that are universally -recognised as The Right Thing To Use for certain tasks. If you -accessed a database without using DBI, pulled data from the WWW -without using one of the LWP modules or parsed XML without using -XML::Parser or one of its subclasses then you'd run the risk of -being shunned by polite Perl society. - -I believe that the year 2000 saw the emergence of another 'must -have' Perl module - the Template Toolkit. I don't think I'm -alone in this belief as the Template Toolkit won the 'Best New -Module' award at the Perl Conference last summer. Version 2.0 of -the Template Toolkit (known as TT2 to its friends) was recently -released to the CPAN. - -TT2 was designed and written by Andy Wardley E<lt>abw@wardley.orgE<gt>. -It was born out of Andy's previous templating module, -Text::Metatext, in best Fred Brooks 'plan to throw one away' -manner; and aims to be the most useful (or, at least, the most -I<used>) Perl templating system. - -TT2 provides a way to take a file of fixed boilerplate text -(the template) and embed variable data within it. One obvious -use of this is in the creation of dynamic web pages and this is -where a lot of the attention that TT2 has received has been -focussed. In this article, I hope to demonstrate that TT2 is -just as useful in non-web applications. - -=head1 Using the Template Toolkit - -Let's look at how we'd use TT2 to process a simple data file. -TT2 is an object oriented Perl module. Having downloaded it from -CPAN and installed it in the usual manner, using it in your -program is as easy as putting the lines - - use Template; - my $tt = Template->new; - -in your code. The constructor function, C<new>, takes -a number of optional parameters which are documented in the -copious manual pages that come with the module, but for the -purposes of this article we'll keep things as simple as -possible. - -To process the template, you would call the C<process> method -like this - - $tt->process('my_template', \%data) - || die $tt->error; - -We pass two parameters to C<process>, the first is the name of -the file containing the template to process (in this case, -my_template) and the second is a reference to a hash which -contains the data items that you want to use in the template. If -processing the template gives any kind of error, the program -will die with a (hopefully) useful error message. - -So what kinds of things can go in C<%data>? The answer is just -about anything. Here's an example showing data about English -Premier League football teams. - - my @teams = ({ name => 'Man Utd', - played => 16, - won => 12, - drawn => 3, - lost => 1 }, - { name => 'Bradford', - played => 16, - won => 2, - drawn => 5, - lost => 9 }); - - my %data = ( name => 'English Premier League', - season => '2000/01', - teams => \@teams ); - -This creates three data items which can be accessed within the -template, called C<name>, C<season> and C<teams>. Notice that -C<teams> is a complex data structure. - -Here is a template that we might use to process this data. - - League Standings - - League Name: [% name %] - Season : [% season %] - - Teams: - [% FOREACH team = teams -%] - [% team.name %] [% team.played -%] - [% team.won %] [% team.drawn %] [% team.lost %] - [% END %] - -Running this template with this data gives us the following -output - - League Standings - - League Name: English Premier League - Season : 2000/01 - - Teams: - Man Utd 16 12 3 1 - Bradford 16 2 5 9 - -Hopefully the syntax of the template is simple enough to -follow. There are a few points to note. - -=over 4 - -=item * - -Template processing directives are written using a simple -language which is not Perl. - -=item * - -The keys of the C<%data> have become the names of the data -variables within the template. - -=item * - -Template processing directives are surrounded by C<[%> and -C<%]> sequences. - -=item * - -If these tags are replaced with C<[%-> C<-%]> then the preceding -or following linefeed is suppressed. - -=item * - -In the C<FOREACH> loop, each element of the C<teams> list was -assigned, in turn, to the temporary variable C<team>. - -=item * - -Each item assigned to the C<team> variable is a Perl hash. -Individual values within the hash are accessed using a dot notation. - -=back - -It's probably the first and last of these points which are the -most important. The first point emphasises the separation of the -data acquisition logic from the presentation logic. The person -creating the presentation template doesn't need to know Perl, -they only need to know the data items which will be passed into -the template. - -The last point demonstrates the way that TT2 protects the -template designer from the implementation of the data structures. -The data objects passed to the template processor can be scalars, -arrays, hashes, objects or even subroutines. The template -processor will just interpret your data correctly and Do The -Right Thing to return the correct value to you. In this example -each team was a hash, but in a larger system each team might be -an object, in which case C<name>, C<played>, etc. would be accessor -methods to the underlying object attributes. No changes would be -required to the template as the template processor would realise -that it needed to call methods rather than access hash values. - -=head2 A more complex example - -Stats about the English Football League are usually presented in -a slightly more complex format than the one we used above. A -full set of stats will show the number of games that a team has -won, lost or drawn, the number of goals scored for and against -the team and the number of points that the team therefore has. -Teams gain three points for a win and one point for a draw. When -teams have the same number of points they are separated by the -goal difference, that is the number of goals the team has scored -minus the number of team scored against them. To complicate -things even further, the games won, drawn and lost and the goals -for and against are often split between home and away games. - -Therefore if you have a data source which lists the team name -togther with the games won, drawn and lost and the goals for and -against split into home and away (a total of eleven data items) -you can calculate all of the other items (goal difference, -points awarded and even position in the league). Let's take such -a file, but we'll only look at the top three teams. It will look -something like this: - - Man Utd,7,1,0,26,4,5,2,1,15,6 - Arsenal,7,1,0,17,4,2,3,3,7,9 - Leicester,4,3,1,10,8,4,2,2,7,4 - -A simple script to read this data into an array of hashes will -look something like this (I've simplified the names of the data -columns - w, d, and l are games won, drawn and lost and f and a -are goals scored for and against; h and a at the front of a data -item name indicates whether it's a home or away statistic): - - my @cols = qw(name hw hd hl hf ha aw ad al af aa); - - my @teams; - while (<>) { - chomp; - - my %team; - - @team{@cols} = split /,/; - - push @teams, \%team; - } - -We can then go thru the teams again and calculate all of the -derived data items: - - foreach (@teams) { - $_->{w} = $_->{hw} + $_->{aw}; - $_->{d} = $_->{hd} + $_->{ad}; - $_->{l} = $_->{hl} + $_->{al}; - - $_->{pl} = $_->{w} + $_->{d} + $_->{l}; - - $_->{f} = $_->{hf} + $_->{af}; - $_->{a} = $_->{ha} + $_->{aa}; - - $_->{gd} = $_->{f} - $_->{a}; - $_->{pt} = (3 * $_->{w}) + $_->{d}; - } - -And then produce a list sorted in descending order: - - @teams = sort { - $b->{pt} <=> $b->{pt} || $b->{gd} <=> $a->{gd} - } @teams; - -And finally add the league position data item: - - $teams[$_]->{pos} = $_ + 1 - foreach 0 .. $#teams; - -Having pulled all of our data into an internal data structure -we can start to produce output using out templates. A template -to create a CSV file containing the data split between home and -away stats would look like this: - - [% FOREACH team = teams -%] - [% team.pos %],[% team.name %],[% team.pl %],[% team.hw %], - [%- team.hd %],[% team.hl %],[% team.hf %],[% team.ha %], - [%- team.aw %],[% team.ad %],[% team.al %],[% team.af %], - [%- team.aa %],[% team.gd %],[% team.pt %] - [%- END %] - -And processing it like this: - - $tt->process('split.tt', { teams => \@teams }, 'split.csv') - || die $tt->error; - -produces the following output: - - 1,Man Utd,16,7,1,0,26,4,5,2,1,15,6,31,39 - 2,Arsenal,16,7,1,0,17,4,2,3,3,7,9,11,31 - 3,Leicester,16,4,3,1,10,8,4,2,2,7,4,5,29 - -Notice that we've introduced the third parameter to C<process>. -If this parameter is missing then the TT2 sends its output to -C<STDOUT>. If this parameter is a scalar then it is taken as the -name of a file to write the output to. This parameter can also be -(amongst other things) a filehandle or a reference to an object w -hich is assumed to implement a C<print> method. - -If we weren't interested in the split between home and away games, -then we could use a simpler template like this: - - [% FOREACH team = teams -%] - [% team.pos %],[% team.name %],[% team.pl %],[% team.w %], - [%- team.d %],[% team.l %],[% team.f %],[% team.a %], - [%- team.aa %],[% team.gd %],[% team.pt %] - [% END -%] - -Which would produce output like this: - - 1,Man Utd,16,12,3,1,41,10,6,31,39 - 2,Arsenal,16,9,4,3,24,13,9,11,31 - 3,Leicester,16,8,5,3,17,12,4,5,29 - -=head1 Producing XML - -This is starting to show some of the power and flexibility of -TT2, but you may be thinking that you could just as easily produce -this output with a C<foreach> loop and a couple of C<print> -statements in your code. This is, of course, true; but that's -because I've chosen a deliberately simple example to explain the -concepts. What if we wanted to produce an XML file containing the -data? And what if (as I mentioned earlier) the league data was held -in an object? The code would then look even easier as most of the code -we've written earlier would be hidden away in C<FootballLeague.pm>. - - use FootballLeague; - use Template; - - my $league = FootballLeague->new(name => 'English Premier'); - - my $tt = Template->new; - - $tt->process('league_xml.tt', { league => $league }) - || die $tt->error; - -And the template in C<league_xml.tt> would look something like this: - - <?xml version="1.0"?> - <!DOCTYPE LEAGUE SYSTEM "league.dtd"> - - <league name="[% league.name %]" season="[% league.season %]"> - [% FOREACH team = league.teams -%] - <team name="[% team.name %]" - pos="[% team.pos %]" - played="[% team.pl %]" - goal_diff="[% team.gd %]" - points="[% team.pt %]"> - <stats type="home"> - win="[% team.hw %]" - draw="[%- team.hd %]" - lose="[% team.hl %]" - for="[% team.hf %]" - against="[% team.ha %]" /> - <stats type="away"> - win="[% team.aw %]" - draw="[%- team.ad %]" - lose="[% team.al %]" - for="[% team.af %]" - against="[% team.aa %]" /> - </team> - [% END -%] - &/league> - -Notice that as we've passed the whole object into C<process> then -we need to put an extra level of indirection on our template -variables - everything is now a component of the C<league> variable. -Other than that, everything in the template is very similar to what -we've used before. Presumably now C<team.name> calls an accessor -function rather than carrying out a hash lookup, but all of this -is transparent to our template designer. - -=head1 Multiple Formats - -As a final example, let's suppose that we need to create output -football league tables in a number of formats. Perhaps we are -passing this data on to other people and they can't all use the -same format. Some of our users need CSV files and others need -XML. Some require data split between home and away matches and -other just want the totals. In total, then, we'll need four -different templates, but the good news is that they can use the -same data object. All the script needs to do is to establish -which template is required and process it. - - use FootballLeague; - use Template; - - my ($name, $type, $stats) = @_; - - my $league = FootballLeague->new(name => $name); - - my $tt = Template->new; - - $tt->process("league_${type}_$stats.tt", - { league => $league } - "league_$stats.$type") - || die $tt->error; - -For example, you can call this script as - - league.pl 'English Premier' xml split - -This will process a template called C<league_xml_split.tt> -and put the results in a file called C<league_split.xml>. - -This starts to show the true strength of the Template Toolkit. -If we later wanted to add another file format - perhaps we -wanted to create a league table HTML page or even a LaTeX -document - then we would just need to create the appropriate -template and name it according to our existing naming -convention. We would need to make no changes to the code. - -I hope you can now see why the Template Toolkit is fast becoming -an essential part of many people's Perl installation. - -=head1 AUTHOR - -Dave Cross E<lt>dave@dave.org.ukE<gt> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Dave Cross E<lt>dave@dave.org.ukE<gt> - -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: diff --git a/lib/Template/Tutorial/Web.pod b/lib/Template/Tutorial/Web.pod deleted file mode 100644 index a5ed9bb..0000000 --- a/lib/Template/Tutorial/Web.pod +++ /dev/null @@ -1,801 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Tutorial::Web -# -# DESCRIPTION -# This tutorial provides an introduction to the Template Toolkit and -# a "quick start" guide to getting up to speed. Its primarily focus -# is on using the Template Toolkit to build web content and it covers -# 4 basic areas: using tpage and ttree; using the Template.pm module -# in CGI scripts; writing Apache/mod_perl handlers; and extending the -# toolkit by writing plugins. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 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. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tutorial::Web - Generating Web Content Using the Template Toolkit - -=head1 DESCRIPTION - -This tutorial document provides a introduction to the Template Toolkit -and demonstrates some of the typical ways it may be used for -generating web content. It covers the generation of static pages from -templates using the L<tpage|Template::Tools::tpage> and -L<ttree|Template::Tools::ttree> scripts and then goes on to -show dynamic content generation using CGI scripts and Apache/mod_perl -handlers. - -Various features of the Template Toolkit are introduced and described -briefly and explained by use of example. For further information, -see L<Template>, L<Template::Manual> and the various sections within -it. e.g. - - perldoc Template # Template.pm module usage - perldoc Template::Manual # index to manual - perldoc Template::Manual::Config # e.g. configuration options - -The documentation is now also distributed in HTML format (or rather, -in the form of HTML templates). See the 'docs' sub-directory of the -distribution for further information on building the HTML documentation. - -If you're already reading this as part of the HTML documentation, then -you don't need to worry about all that. You can have a seat, sit back. - back and enjoy the rest of the tutorial... - -=head1 INTRODUCTION - -The Template Toolkit is a set of Perl modules which collectively -implement a template processing system. In this context, a template -is a text document containing special markup tags called 'directives'. -A directive is an instruction for the template processor to perform -some action and substitute the result into the document in place of -the original directive. Directives include those to define or insert -a variable value, iterate through a list of values (FOREACH), declare -a conditional block (IF/UNLESS/ELSE), include and process another template -file (INCLUDE) and so on. - -In all other respects, the document is a plain text file and may -contain any other content (e.g. HTML, XML, RTF, LaTeX, etc). Directives -are inserted in the document within the special markup tags which are -'[%' and '%]' by default, but can be changed via the module -configuration options. Here's an example of an HTML document with -additional Template Toolkit directives. - - [% INCLUDE header - title = 'This is an HTML example' - %] - - <h1>Some Interesting Links</h1> - - [% webpages = [ - { url => 'http://foo.org', title => 'The Foo Organisation' } - { url => 'http://bar.org', title => 'The Bar Organisation' } - ] - %] - - Links: - <ul> - [% FOREACH link = webpages %] - <li><a href="[% link.url %]">[% link.title %]</a> - [% END %] - </ul> - - [% INCLUDE footer %] - -This example shows how the INCLUDE directive is used to load and process -separate 'header' and 'footer' template files, including the output in -the current document. These files might look like this: - -header: - - <html> - <head> - <title>[% title %]</title> - </head> - - <body bgcolor="#ffffff"> - -footer: - - <hr> - - <center> - © Copyright 2000 Me, Myself, I - </center> - - </body> - </html> - -The example also uses the FOREACH directive to iterate through the -'webpages' list to build a table of links. In this example, we have -defined this list within the template to contain a number of hash references, -each containing a 'url' and 'title' member. The FOREACH directive -iterates through the list, aliasing 'link' to each item (hash ref). -The B<[% link.url %]> and B<[% link.title %]> directives then access -the individual values in the hash and insert them into the document. - -The following sections show other ways in which data can be defined for -use in a template. - -=head1 GENERATING STATIC PAGES - -Having created a template file we can now process it to generate some -real output. The quickest and easiest way to do this is to use the -F<tpage> script. This is provided as part of the Template Toolkit and -should be installed in your usual Perl bin directory. - -Assuming you saved your template file as 'mypage.html', you would run -the command: - - tpage mypage.html - -This will process the template file, sending the output to STDOUT -(i.e. whizzing past you on the screen). You may want to redirect the -output to a file but be careful not to specify the same name as the -template file, or you'll overwrite it. You may want to use one prefix -for your templates such as '.atml' (for 'Another Template Markup -Language', perhaps?) and the regular '.html' for the output files -(assuming you're creating HTML, that is). Alternatively, you might -redirect the output to another directory. e.g. - - tpage mypage.atml > mypage.html - tpage templates/mypage.html > html/mypage.html - -The B<tpage> script is very basic and only really intended to give you -an easy way to process a template without having to write any Perl code. -A much more flexible tool is B<ttree>, described below, but for now let's -look at the output generated by processing the above example (some -whitespace removed for brevity): - - <html> - <head> - <title>This is an HTML example</title> - </head> - - <body bgcolor="#ffffff"> - - <h1>Some Interesting Links</h1> - - Links: - <ul> - <li><a href="http://foo.org">The Foo Organsiation</a> - <li><a href="http://bar.org">The Bar Organsiation</a> - </ul> - - <hr> - - <center> - © Copyright 2000 Me, Myself, I - </center> - - </body> - </html> - -The F<header> and F<footer> template files have been included (assuming -you created them and they're in the current directory) and the link data -has been built into an HTML list. - -The F<ttree> script, also distributed as part of the Template Toolkit, -provides a more flexible way to process template documents. The first -time you run the script, it will ask you if it should create a -configuration file, usually called '.ttreerc' in your home directory. -Answer 'y' to have it create the file. - -The F<ttree> documentation describes how you can change the location -of this file and also explains the syntax and meaning of the various -options in the file. Comments are written to the sample configuration -file which should also help. - - perldoc ttree - ttree -h - -In brief, the configuration file describes the directories in which -template files are to be found (src), where the corresponding output -should be written to (dest), and any other directories (lib) that may -contain template files that you plan to INCLUDE into your source -documents. You can also specify processing options (such as 'verbose' -and 'recurse') and provide regular expression to match files that you -don't want to process (ignore, accept) or should be copied instead of -processed (copy). - -An example F<.ttreerc> file is shown here: - -$HOME/.ttreerc: - verbose - recurse - - # this is where I keep other ttree config files - cfg = ~/.ttree - - src = ~/websrc/src - lib = ~/websrc/lib - dest = ~/public_html/test - - ignore = \b(CVS|RCS)\b - ignore = ^# - -You can create many different configuration files and store them -in the directory specified in the 'cfg' option, shown above. You then -add the C<-f filename> option to F<ttree> to have it read that file. - -When you run the script, it compares all the files in the 'src' directory -(including those in sub-directories if the 'recurse' option is set), with -those in the 'dest' directory. If the destination file doesn't exist or -has an earlier modification time than the corresponding source file, then -the source will be processed with the output written to the destination -file. The C<-a> option forces all files to be processed, regardless of -modification times. - -The script I<doesn't> process any of the files in the 'lib' directory, -but it does add it to the INCLUDE_PATH for the template processor so -that it can locate these files via an INCLUDE or PROCESS directive. -Thus, the 'lib' directory is an excellent place to keep template elements -such as header, footers, etc., that aren't complete documents in their -own right. - -You can also specify various Template Toolkit options from the configuration -file. Consult the B<ttree> documentation and help summary (C<ttree -h>) -for full details. e.g. - -$HOME/.ttreerc: - pre_process = config - interpolate - post_chomp - -The 'pre_process' option allows you to specify a template file which -should be processed before each file. Unsurprisingly, there's also a -'post_process' option to add a template after each file. In the -fragment above, we have specified that the 'config' template should be -used as a prefix template. We can create this file in the 'lib' -directory and use it to define some common variables, including those -web page links we defined earlier and might want to re-use in other -templates. We could also include an HTML header, title, or menu bar -in this file which would then be prepended to each and every template -file, but for now we'll keep all that in a separate 'header' file. - -$lib/config: - - [% root = '~/abw' - home = "$root/index.html" - images = "$root/images" - email = 'abw@wardley.org' - graphics = 1 - webpages = [ - { url => 'http://foo.org', title => 'The Foo Organsiation' } - { url => 'http://bar.org', title => 'The Bar Organsiation' } - ] - %] - -Assuming you've created or copied the 'header' and 'footer' files from the -earlier example into your 'lib' directory, you can now start to create -web pages like the following in your 'src' directory and process them -with F<ttree>. - -$src/newpage.html: - - [% INCLUDE header - title = 'Another Template Toolkit Test Page' - %] - - <a href="[% home %]">Home</a> - <a href="mailto:[% email %]">Email</a> - - [% IF graphics %] - <img src="[% images %]/logo.gif" align=right width=60 height=40> - [% END %] - - [% INCLUDE footer %] - -Here we've shown how pre-defined variables can be used as flags to -enable certain feature (e.g. 'graphics') and to specify common items -such as an email address and URL's for the home page, images directory -and so on. This approach allows you to define these values once so -that they're consistent across all pages and can easily be changed to -new values. - -When you run B<ttree>, you should see output similar to the following -(assuming you have the verbose flag set). - - ttree 1.14 (Template Toolkit version 1.02a) - - Source: /home/abw/websrc/src - Destination: /home/abw/public_html/test - Include Path: [ /home/abw/websrc/lib ] - Ignore: [ \b(CVS|RCS)\b, ^# ] - Copy: [ ] - Accept: [ * ] - - + newpage.html - -The '+' before 'newpage.html' shows that the file was processed, with -the output being written to the destination directory. If you run the -same command again, you'll see the following line displayed instead -showing a '-' and giving a reason why the file wasn't processed. - - - newpage.html (not modified) - -It has detected a 'newpage.html' in the destination directory which is -more recent than that in the source directory and so hasn't bothered -to waste time re-processing it. To force all files to be processed, -use the C<-a> option. You can also specify one or more filenames as -command line arguments to F<ttree>: - - tpage newpage.html - -This is what the destination page looks like. - -$dest/newpage.html: - - <html> - <head> - <title>Another Template Toolkit Test Page</title> - </head> - - <body bgcolor="#ffffff"> - - <a href="~/abw/index.html">Home</a> - <a href="mailto:abw@wardley.org">Email me</a> - - <img src="~/abw/images/logo.gif" align=right width=60 height=40> - - <hr> - - <center> - © Copyright 2000 Me, Myself, I - </center> - - </body> - </html> - -You can add as many documents as you like to the 'src' directory and -F<ttree> will apply the same process to them all. In this way, it is -possible to build an entire tree of static content for a web site with -a single command. The added benefit is that you can be assured of -consistency in links, header style, or whatever else you choose to -implement in terms of common templates elements or variables. - -=head1 DYNAMIC CONTENT GENERATION VIA CGI SCRIPT - -The L<Template|Template> module provides a simple front-end to the Template -Toolkit for use in CGI scripts and Apache/mod_perl handlers. Simply -'use' the Template module, create an object instance with the new() -method and then call the process() method on the object, passing the -name of the template file as a parameter. The second parameter passed -is a reference to a hash array of variables that we want made available -to the template: - - #!/usr/bin/perl -w - - use strict; - use Template; - - my $file = 'src/greeting.html'; - my $vars = { - message => "Hello World\n" - }; - - my $template = Template->new(); - - $template->process($file, $vars) - || die "Template process failed: ", $template->error(), "\n"; - -So that our scripts will work with the same template files as our earlier -examples, we'll can add some configuration options to the constructor to -tell it about our environment: - - my $template->new({ - # where to find template files - INCLUDE_PATH => '/home/abw/websrc/src:/home/abw/websrc/lib', - # pre-process lib/config to define any extra values - PRE_PROCESS => 'config', - }); - -Note that here we specify the 'config' file as a PRE_PROCESS option. -This means that the templates we process can use the same global -variables defined earlier for our static pages. We don't have to -replicate their definitions in this script. However, we can supply -additional data and functionality specific to this script via the hash -of variables that we pass to the process() method. - -These entries in this hash may contain simple text or other values, -references to lists, others hashes, sub-routines or objects. The Template -Toolkit will automatically apply the correct procedure to access these -different types when you use the variables in a template. - -Here's a more detailed example to look over. Amongst the different -template variables we define in C<$vars>, we create a reference to a -CGI object and a 'get_user_projects' sub-routine. - - #!/usr/bin/perl -w - - use strict; - use Template; - use CGI; - - $| = 1; - print "Content-type: text/html\n\n"; - - my $file = 'userinfo.html'; - my $vars = { - 'version' => 3.14, - 'days' => [ qw( mon tue wed thu fri sat sun ) ], - 'worklist' => \&get_user_projects, - 'cgi' => CGI->new(), - 'me' => { - 'id' => 'abw', - 'name' => 'Andy Wardley', - }, - }; - - sub get_user_projects { - my $user = shift; - my @projects = ... # do something to retrieve data - return \@projects; - } - - my $template = Template->new({ - INCLUDE_PATH => '/home/abw/websrc/src:/home/abw/websrc/lib', - PRE_PROCESS => 'config', - }); - - $template->process($file, $vars) - || die $template->error(); - -Here's a sample template file that we might create to build the output -for this script. - -$src/userinfo.html: - - [% INCLUDE header - title = 'Template Toolkit CGI Test' - %] - - <a href="mailto:[% email %]">Email [% me.name %]</a> - - <p>This is version [% version %]</p> - - <h3>Projects</h3> - <ul> - [% FOREACH project = worklist(me.id) %] - <li> <a href="[% project.url %]">[% project.name %]</a> - [% END %] - </ul> - - [% INCLUDE footer %] - -This example shows how we've separated the Perl implementation (code) from -the presentation (HTML) which not only makes them easier to maintain in -isolation, but also allows the re-use of existing template elements -such as headers and footers, etc. By using template to create the -output of your CGI scripts, you can give them the same consistency -as your static pages built via L<ttree|Template::Tools::ttree> or -other means. - -Furthermore, we can modify our script so that it processes any one of a -number of different templates based on some condition. A CGI script to -maintain a user database, for example, might process one template to -provide an empty form for new users, the same form with some default -values set for updating an existing user record, a third template for -listing all users in the system, and so on. You can use any Perl -functionality you care to write to implement the logic of your -application and then choose one or other template to generate the -desired output for the application state. - -=head1 DYNAMIC CONTENT GENERATION VIA APACHE/MOD_PERL HANDLER - -B<NOTE:> the Apache::Template module is now available from CPAN -and provides a simple and easy to use Apache/mod_perl interface to the -Template Toolkit. It's only in it's first release (0.01) at the time -of writing and it currently only offers a fairly basic facility, but -it implements most, if not all of what is described below, and it -avoids the need to write your own handler. However, in many cases, -you'll want to write your own handler to customise processing for your -own need, and this section will show you how to get started. - -The Template module can be used in a similar way from an Apache/mod_perl -handler. Here's an example of a typical Apache F<httpd.conf> file: - - PerlModule CGI; - PerlModule Template - PerlModule MyOrg::Apache::User - - PerlSetVar websrc_root /home/abw/websrc - - <Location /user/bin> - SetHandler perl-script - PerlHandler MyOrg::Apache::User - </Location> - -This defines a location called '/user/bin' to which all requests will -be forwarded to the handler() method of the MyOrg::Apache::User -module. That module might look something like this: - - package MyOrg::Apache::User; - - use strict; - use vars qw( $VERSION ); - use Apache::Constants qw( :common ); - use Template qw( :template ); - use CGI; - - $VERSION = 1.59; - - sub handler { - my $r = shift; - - my $websrc = $r->dir_config('websrc_root') - or return fail($r, SERVER_ERROR, - "'websrc_root' not specified"); - - my $template = Template->new({ - INCLUDE_PATH => "$websrc/src/user:$websrc/lib", - PRE_PROCESS => 'config', - OUTPUT => $r, # direct output to Apache request - }); - - my $params = { - uri => $r->uri, - cgi => CGI->new, - }; - - # use the path_info to determine which template file to process - my $file = $r->path_info; - $file =~ s[^/][]; - - $r->content_type('text/html'); - $r->send_http_header; - - $template->process($file, $params) - || return fail($r, SERVER_ERROR, $template->error()); - - return OK; - } - - sub fail { - my ($r, $status, $message) = @_; - $r->log_reason($message, $r->filename); - return $status; - } - -The handler accepts the request and uses it to determine the 'websrc_root' -value from the config file. This is then used to define an INCLUDE_PATH -for a new Template object. The URI is extracted from the request and a -CGI object is created. These are both defined as template variables. - -The name of the template file itself is taken from the PATH_INFO element -of the request. In this case, it would comprise the part of the URL -coming after '/user/bin', e.g for '/user/bin/edit', the template file -would be 'edit' located in "$websrc/src/user". The headers are sent -and the template file is processed. All output is sent directly to the -print() method of the Apache request object. - -=head1 USING PLUGINS TO EXTEND FUNCTIONALITY - -As we've already shown, it is possible to bind Perl data and functions -to template variables when creating dynamic content via a CGI script -or Apache/mod_perl process. The Template Toolkit also supports a -plugin interface which allows you define such additional data and/or -functionality in a separate module and then load and use it as -required with the USE directive. - -The main benefit to this approach is that you can load the extension into -any template document, even those that are processed "statically" by -F<tpage> or F<ttree>. You I<don't> need to write a Perl wrapper to -explicitly load the module and make it available via the stash. - -Let's demonstrate this principle using the DBI plugin written by Simon -Matthews E<lt>sam@knowledgepool.comE<gt>. You can create this -template in your 'src' directory and process it using F<ttree> to see -the results. Of course, this example relies on the existence of the -appropriate SQL database but you should be able to adapt it to your -own resources, or at least use it as a demonstrative example of what's -possible. - - [% INCLUDE header - title = 'User Info' - %] - - [% USE DBI('dbi:mSQL:mydbname') %] - - <table border=0 width="100%"> - <tr> - <th>User ID</th> - <th>Name</th> - <th>Email</th> - </tr> - - [% FOREACH user = DBI.query('SELECT * FROM user ORDER BY id') %] - <tr> - <td>[% user.id %]</td> - <td>[% user.name %]</td> - <td>[% user.email %]</td> - </tr> - [% END %] - - </table> - - [% INCLUDE footer %] - -A plugin is simply a Perl module in a known location and conforming to -a known standard such that the Template Toolkit can find and load it -automatically. You can create your own plugin by inheriting from the -F<Template::Plugin> module. - -Here's an example which defines some data items ('foo' and 'people') -and also an object method ('bar'). We'll call the plugin 'FooBar' for -want of a better name and create it in the 'MyOrg::Template::Plugin::FooBar' -package. We've added a 'MyOrg' to the regular 'Template::Plugin::*' package -to avoid any conflict with existing plugins. - -You can create a module stub using the Perl utlity F<h2xs>: - - h2xs -A -X -n MyOrg::Template::Plugin::FooBar - -This will create a directory structure representing the package name -along with a set of files comprising your new module. You can then -edit FooBar.pm to look something like this: - - package MyOrg::Template::Plugin::FooBar; - - use Template::Plugin; - use vars qw( $VERSION ); - use base qw( Template::Plugin ); - - $VERSION = 1.23; - - sub new { - my ($class, $context, @params) = @_; - - bless { - _CONTEXT => $context, - foo => 25, - people => [ 'tom', 'dick', 'harry' ], - }, $class; - } - - sub bar { - my ($self, @params) = @_; - # ...do something... - return $some_value; - } - -The plugin constructor new() receives the class name as the first -parameter, as is usual in Perl, followed by a reference to something -called a Template::Context object. You don't need to worry too much -about this at the moment, other than to know that it's the main -processing object for the Template Toolkit. It provides access to the -functionality of the processor and some plugins may need to -communicate with it. We don't at this stage, but we'll save the -reference anyway in the '_CONTEXT' member. The leading underscore is -a convention which indicates that this item is private and the -Template Toolkit won't attempt to access this member. The other -members defined, 'foo' and 'people' are regular data items which will be -made available to templates using this plugin. Following the context -reference are passed any additional parameters specified with the -USE directive, such as the data source parameter, 'dbi:mSQL:mydbname', -that we used in the earlier DBI example. - -If you used F<h2xs> to create the module stub then you'll already -have a Makefile.PL and you can incite the familiar incantation to -build and install it. Don't forget to add some tests to test.pl! - - perl Makefile.PL - make - make test - make install - -If you don't or can't install it to the regular place for your Perl -modules (perhaps because you don't have the required privileges) then -you can set the PERL5LIB environment variable to specify another location. -If you're using F<ttree> then you can add the following line to your -configuration file instead. This has the effect of add '/path/to/modules' -to the @INC array to a similar end. - -$HOME/.ttreerc: - - perl5lib = /path/to/modules - -One further configuration item must be added to inform the toolkit of -the new package name we have adopted for our plugins: - -$HOME/.ttreerc: - - plugin_base = 'MyOrg::Template::Plugin' - -If you're writing Perl code to control the Template modules directly, -then this value can be passed as a configuration parameter when you -create the module. - - use Template; - - my $template = Template->new({ - PLUGIN_BASE => 'MyOrg::Template::Plugin' - }); - -Now we can create a template which uses this plugin: - - [% INCLUDE header - title = 'FooBar Plugin Test' - %] - - [% USE FooBar %] - - Some values available from this plugin: - [% FooBar.foo %] [% FooBar.bar %] - - The users defined in the 'people' list: - [% FOREACH uid = FooBar.people %] - * [% uid %] - [% END %] - - [% INCLUDE footer %] - -The 'foo', 'bar' and 'people' items of the FooBar plugin are -automatically resolved to the appropriate data items or method calls -on the underlying object. - -Using this approach, it is possible to create application -functionality in a single module which can then be loaded and used on -demand in any template. The simple interface between template -directives and plugin objects allows complex, dynamic content to be -built from a few simple template documents without knowing anything -about the underlying implementation. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 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. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/View.pm b/lib/Template/View.pm deleted file mode 100644 index 6de8d42..0000000 --- a/lib/Template/View.pm +++ /dev/null @@ -1,752 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::View -# -# DESCRIPTION -# A custom view of a template processing context. Can be used to -# implement custom "skins". -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 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. -# -# TODO -# * allowing print to have a hash ref as final args will cause problems -# if you do this: [% view.print(hash1, hash2, hash3) %]. Current -# work-around is to do [% view.print(hash1); view.print(hash2); -# view.print(hash3) %] or [% view.print(hash1, hash2, hash3, { }) %] -# -# REVISION -# $Id: View.pm,v 2.9 2004/01/30 18:36:11 abw Exp $ -# -#============================================================================ - -package Template::View; - -require 5.004; - -use strict; -use vars qw( $VERSION $DEBUG $AUTOLOAD @BASEARGS $MAP ); -use base qw( Template::Base ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.9 $ =~ /(\d+)\.(\d+)/); -$DEBUG = 0 unless defined $DEBUG; -@BASEARGS = qw( context ); -$MAP = { - HASH => 'hash', - ARRAY => 'list', - TEXT => 'text', - default => '', -}; - -$DEBUG = 0; - -#------------------------------------------------------------------------ -# _init(\%config) -# -# Initialisation method called by the Template::Base class new() -# constructor. $self->{ context } has already been set, by virtue of -# being named in @BASEARGS. Remaining config arguments are presented -# as a hash reference. -#------------------------------------------------------------------------ - -sub _init { - my ($self, $config) = @_; - - # move 'context' somewhere more private - $self->{ _CONTEXT } = $self->{ context }; - delete $self->{ context }; - - # generate table mapping object types to templates - my $map = $config->{ map } || { }; - $map->{ default } = $config->{ default } unless defined $map->{ default }; - $self->{ map } = { - %$MAP, - %$map, - }; - - # local BLOCKs definition table - $self->{ _BLOCKS } = $config->{ blocks } || { }; - - # name of presentation method which printed objects might provide - $self->{ method } = defined $config->{ method } - ? $config->{ method } : 'present'; - - # view is sealed by default preventing variable update after - # definition, however we don't actually seal a view until the - # END of the view definition - my $sealed = $config->{ sealed }; - $sealed = 1 unless defined $sealed; - $self->{ sealed } = $sealed ? 1 : 0; - - # copy remaining config items from $config or set defaults - foreach my $arg (qw( base prefix suffix notfound silent )) { - $self->{ $arg } = $config->{ $arg } || ''; - } - - # name of data item used by view() - $self->{ item } = $config->{ item } || 'item'; - - # map methods of form ${include_prefix}_foobar() to include('foobar')? - $self->{ include_prefix } = $config->{ include_prefix } || 'include_'; - # what about mapping foobar() to include('foobar')? - $self->{ include_naked } = defined $config->{ include_naked } - ? $config->{ include_naked } : 1; - - # map methods of form ${view_prefix}_foobar() to include('foobar')? - $self->{ view_prefix } = $config->{ view_prefix } || 'view_'; - # what about mapping foobar() to view('foobar')? - $self->{ view_naked } = $config->{ view_naked } || 0; - - # the view is initially unsealed, allowing directives in the initial - # view template to create data items via the AUTOLOAD; once sealed via - # call to seal(), the AUTOLOAD will not update any internal items. - delete @$config{ qw( base method map default prefix suffix notfound item - include_prefix include_naked silent sealed - view_prefix view_naked blocks ) }; - $config = { %{ $self->{ base }->{ data } }, %$config } - if $self->{ base }; - $self->{ data } = $config; - $self->{ SEALED } = 0; - - return $self; -} - - -#------------------------------------------------------------------------ -# seal() -# unseal() -# -# Seal or unseal the view to allow/prevent new datat items from being -# automatically created by the AUTOLOAD method. -#------------------------------------------------------------------------ - -sub seal { - my $self = shift; - $self->{ SEALED } = $self->{ sealed }; -} - -sub unseal { - my $self = shift; - $self->{ SEALED } = 0; -} - - -#------------------------------------------------------------------------ -# clone(\%config) -# -# Cloning method which takes a copy of $self and then applies to it any -# modifications specified in the $config hash passed as an argument. -# Configuration items may also be specified as a list of "name => $value" -# arguments. Returns a reference to the cloned Template::View object. -# -# NOTE: may need to copy BLOCKS??? -#------------------------------------------------------------------------ - -sub clone { - my $self = shift; - my $clone = bless { %$self }, ref $self; - my $config = ref $_[0] eq 'HASH' ? shift : { @_ }; - - # merge maps - $clone->{ map } = { - %{ $self->{ map } }, - %{ $config->{ map } || { } }, - }; - - # "map => { default=>'xxx' }" can be specified as "default => 'xxx'" - $clone->{ map }->{ default } = $config->{ default } - if defined $config->{ default }; - - # update any remaining config items - my @args = qw( base prefix suffix notfound item method include_prefix - include_naked view_prefix view_naked ); - foreach my $arg (@args) { - $clone->{ $arg } = $config->{ $arg } if defined $config->{ $arg }; - } - push(@args, qw( default map )); - delete @$config{ @args }; - - # anything left is data - my $data = $clone->{ data } = { %{ $self->{ data } } }; - @$data{ keys %$config } = values %$config; - - return $clone; -} - - -#------------------------------------------------------------------------ -# print(@items, ..., \%config) -# -# Prints @items in turn by mapping each to an approriate template using -# the internal 'map' hash. If an entry isn't found and the item is an -# object that implements the method named in the internal 'method' item, -# (default: 'present'), then the method will be called passing a reference -# to $self, against which the presenter method may make callbacks (e.g. -# to view_item()). If the presenter method isn't implemented, then the -# 'default' map entry is consulted and used if defined. The final argument -# may be a reference to a hash array providing local overrides to the internal -# defaults for various items (prefix, suffix, etc). In the presence -# of this parameter, a clone of the current object is first made, applying -# any configuration updates, and control is then delegated to it. -#------------------------------------------------------------------------ - -sub print { - my $self = shift; - - # if final config hash is specified then create a clone and delegate to it - # NOTE: potential problem when called print(\%data_hash1, \%data_hash2); - if ((scalar @_ > 1) && (ref $_[-1] eq 'HASH')) { - my $cfg = pop @_; - my $clone = $self->clone($cfg) - || return; - return $clone->print(@_) - || $self->error($clone->error()); - } - my ($item, $type, $template, $present); - my $method = $self->{ method }; - my $map = $self->{ map }; - my $output = ''; - - # print each argument - foreach $item (@_) { - my $newtype; - - if (! ($type = ref $item)) { - # non-references are TEXT - $type = 'TEXT'; - $template = $map->{ $type }; - } - elsif (! defined ($template = $map->{ $type })) { - # no specific map entry for object, maybe it implements a - # 'present' (or other) method? - if ( $method && UNIVERSAL::can($item, $method) ) { - $present = $item->$method($self); ## call item method - # undef returned indicates error, note that we expect - # $item to have called error() on the view - return unless defined $present; - $output .= $present; - next; ## NEXT - } - elsif ( UNIVERSAL::isa($item, 'HASH' ) - && defined($newtype = $item->{$method}) - && defined($template = $map->{"$method=>$newtype"})) { - } - elsif ( defined($newtype) - && defined($template = $map->{"$method=>*"}) ) { - $template =~ s/\*/$newtype/; - } - elsif (! ($template = $map->{ default }) ) { - # default not defined, so construct template name from type - ($template = $type) =~ s/\W+/_/g; - } - } -# else { -# $self->DEBUG("defined map type for $type: $template\n"); -# } - $self->DEBUG("printing view '", $template || '', "', $item\n") if $DEBUG; - $output .= $self->view($template, $item) - if $template; - } - return $output; -} - - -#------------------------------------------------------------------------ -# view($template, $item, \%vars) -# -# Wrapper around include() which expects a template name, $template, -# followed by a data item, $item, and optionally, a further hash array -# of template variables. The $item is added as an entry to the $vars -# hash (which is created empty if not passed as an argument) under the -# name specified by the internal 'item' member, which is appropriately -# 'item' by default. Thus an external object present() method can -# callback against this object method, simply passing a data item to -# be displayed. The external object doesn't have to know what the -# view expects the item to be called in the $vars hash. -#------------------------------------------------------------------------ - -sub view { - my ($self, $template, $item) = splice(@_, 0, 3); - my $vars = ref $_[0] eq 'HASH' ? shift : { @_ }; - $vars->{ $self->{ item } } = $item if defined $item; - $self->include($template, $vars); -} - - -#------------------------------------------------------------------------ -# include($template, \%vars) -# -# INCLUDE a template, $template, mapped according to the current prefix, -# suffix, default, etc., where $vars is an optional hash reference -# containing template variable definitions. If the template isn't found -# then the method will default to any 'notfound' template, if defined -# as an internal item. -#------------------------------------------------------------------------ - -sub include { - my ($self, $template, $vars) = @_; - my $context = $self->{ _CONTEXT }; - - $template = $self->template($template); - - $vars = { } unless ref $vars eq 'HASH'; - $vars->{ view } ||= $self; - - $context->include( $template, $vars ); - -# DEBUGGING -# my $out = $context->include( $template, $vars ); -# print STDERR "VIEW return [$out]\n"; -# return $out; -} - - -#------------------------------------------------------------------------ -# template($template) -# -# Returns a compiled template for the specified template name, according -# to the current configuration parameters. -#------------------------------------------------------------------------ - -sub template { - my ($self, $name) = @_; - my $context = $self->{ _CONTEXT }; - return $context->throw(Template::Constants::ERROR_VIEW, - "no view template specified") - unless $name; - - my $notfound = $self->{ notfound }; - my $base = $self->{ base }; - my ($template, $block, $error); - - return $block - if ($block = $self->{ _BLOCKS }->{ $name }); - - # try the named template - $template = $self->template_name($name); - $self->DEBUG("looking for $template\n") if $DEBUG; - eval { $template = $context->template($template) }; - - # try asking the base view if not found - if (($error = $@) && $base) { - $self->DEBUG("asking base for $name\n") if $DEBUG; - eval { $template = $base->template($name) }; - } - - # try the 'notfound' template (if defined) if that failed - if (($error = $@) && $notfound) { - unless ($template = $self->{ _BLOCKS }->{ $notfound }) { - $notfound = $self->template_name($notfound); - $self->DEBUG("not found, looking for $notfound\n") if $DEBUG; - eval { $template = $context->template($notfound) }; - - return $context->throw(Template::Constants::ERROR_VIEW, $error) - if $@; # return first error - } - } - elsif ($error) { - $self->DEBUG("no 'notfound'\n") - if $DEBUG; - return $context->throw(Template::Constants::ERROR_VIEW, $error); - } - return $template; -} - - -#------------------------------------------------------------------------ -# template_name($template) -# -# Returns the name of the specified template with any appropriate prefix -# and/or suffix added. -#------------------------------------------------------------------------ - -sub template_name { - my ($self, $template) = @_; - $template = $self->{ prefix } . $template . $self->{ suffix } - if $template; - - $self->DEBUG("template name: $template\n") if $DEBUG; - return $template; -} - - -#------------------------------------------------------------------------ -# default($val) -# -# Special case accessor to retrieve/update 'default' as an alias for -# '$map->{ default }'. -#------------------------------------------------------------------------ - -sub default { - my $self = shift; - return @_ ? ($self->{ map }->{ default } = shift) - : $self->{ map }->{ default }; -} - - -#------------------------------------------------------------------------ -# AUTOLOAD -# - -# Returns/updates public internal data items (i.e. not prefixed '_' or -# '.') or presents a view if the method matches the view_prefix item, -# e.g. view_foo(...) => view('foo', ...). Similarly, the -# include_prefix is used, if defined, to map include_foo(...) to -# include('foo', ...). If that fails then the entire method name will -# be used as the name of a template to include iff the include_named -# parameter is set (default: 1). Last attempt is to match the entire -# method name to a view() call, iff view_naked is set. Otherwise, a -# 'view' exception is raised reporting the error "no such view member: -# $method". -#------------------------------------------------------------------------ - -sub AUTOLOAD { - my $self = shift; - my $item = $AUTOLOAD; - $item =~ s/.*:://; - return if $item eq 'DESTROY'; - - if ($item =~ /^[\._]/) { - return $self->{ _CONTEXT }->throw(Template::Constants::ERROR_VIEW, - "attempt to view private member: $item"); - } - elsif (exists $self->{ $item }) { - # update existing config item (e.g. 'prefix') if unsealed - return $self->{ _CONTEXT }->throw(Template::Constants::ERROR_VIEW, - "cannot update config item in sealed view: $item") - if @_ && $self->{ SEALED }; - $self->DEBUG("accessing item: $item\n") if $DEBUG; - return @_ ? ($self->{ $item } = shift) : $self->{ $item }; - } - elsif (exists $self->{ data }->{ $item }) { - # get/update existing data item (must be unsealed to update) - if (@_ && $self->{ SEALED }) { - return $self->{ _CONTEXT }->throw(Template::Constants::ERROR_VIEW, - "cannot update item in sealed view: $item") - unless $self->{ silent }; - # ignore args if silent - @_ = (); - } - $self->DEBUG(@_ ? "updating data item: $item <= $_[0]\n" - : "returning data item: $item\n") if $DEBUG; - return @_ ? ($self->{ data }->{ $item } = shift) - : $self->{ data }->{ $item }; - } - elsif (@_ && ! $self->{ SEALED }) { - # set data item if unsealed - $self->DEBUG("setting unsealed data: $item => @_\n") if $DEBUG; - $self->{ data }->{ $item } = shift; - } - elsif ($item =~ s/^$self->{ view_prefix }//) { - $self->DEBUG("returning view($item)\n") if $DEBUG; - return $self->view($item, @_); - } - elsif ($item =~ s/^$self->{ include_prefix }//) { - $self->DEBUG("returning include($item)\n") if $DEBUG; - return $self->include($item, @_); - } - elsif ($self->{ include_naked }) { - $self->DEBUG("returning naked include($item)\n") if $DEBUG; - return $self->include($item, @_); - } - elsif ($self->{ view_naked }) { - $self->DEBUG("returning naked view($item)\n") if $DEBUG; - return $self->view($item, @_); - } - else { - return $self->{ _CONTEXT }->throw(Template::Constants::ERROR_VIEW, - "no such view member: $item"); - } -} - - -1; - - -__END__ - -=head1 NAME - -Template::View - customised view of a template processing context - -=head1 SYNOPSIS - - # define a view - [% VIEW view - # some standard args - prefix => 'my_', - suffix => '.tt2', - notfound => 'no_such_file' - ... - - # any other data - title => 'My View title' - other_item => 'Joe Random Data' - ... - %] - # add new data definitions, via 'my' self reference - [% my.author = "$abw.name <$abw.email>" %] - [% my.copy = "© Copyright 2000 $my.author" %] - - # define a local block - [% BLOCK header %] - This is the header block, title: [% title or my.title %] - [% END %] - - [% END %] - - # access data items for view - [% view.title %] - [% view.other_item %] - - # access blocks directly ('include_naked' option, set by default) - [% view.header %] - [% view.header(title => 'New Title') %] - - # non-local templates have prefix/suffix attached - [% view.footer %] # => [% INCLUDE my_footer.tt2 %] - - # more verbose form of block access - [% view.include( 'header', title => 'The Header Title' ) %] - [% view.include_header( title => 'The Header Title' ) %] - - # very short form of above ('include_naked' option, set by default) - [% view.header( title => 'The Header Title' ) %] - - # non-local templates have prefix/suffix attached - [% view.footer %] # => [% INCLUDE my_footer.tt2 %] - - # fallback on the 'notfound' template ('my_no_such_file.tt2') - # if template not found - [% view.include('missing') %] - [% view.include_missing %] - [% view.missing %] - - # print() includes a template relevant to argument type - [% view.print("some text") %] # type=TEXT, template='text' - - [% BLOCK my_text.tt2 %] # 'text' with prefix/suffix - Text: [% item %] - [% END %] - - # now print() a hash ref, mapped to 'hash' template - [% view.print(some_hash_ref) %] # type=HASH, template='hash' - - [% BLOCK my_hash.tt2 %] # 'hash' with prefix/suffix - hash keys: [% item.keys.sort.join(', ') - [% END %] - - # now print() a list ref, mapped to 'list' template - [% view.print(my_list_ref) %] # type=ARRAY, template='list' - - [% BLOCK my_list.tt2 %] # 'list' with prefix/suffix - list: [% item.join(', ') %] - [% END %] - - # print() maps 'My::Object' to 'My_Object' - [% view.print(myobj) %] - - [% BLOCK my_My_Object.tt2 %] - [% item.this %], [% item.that %] - [% END %] - - # update mapping table - [% view.map.ARRAY = 'my_list_template' %] - [% view.map.TEXT = 'my_text_block' %] - - - # change prefix, suffix, item name, etc. - [% view.prefix = 'your_' %] - [% view.default = 'anyobj' %] - ... - -=head1 DESCRIPTION - -TODO - -=head1 METHODS - -=head2 new($context, \%config) - -Creates a new Template::View presenting a custom view of the specified -$context object. - -A reference to a hash array of configuration options may be passed as the -second argument. - -=over 4 - -=item prefix - -Prefix added to all template names. - - [% USE view(prefix => 'my_') %] - [% view.view('foo', a => 20) %] # => my_foo - -=item suffix - -Suffix added to all template names. - - [% USE view(suffix => '.tt2') %] - [% view.view('foo', a => 20) %] # => foo.tt2 - -=item map - -Hash array mapping reference types to template names. The print() -method uses this to determine which template to use to present any -particular item. The TEXT, HASH and ARRAY items default to 'test', -'hash' and 'list' appropriately. - - [% USE view(map => { ARRAY => 'my_list', - HASH => 'your_hash', - My::Foo => 'my_foo', } ) %] - - [% view.print(some_text) %] # => text - [% view.print(a_list) %] # => my_list - [% view.print(a_hash) %] # => your_hash - [% view.print(a_foo) %] # => my_foo - - [% BLOCK text %] - Text: [% item %] - [% END %] - - [% BLOCK my_list %] - list: [% item.join(', ') %] - [% END %] - - [% BLOCK your_hash %] - hash keys: [% item.keys.sort.join(', ') - [% END %] - - [% BLOCK my_foo %] - Foo: [% item.this %], [% item.that %] - [% END %] - -=item method - -Name of a method which objects passed to print() may provide for presenting -themselves to the view. If a specific map entry can't be found for an -object reference and it supports the method (default: 'present') then -the method will be called, passing the view as an argument. The object -can then make callbacks against the view to present itself. - - package Foo; - - sub present { - my ($self, $view) = @_; - return "a regular view of a Foo\n"; - } - - sub debug { - my ($self, $view) = @_; - return "a debug view of a Foo\n"; - } - -In a template: - - [% USE view %] - [% view.print(my_foo_object) %] # a regular view of a Foo - - [% USE view(method => 'debug') %] - [% view.print(my_foo_object) %] # a debug view of a Foo - -=item default - -Default template to use if no specific map entry is found for an item. - - [% USE view(default => 'my_object') %] - - [% view.print(objref) %] # => my_object - -If no map entry or default is provided then the view will attempt to -construct a template name from the object class, substituting any -sequence of non-word characters to single underscores, e.g. - - # 'fubar' is an object of class Foo::Bar - [% view.print(fubar) %] # => Foo_Bar - -Any current prefix and suffix will be added to both the default template -name and any name constructed from the object class. - -=item notfound - -Fallback template to use if any other isn't found. - -=item item - -Name of the template variable to which the print() method assigns the current -item. Defaults to 'item'. - - [% USE view %] - [% BLOCK list %] - [% item.join(', ') %] - [% END %] - [% view.print(a_list) %] - - [% USE view(item => 'thing') %] - [% BLOCK list %] - [% thing.join(', ') %] - [% END %] - [% view.print(a_list) %] - -=item view_prefix - -Prefix of methods which should be mapped to view() by AUTOLOAD. Defaults -to 'view_'. - - [% USE view %] - [% view.view_header() %] # => view('header') - - [% USE view(view_prefix => 'show_me_the_' %] - [% view.show_me_the_header() %] # => view('header') - -=item view_naked - -Flag to indcate if any attempt should be made to map method names to -template names where they don't match the view_prefix. Defaults to 0. - - [% USE view(view_naked => 1) %] - - [% view.header() %] # => view('header') - -=back - -=head2 print( $obj1, $obj2, ... \%config) - -TODO - -=head2 view( $template, \%vars, \%config ); - -TODO - -=head1 AUTHOR - -Andy Wardley E<lt>abw@kfs.orgE<gt> - -=head1 REVISION - -$Revision: 2.9 $ - -=head1 COPYRIGHT - -Copyright (C) 2000 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. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, - -=cut - - - - - |
