use Template3; # simple all-in-one method to process a template Template3->process($input, $data, $output); # or for fine control Template3->render( input => $input, data => $data, output => $output, # plus any other environment options ); # creating a Template3 object my $tt3 = Template3->new( template_path => '/path/to/templates', header => 'site/header.tt3', footer => 'site/footer.tt3', ); # then use it $tt3->process('hello.tt3', { name => 'World' }); # or $tt3->render( input => 'hello.tt3', data => { name => 'World' }, output => 'hello.html', );
This documentation has been inherited from a previous prototype of TT3 and hasn't yet been fully edited to reflect the changes to the way the module works. As a result, some of the documentation may be incomplete and/or incorrect.
The Template3 module provides a simple interface to the Template Toolkit for Perl programmers. It is implemented as a thin wrapper around a Template::TT3::Engine object which is responsible for doing the real work of processing templates. The default engine is Template::TT3::Engine::TT3 which implements version 3 of the Template Toolkit language.
The Template3 module will eventually replace the current Template module from TT2. Until then we must write:
use Template3;
However, when TT3 is finally released (on Tuesday, some time shortly after
lunch), we will be able to drop the '3' and just use the Template
module:
use Template; # no '3'
At this point, anyone who is relying on the Template
module to work as it
currently does with TT2 will be sorely disappointed. TT3 has been completely
re-designed and re-built from the ground up and nothing is guaranteed to work
the same (although most things are quite similar).
For further information about backward compatibility with version 2 of the Template Toolkit, please see Template::TT3::Manual::Compatibility .
To use the module you must first load it into your Perl program:
use Template3;
There are a number of options you can specify when loading the module. See LOAD OPTIONS below for further details.
You can use the module by calling Template3 class methods directly:
Template3->process($input, $data, $output);
Or by creating a Template3
object and calling methods against it:
my $tt3 = Template3->new; $tt3->process($input, $data, $output);
The METHODS section below contains details of all the methods available. See CLASS METHODS following that for further details on how class methods are delegated to a prototype object.
The following options can be specified when you use
the Template3
module.
The Template3
module is implemented as a thin wrapper around a
Template::TT3::Engine
object which is responsible for doing the real work
of processing templates.
The default engine is Template::TT3::Engine::TT3 , implementing the TT3 API for the Template Toolkit. This is slightly different to the TT2 API (UPDATE: in fact it might not be that different after all).
The engine
option allows you to specify the engine module that you want to
use.
use Template3 engine => 'Template::TT3::Engine::TT2';
You can drop the Template::TT3::Engine
prefix and leave it up to the
Template::TT3::Engines
factory module to find and load the relevant
module for you.
use Template3 engine => 'TT2';
Shorthand for engaging the TT2
engine and creating a TT2
alias.
use Template3 'TT2'; my $tt2 = TT2->new;
It is equivalent to:
use Template3 engine => 'TT2', as => 'TT2';
Shorthand for engaging the TT3
engine and creating a TT3
alias.
use Template 'TT3'; my $tt3 = TT3->new;
It is equivalent to:
use Template3 engine => 'TT3', as => 'TT3';
We should have other options for configuring the prototype engine. e.g.
use Template3 template_path => '/path/to/templates', dialect => 'TT3';
Hmmm... that's going to be tricky. It requires us to know about all the options that any engine/dialect/service/etc could implement (not feasible) or to blindly accept any options which is sub-optimal (no way to automatically detect typos, invalid options, etc). Probably better to have an explicit config option.
use Template3 config => { template_path => '/path/to/templates', dialect => 'TT3', };
We could perhaps also allow a config file:
use Template3 config => '/path/to/config/file.yaml'; # detect codec from extension
Please note that the following list is incomplete. This is partly because I haven't got around to documenting them yet, and partly because there are so many of them that I haven't decided which ones should go here and which should be relegated to the longer Template::TT3::Manual::Config documentation. Furthermore, there are a number of configuration options which should work, and do work (as far as I'm aware), but don't yet have tests explicitly proving that they work. At that point in time I'd rather document the stuff that I know works and add other items as and when I write the tests for them.
TODO: Explain how TT3 is built from a large number of small, (mostly) simple components. They all have their own configuration options. The Template3 module is a thin wrapper around Template::TT3::Engine::TT3 (or whatever other engine you explicitly select). The engine creates a Template::TT3::Hub which acts as the central repository for all the things we might need. We pass the entire configuration hash over to the hub and then leave it up to the hub to create whatever we need (templates providers, dialects, context objects, and so on). The hub ensures that the constructor for each component gets a copy of the config (or the relevant sub-section within it). So in summary, you can specify any option supported by any sub-component of TT3 and it should (fingers crossed) get forwarded to the components's constructor.
TODO: Template::TT3::Manual::Config will eventually contain the full description of all the options. This section should contain a summary of the most important options.
This option allows you to specify the template dialect that you want to use. At present there is only one dialect: TT3. A TT2 dialect will be provided in the near future, offering something very similar to the current TT2 language, but implemented using the new TT3 parser. You can also create your own dialects, either to customise TT3 or to plug in an entirely different template language. Until I've had the chance to write more about this, you might like to consult the slides from my London Perl Workshop talk which shows a trivial example of creating a custom dialect. http://tt3.template-toolkit.org/talks/tt3-lpw2009/slides/slide17.html .
my $tt3 = Template3->new( dialect => 'TT2' # no TT2 dialect yet - coming RSN );
This option allows you to specify the location of templates as a single value or a reference to a list of values.
# single location my $tt3 = Template3->new( template_path => '/path/to/templates' ); # multiple locations my $tt3 = Template3->new( template_path => [ '/path/one', '/path/two' ] );
Each item in the path can be a reference to a hash array containing the path and any other configuration items relating to the templates loaded from that location. The following example shows how you can define a template path that loads TT2 templates from one location and TT3 templates from another (note that the TT2 dialect isn't implemented yet, so this is theoretical - however, the dialect switching does work)
my $tt3 = Template3->new( template_path => [ { path => '/path/to/templates/tt3', dialect => 'TT3', }, { path => '/path/to/templates/tt2', dialect => 'TT2', } ] );
If you don't specify a template_path
then TT3 will allow you to access
any file on the filesystem. Templates specified with relative path names
will be resolved relative to the current working directory.
use Template3; Template3->process('hello.tt3'); # in current directory Template3->process('../hello.tt3'); # in parent directory Template3->process('/tmp/hello.tt3'); # absolute path
This option allows you to specify a header template that should be processed before each main page template. The output from the footer is added to the start of the main page output. This affects templates processed using the process() or render() methods().
my $tt3 = Template3->new( header => 'site/header.tt3', );
This option allows you to specify a footer template that should be processed after each main page template. The output from the footer is added to the end of the main page output. This affects templates processed using the process() or render() methods().
my $tt3 = Template3->new( header => 'site/header.tt3', );
This option allows you to specify a wrapper template that should be used to
enclose the output from the main page template. The wrapper template is
processed, passing the output generated from the main page template as the
content
variable. This affects templates processed using the
process()
or
render()
methods().
my $tt3 = Template3->new( wrapper => 'site/wrapper.tt3', );
TT3 uses a new service pipeline architecture for processing templates. The pipeline is defined as a number of service components, each of which does one small and simple thing.
The default pipeline is defined as:
input => header => footer => wrapper => output
The input
service deals with fetching and processing the main page
template. The
header
,
footer
and
wrapper
components decorate
the output by adding headers, footers and wrappers respectively. The
output
component emits the generated content to a file, file handle,
object, or simply returns it if no output target has been specified.
Each of these service components has a corresponding option that can be specified as a configuration option (see header , footer and wrapper ) and/or as an option to the render() method.
$tt3->render( input => 'example.tt3', header => 'site/header.tt3', footer => 'site/footer.tt3', );
If you want to do something more complicated then you can defined your own
service pipeline. For example, if you want two different headers, one which
we'll call the site_header
and the other, the section_header
, then you
can write something like this:
my $tt3 = Template3->new( service => [ 'header:site_header', # type:name is sugar for: 'header:section_header', # { type=>$type, name=>$name } 'footer', ], site_header => 'site/header.tt3', # default site header footer => 'site/footer.tt3', # default site footer section_header => '', # no default section header );
Note that you must specify a defined but false value for any components
that don't have a default template (e.g. section_header
in the above
example). Otherwise the service component will be optimised out of the
pipeline and you'll be denied from using it later (this optimisation means
that you don't pay any penalty for things like
header
,
footer
and
wrapper
if you don't use them).
Note that the input
and output
service components are added
automatically. I'm not 100% sure that this is a good idea so it may
change in the near future.
Now you can call the render() method and configure the environment to affect any of the service components.
$tt3->render( input => 'hello.tt3', section_header => 'welcome/header.tt3', );
TODO: list base classes
Constructor method. Accepts a list or reference to a hash array of named parameters.
# list of named parameters my $tt3 = Template3->new( path => $path ); # hash reference of named parameters my $tt3 = Template3->new({ path => $path });
See CONFIGURATION OPTIONS for a full list of configuration options.
NOTE: the parameters for these methods aren't nailed down yet... they still might end up more like TT2's process($input, $vars, $output) UPDATE: yes, I think they will... we'll keep process() being the all-in-one ($input, $data, $output) method and provide others (like fill()) for lower level stuff.
Method to process a template and return the output generated. Accepts
a list or hash reference of named parameters. The template will be loaded
from the file
specified, or from the source text
provided. Template
variables can be provided using the vars
parameter.
# template file print $tt3->process( file => '/path/to/file.tt3', vars => $vars ); # template text print $tt3->process( text => "Hello [% name %]", vars => $vars );
Any errors are thrown as exceptions using Perl's die
. You can use
the
try
method (inherited from
Badger::Base
)
if you want to "downgrade" any exception errors to false values. The
error()
method can be called to examine the error
raised.
$tt3->try->process($input, $data, $output) || print "FAIL: ", $tt3->error;
The above example is equivalent to:
eval { $tt3->process($input, $data, $output) }; if ($@) { print "FAIL: ", $tt3->error; }
Errors are returned as
exception
objects, but you
can safely print
them to see a summary of the error type and message.
This method does the same thing as process() but using named parameters.
$tt3->render( input => 'example.tt3', data => { name => 'World' }, output => 'example.html', );
The named parameters define an environment that is passed to the
service
pipeline. In addition to the input
, data
and output
options
corresponding to the positional arguments of the
process()
method, the
environment can also contain parameters that affect other components in
the service pipeline.
$tt3->render( input => 'example.tt3', data => { name => 'World' }, output => 'example.html', header => 'site/header.tt3', footer => 'site/footer.tt3', );
This is a low-level method for processing a single template and returning the output generated. The service pipeline is bypassed, so you don't get any extra headers, footers, output redirection or anything else like that.
my $output = $tt3->fill( file => 'example.tt3', data => { name => 'Badger' }, ); my $output = $tt3->fill( text => 'Hello [% name %]', data => { name => 'Badger' }, );
The arguments are a little clumsy at present. They may get changed in the near future as part of a general cleaned and consistency drive.
Returns the prototype object. This method is inherited from Badger::Protoype . See CLASS METHODS .
When you call a Template3 class method it is delegated to a prototype object for that class. The prototype object will be automagically created (by the prototype() method) and cached for subsequent use.
So calling a class method like this:
Template3->process($file);
is directly equivalent to calling an object method against the class prototype, like this:
Template3->prototype->process($file);
The
prototype()
method creates a new object by calling the
new()
class method. It then stores the returned object in the class $PROTOTYPE
variable and returns this cached object on subsequent calls.
Note that you can configure the prototype object by calling the config() method.
NOTE: this doesn't work yet...
Template3->config( path => $path );
Or explicitly:
Template3->prototype->config( path => $path ); # same thing as above
The object returned by the prototype() method will be an instance of the engine class in use (as created by the new() method). The following sections describes engines in further detail.
Andy Wardley http://wardley.org/