NAME
HTML::Template::Compiled - Template System Compiles HTML::Template files to Perl code
VERSION
our $VERSION = "0.34";
SYNOPSIS
use HTML::Template::Compiled;
my $htc = HTML::Template::Compiled->new(filename => 'test.tmpl');
$htc->param(
BAND => $name,
ALBUMS = [
{ TITLE => $t1, YEAR => $y1 },
{ TITLE => $t2, YEAR => $y2 },
],
);
print $htc->output;
test.tmpl:
Band: <TMPL_VAR BAND>
<TMPL_LOOP ALBUMS>
Title: <TMPL_VAR TITLE> (<TMPL_VAR YEAR>)
</TMPL_LOOP>
DESCRIPTION
HTML::Template::Compiled (HTC) is a template system which uses the same template syntax as HTML::Template and the same perl API. Internally it works different, because it turns the template into perl code, and once that is done, generating the output is much quicker (20 times) than with HTML::Template (at least with my tests). It also can generate perl files so that the next time the template is loaded it doesn't have to be parsed again. The best performance gain is probably reached in applications running under mod_perl, for example.
HTC does not implement all features of HTML::Template (yet), and it has got some additional features which are explained below.
HTC will complain if you have a closing tag that does not fit the last opening tag. To get the line number, set the line_numbers-option (See "OPTIONS" below)
FEATURES FROM HTML::TEMPLATE
- TMPL_VAR
- TMPL_LOOP
- TMPL_(IF|UNLESS|ELSE)
- TMPL_INCLUDE
- HTML_TEMPLATE_ROOT
- ESCAPE=(HTML|URI)
__first__
,__last__
,__inner__
,__odd__
,__counter__
- <!-- TMPL_VAR NAME=PARAM1 -->
- case insensitive var names
-
use option case_insensitive => 1 to use this feature
ADDITIONAL FEATURES
- TMPL_ELSIF
- TMPL_WITH
- Generating perl code
- more variable access
- rendering objcets
- asp/jsp-like templates
-
For those who like it (i like it because it is shorter than TMPL_), you can use <% %> tags and the <%= tag instead of <%VAR (which will work, too):
<%IF blah%> <%= VARIABLE%> <%/IF>
MISSING FEATURES
There are some features of H::T that are missing and that I don't plan to implement. I'll try to list them here.
global_vars
-
No, I don't want to look in the whole hash for a var name. If you want to use a variable, you should know where it is.
die_on_bad_params
-
I don't think I'll implement that in the near future.
VARIABLE ACCESS
With HTC, you have more control over how you access your template parameters. An example:
my %hash = (
SELF => '/path/to/script.pl',
LANGUAGE => 'de',
BAND => 'Bauhaus',
ALBUMS => [
{
NAME => 'Mask',
SONGS => [ { NAME => 'Hair of the Dog' }, ... ],
},
],
INFO => {
BIOGRAPHY => '...',
LINK => '...'
},
);
Now in the TMPL_LOOP ALBUMS
you would like to access the path to your script, stored in $hash{SELF}. in HTML::Template you have to set the option global_vars
, so you can access $hash{SELF}
from everywhere. Unfortunately, now NAME
is also global, which isn't a problem in this simple example, but in a more complicated template this is impossible. With HTC, you don't have global_vars
, but you can say:
<TMPL_VAR .SELF>
to access the root element, and you could even say .INFO.BIOGRAPHY
or ALBUMS.0.SONGS.0.NAME
RENDERING OBJECTS
This is still experimental. You have been warned.
Additionally to feeding a simple hash do HTC, you can feed it objects. To do method calls you can use '->' in the template or define a different string if you don't like that.
my $htc = HTML::Template::Compiled->new(
...
method_call => '.', # default ->
deref => '/', # default .
);
$htc->param(
VAR => "blah",
OBJECT => bless({...}, "Your::Class"),
);
<TMPL_VAR NAME="OBJECT.fullname">
<TMPL_WITH OBJECT>
Name: <TMPL_VAR _.fullname>
</TMPL_WITH>
fullname
will call the fullname method of your Your::Class object. You have to use _
here because with using only fullname
HTC couldn't know if you want to dereference a hash or do a method call.
The default values might change in the future depending on what people use most, so at the moment it's the best to always set the options.
And please don't set deref and method call to the same value - this won't work.
DEBUGGING
For printing out the contents of all the parameters you can do:
<TMPL_LOOP ALBUMS>
Dump: <TMPL_VAR _>
</TMPL_LOOP>
The special name _
will give you a Data::Dumper output of the current variable, in this case it will dump out the contents of every album in a loop.
TMPL_WITH
If you have a deep leveled hash you might not want to write THE.FULL.PATH.TO.YOUR.VAR always. Jump to your desired level once and then you need only one level. Compare:
<TMPL_WITH DEEP.PATH.TO.HASH>
<TMPL_VAR NAME>: <TMPL_VAR AGE>
</TMPL_WITH>
<TMPL_VAR DEEP.PATH.TO.HASH.NAME>: <TMPL_VAR DEEP.PATH.TO.HASH.AGE>
Options
- path
-
Path to template files
- cache_dir
-
Path to caching directory (you have to create it before)
- filename
-
Template to parse
- loop_context_vars
-
Vars like
__first__
,__last__
,__inner__
,__odd__
,__counter__
- deref
-
Define the string you want to use for dereferencing, default is
.
at the moment:<TMPL_VAR hash.key>
- method_call
-
Define the string you want to use for method calls, default is -> at the moment:
<TMPL_VAR object->method>
- line_numbers
-
For debugging: prints the line number of the wrong tag, e.g. if you have a /TMPL_IF that does not have an opening tag.
- case_insensitive
-
default is 0, set it to 1 to use this feature like in HTML::Template. Note that this can slow down your program
EXPORT
None.
CACHING
You create a template almost like in HTML::Template:
my $t1 = HTML::Template::Compiled->new(
path => 'templates',
loop_context_vars => 1,
filename => 'test.html',
# for testing without cache comment out
cache_dir => "cache",
);
The next time you start your application, HTC will read all generated perl files, and a call to the constructor like above won't parse the template, but just use the loaded code. If your template file has changed, though, then it will be parsed again.
You can set $HTML::Template::Compiled::NEW_CHECK to the amount of seconds you want to wait until the template is expired. So $HTML::Template::Compiled::NEW_CHECK = 60 * 10;
will check after 10 minutes if the tmpl file was modified. Set it to a very high value will then ignore any changes, until you delete the generated code.
TODO
Better access to cached perl files, scalarref, filehandle, debugging option, filters, query, using File::Spec for portability, fixing HTC-Main.pm, maybe implement expressions, ...
BUGS
Probably many more bugs I don't know yet =)
Why another Template System?
You might ask why I implement yet another templating system. There are so many to choose from. Well, there are several reasons.
I like the syntax of HTML::Template *because* it is very restricted. It's also easy to use (template syntax and API). However, there are some things I miss I try to implement here.
I think while HTML::Template is quite good, the implementation can be made more efficient (and still pure Perl). That's what I'm trying to achieve.
I use it in my web applications, so I first write it for myself =) If I can efficiently use it, it was worth it.
SEE ALSO
http://www.tinita.de/projects/perl/
AUTHOR
Tina Mueller
CREDITS
Bjoern Kriews (Original Idea)
Ronnie Neumann, Martin Fabiani for ideas and beta-testing
COPYRIGHT AND LICENSE
Copyright (C) 2005 by Tina Mueller
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.3 or, at your option, any later version of Perl 5 you may have available.