Initial Commit
This commit is contained in:
1920
database/perl/vendor/lib/Template/Manual/Config.pod
vendored
Normal file
1920
database/perl/vendor/lib/Template/Manual/Config.pod
vendored
Normal file
File diff suppressed because it is too large
Load Diff
113
database/perl/vendor/lib/Template/Manual/Credits.pod
vendored
Normal file
113
database/perl/vendor/lib/Template/Manual/Credits.pod
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Credits
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2020 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.
|
||||
#
|
||||
#========================================================================
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Manual::Credits - Author and contributor credits
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The Template Toolkit began its life as the C<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/)
|
||||
|
||||
C<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.
|
||||
(CRE), 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.
|
||||
|
||||
Version 3 has been in development ever since.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2020 Andy Wardley. All Rights Reserved.
|
||||
|
||||
The Template Toolkit is free software; you can redistribute it and/or
|
||||
modify it under the same terms as Perl itself.
|
||||
|
||||
=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.
|
||||
|
||||
If you submit a patch/pull request then please make sure you add your
|
||||
own name to this list and include it in the changes.
|
||||
|
||||
Adam Kennedy, ahollandECS, Alexey A. Kiritchun, Amiri Barksdale, Andreas Koenig,
|
||||
Andy Wardley, Autrijus Tang, Axel Gerstmair, Barrie Slaymaker, Ben Tilly,
|
||||
Breno G. de Oliveira, Briac PilprE<eacute>, Brian Fraser, Brian Wightman,
|
||||
Bryce Harrington, Chris Dean, Chris Winters, Christian, chromatic, Colin Johnson,
|
||||
Colin Keith, Craig Barratt, Darren Chamberlain, Dave Cash, Dave Cross, Dave Hodgkinson,
|
||||
Dave Howorth, Dave Jacoby, David Steinbrunner, Denis F. Latypoff, Dennis Clark,
|
||||
Doug, Drew Taylor, Dylan, E. Choroba, eadjei, Eric Cholet, Francois Desarmenien,
|
||||
François Andriot, fREW Schmidt, gordon-fish, Guido Flohr, Hans von Lengerke,
|
||||
Harald Joerg, Horst Dumcke, Ivan Krylov, Ivan Kurmanov, Jacques Germishuys,
|
||||
Jason Lewis, Jay Hannah, Jens Rehsack, Jess Robinson, Jim Vaughan, John Lightsey,
|
||||
John Napiorkowski, Jon Jensen, Jonas Liljegren, Jonathon Padfield, José Joaquín Atria,
|
||||
Jose Luis Martinez, Josh Rosenbaum, Kenny Gatdula, Kent Fredric, Kevin M. Goess, Koenig,
|
||||
Leon Brocard, Leslie Michael Orchard, Lubomir, Lyle Brooks, Marc Remy, Mark Fowler,
|
||||
Martin, Matthew Somerville, Michael Fowler, Michael Stevens, Mike Schilli,
|
||||
Mikhail Klyuchnikov from Positive Technologies, nataraj, Neil Bowers, Nick Hibma,
|
||||
Nicolas R, Nik Clayton, Norbert Buchmüller, Paul Orrock, Paul Seamons, Paul Sharpe,
|
||||
Perrin Harkins, Philippe Bruhat (BooK), Piers Cawley, Portman, Rafael Kitover,
|
||||
Randal L. Schwartz, Ricardo Signes, Richard Tietjen, Robin Berjon, Rod Taylor, Schaffner,
|
||||
sdeseille, Sean McAfee, Sean Zellmer, Simon, Simon Dawson, Simon Matthews, Simon Napiorkowski,
|
||||
Slaven Rezic, Smylers, Stas Bekman, Stathy G. Touloumis, stefano-b, Steinwand,
|
||||
Steve Peters, Swen, Thierry-Michel Barral, Thuemmler, Timmy Chan, Todd Rinaldo, Tom Delmas,
|
||||
Tony Bowden, Tosh Cooey, Ville SkyttE<auml>, Vivek Khera, Wilcox, William Hardison,
|
||||
Yanick Champoux, Yuri Pimenov.
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
1970
database/perl/vendor/lib/Template/Manual/Directives.pod
vendored
Normal file
1970
database/perl/vendor/lib/Template/Manual/Directives.pod
vendored
Normal file
File diff suppressed because it is too large
Load Diff
507
database/perl/vendor/lib/Template/Manual/Filters.pod
vendored
Normal file
507
database/perl/vendor/lib/Template/Manual/Filters.pod
vendored
Normal file
@@ -0,0 +1,507 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Filters
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 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.
|
||||
#
|
||||
#========================================================================
|
||||
|
||||
=encoding latin1
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Template::Manual::Filters - Standard filters
|
||||
|
||||
=head1 format(format)
|
||||
|
||||
The C<format> filter takes a format string as a parameter (as per
|
||||
C<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. -->
|
||||
|
||||
=head1 upper
|
||||
|
||||
Folds the input to UPPER CASE.
|
||||
|
||||
[% "hello world" FILTER upper %]
|
||||
|
||||
Output:
|
||||
|
||||
HELLO WORLD
|
||||
|
||||
=head1 lower
|
||||
|
||||
Folds the input to lower case.
|
||||
|
||||
[% "Hello World" FILTER lower %]
|
||||
|
||||
Output:
|
||||
|
||||
hello world
|
||||
|
||||
=head1 ucfirst
|
||||
|
||||
Folds the first character of the input to UPPER CASE.
|
||||
|
||||
[% "hello" FILTER ucfirst %]
|
||||
|
||||
Output:
|
||||
|
||||
Hello
|
||||
|
||||
=head1 lcfirst
|
||||
|
||||
Folds the first character of the input to lower case.
|
||||
|
||||
[% "HELLO" FILTER lcfirst %]
|
||||
|
||||
Output:
|
||||
|
||||
hELLO
|
||||
|
||||
=head1 trim
|
||||
|
||||
Trims any leading or trailing whitespace from the input text. Particularly
|
||||
useful in conjunction with C<INCLUDE>, C<PROCESS>, etc., having the same effect
|
||||
as the C<TRIM> configuration option.
|
||||
|
||||
[% INCLUDE myfile | trim %]
|
||||
|
||||
=head1 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
|
||||
|
||||
=head1 html
|
||||
|
||||
Converts the characters C<E<lt>>, C<E<gt>>, C<&> and C<"> to C<<>,
|
||||
C<>>, C<&>, and C<"> 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...
|
||||
|
||||
=head1 html_entity
|
||||
|
||||
The C<html> filter is fast and simple but it doesn't encode the full
|
||||
range of HTML entities that your text may contain. The C<html_entity>
|
||||
filter uses either the C<Apache::Util> module (which is written in C and
|
||||
is therefore faster) or the C<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 C<escape_html()> or C<encode_entities()> subroutines
|
||||
respectively) to convert all extended characters into their appropriate HTML
|
||||
entities (e.g. converting 'C<?>' to 'C<é>'). If neither module is
|
||||
available on your system then an 'C<html_entity>' exception will be thrown
|
||||
reporting an appropriate message.
|
||||
|
||||
If you want to force TT to use one of the above modules in preference to
|
||||
the other, then call either of the L<Template::Filters> class methods:
|
||||
L<use_html_entities()|Template::Filters/use_html_entities()> or
|
||||
L<use_apache_util()|Template::Filters/use_apache_util()>.
|
||||
|
||||
use Template::Filters;
|
||||
Template::Filters->use_html_entities;
|
||||
|
||||
For further information on HTML entity encoding, see
|
||||
L<http://www.w3.org/TR/REC-html40/sgml/entities.html>.
|
||||
|
||||
=head1 xml
|
||||
|
||||
Same as the C<html> filter, but adds C<'> which is the fifth XML
|
||||
built-in entity.
|
||||
|
||||
=head1 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 C<E<lt>pE<gt>>...C<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>
|
||||
|
||||
=head1 html_break / html_para_break
|
||||
|
||||
Similar to the html_para filter described above, but uses the HTML tag
|
||||
sequence C<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.
|
||||
|
||||
=head1 html_line_break
|
||||
|
||||
This filter replaces any newlines with C<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>
|
||||
|
||||
=head1 uri
|
||||
|
||||
This filter URI escapes the input text, converting any characters
|
||||
outside of the permitted URI character set (as defined by RFC 3986)
|
||||
into a C<%nn> hex escape.
|
||||
|
||||
[% 'my file.html' | uri %]
|
||||
|
||||
Output:
|
||||
|
||||
my%20file.html
|
||||
|
||||
The uri filter correctly encodes all reserved characters, including
|
||||
C<&>, C<@>, C</>, C<;>, C<:>, C<=>, C<+>, C<?> and C<$>. This filter
|
||||
is typically used to encode parameters in a URL that could otherwise
|
||||
be interpreted as part of the URL. Here's an example:
|
||||
|
||||
[% path = 'http://tt2.org/example'
|
||||
back = '/other?foo=bar&baz=bam'
|
||||
title = 'Earth: "Mostly Harmless"'
|
||||
%]
|
||||
<a href="[% path %]?back=[% back | uri %]&title=[% title | uri %]">
|
||||
|
||||
The output generated is rather long so we'll show it split across two
|
||||
lines:
|
||||
|
||||
<a href="http://tt2.org/example?back=%2Fother%3Ffoo%3Dbar%26
|
||||
baz%3Dbam&title=Earth%3A%20%22Mostly%20Harmless%22">
|
||||
|
||||
Without the uri filter the output would look like this (also split across
|
||||
two lines).
|
||||
|
||||
<a href="http://tt2.org/example?back=/other?foo=bar
|
||||
&baz=bam&title=Earth: "Mostly Harmless"">
|
||||
|
||||
In this rather contrived example we've manage to generate both a broken URL
|
||||
(the repeated C<?> is not allowed) and a broken HTML element (the href
|
||||
attribute is terminated by the first C<"> after C<Earth: > leaving C<Mostly
|
||||
Harmless"> dangling on the end of the tag in precisely the way that harmless
|
||||
things shouldn't dangle). So don't do that. Always use the uri filter to
|
||||
encode your URL parameters.
|
||||
|
||||
However, you should B<not> use the uri filter to encode an entire URL.
|
||||
|
||||
<a href="[% page_url | uri %]"> # WRONG!
|
||||
|
||||
This will incorrectly encode any reserved characters like C<:> and C</>
|
||||
and that's almost certainly not what you want in this case. Instead
|
||||
you should use the B<url> (note spelling) filter for this purpose.
|
||||
|
||||
<a href="[% page_url | url %]"> # CORRECT
|
||||
|
||||
Please note that this behaviour was changed in version 2.16 of the
|
||||
Template Toolkit. Prior to that, the uri filter did not encode the
|
||||
reserved characters, making it technically incorrect according to the
|
||||
RFC 2396 specification (since superceded by RFC2732 and RFC3986). So we
|
||||
fixed it in 2.16 and provided the url filter to implement the old behaviour
|
||||
of not encoding reserved characters.
|
||||
|
||||
As of version 2.28 of the Template Toolkit, the C<uri> and L<url> filters
|
||||
use the unsafe character set defined by RFC3986. This means that certain
|
||||
characters ("(", ")", "*", "!", "'", and '"') are now deemed unsafe and
|
||||
will be escaped as hex character sequences.
|
||||
|
||||
The ability to use the RFC3986 character set was added in 2.26 but not
|
||||
enabled by default; double quote was incorrectly deemed safe in 2.26 but
|
||||
correctly escaped in 2.27.
|
||||
|
||||
If you want to enable the old behaviour then call the C<use_rfc2732()>
|
||||
method in L<Template::Filters>
|
||||
|
||||
use Template::Filters
|
||||
Template::Filters->use_rfc2732;
|
||||
|
||||
=head1 url
|
||||
|
||||
The url filter is a less aggressive version of the uri filter. It encodes
|
||||
any characters outside of the permitted URI character set (as defined by RFC 2396)
|
||||
into C<%nn> hex escapes. However, unlike the uri filter, the url filter does
|
||||
B<not> encode the reserved characters C<&>, C<@>, C</>, C<;>, C<:>, C<=>, C<+>,
|
||||
C<?> and C<$>.
|
||||
|
||||
=head1 indent(pad)
|
||||
|
||||
Indents the text block by a fixed pad string or width. The 'C<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
|
||||
|
||||
=head1 truncate(length,dots)
|
||||
|
||||
Truncates the text block to the length specified, or a default length
|
||||
of 32. Truncated text will be terminated with 'C<...>' (i.e. the 'C<...>'
|
||||
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...
|
||||
|
||||
If you want to use something other than 'C<...>' you can pass that as a
|
||||
second argument.
|
||||
|
||||
[% FILTER truncate(26, '…') %]
|
||||
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…
|
||||
|
||||
=head1 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!
|
||||
|
||||
=head1 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
|
||||
|
||||
=head1 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
|
||||
|
||||
=head1 redirect(file, options)
|
||||
|
||||
The C<redirect> filter redirects the output of the block into a separate
|
||||
file, specified relative to the C<OUTPUT_PATH> configuration item.
|
||||
|
||||
[% FOREACH user IN myorg.userlist %]
|
||||
[% FILTER redirect("users/${user.id}.html") %]
|
||||
[% INCLUDE userinfo %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
or more succinctly, using side-effect notation:
|
||||
|
||||
[% FOREACH user IN myorg.userlist;
|
||||
INCLUDE userinfo
|
||||
FILTER redirect("users/${user.id}.html");
|
||||
END
|
||||
%]
|
||||
|
||||
A C<file> exception will be thrown if the C<OUTPUT_PATH> option is undefined.
|
||||
|
||||
An optional C<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 C<binmode> option
|
||||
as shown in the first example.
|
||||
|
||||
=head1 eval / evaltt
|
||||
|
||||
The C<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 C<evaltt> filter is provided as an alias for C<eval>.
|
||||
|
||||
=head1 perl / evalperl
|
||||
|
||||
The C<perl> filter evaluates the block as Perl code. The C<EVAL_PERL>
|
||||
option must be set to a true value or a C<perl> exception will be
|
||||
thrown.
|
||||
|
||||
[% my_perl_code | perl %]
|
||||
|
||||
In most cases, the C<[% PERL %]> ... C<[% 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 C<evalperl> filter is provided as an alias for C<perl> for backwards
|
||||
compatibility.
|
||||
|
||||
=head1 stdout(options)
|
||||
|
||||
The stdout filter prints the output generated by the enclosing block to
|
||||
C<STDOUT>. The C<binmode> option can be passed as either a named parameter
|
||||
or a single argument to set C<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 C<stdout> filter can be used to force C<binmode> on C<STDOUT>, or also
|
||||
inside C<redirect>, C<null> or C<stderr> blocks to make sure that particular
|
||||
output goes to C<STDOUT>. See the C<null> filter below for an example.
|
||||
|
||||
=head1 stderr
|
||||
|
||||
The stderr filter prints the output generated by the enclosing block to
|
||||
C<STDERR>.
|
||||
|
||||
=head1 null
|
||||
|
||||
The C<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 C<stdout> filter to ensure that a particular expression
|
||||
generates output to C<STDOUT> (in this case in binary mode).
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
452
database/perl/vendor/lib/Template/Manual/Internals.pod
vendored
Normal file
452
database/perl/vendor/lib/Template/Manual/Internals.pod
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Internals
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 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 NAME
|
||||
|
||||
Template::Manual::Internals - Template Toolkit internals
|
||||
|
||||
=head1 Introduction
|
||||
|
||||
This section of the documentation is aimed at developers wishing to
|
||||
know more about how the Template Toolkit works on the inside in order
|
||||
to extend or adapt it to their own needs.
|
||||
|
||||
If that doesn't sound like you then you probably don't need to read this.
|
||||
There is no test afterwards.
|
||||
|
||||
=head1 Outside Looking In
|
||||
|
||||
The L<Template> module is simply a front end module which creates and
|
||||
uses a L<Template::Service> and pipes the output wherever you want it to
|
||||
go (C<STDOUT> by default, or maybe a file, scalar, etc). The
|
||||
C<Apache::Template> module (available separately from CPAN) is another
|
||||
front end. That creates a C<Template::Service::Apache> object, calls on
|
||||
it as required and sends the output back to the relevant
|
||||
C<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 C<Apache::Template>
|
||||
front end, for example, handles C<Apache::Request> specifics and
|
||||
configuration via the F<httpd.conf>. The regular L<Template> front-end
|
||||
deals with C<STDOUT>, variable refs, etc. Otherwise it is
|
||||
L<Template::Service> (or subclass) which does all the work.
|
||||
|
||||
The L<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.
|
||||
L<Template::Service> hides that all away and makes everything look simple to
|
||||
the outsider. It provides extra features, like C<PRE_PROCESS>, C<PROCESS> and
|
||||
C<POST_PROCESS>, and also provides the error recovery mechanism via C<ERROR>.
|
||||
You ask it to process a template and it takes care of everything for you. The
|
||||
C<Template::Service::Apache> module goes a little bit further, adding some extra
|
||||
headers to the L<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
|
||||
L<process()|Template::Service#process()> method and schedules the named
|
||||
template specified as an argument, and possibly several other templates
|
||||
(C<PRE_PROCESS>, etc) to be processed in order. It doesn't actually process
|
||||
the templates itself, but instead makes a
|
||||
L<process()|Template::Context#process()> call against a L<Template::Context>
|
||||
object.
|
||||
|
||||
L<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
|
||||
L<Template::Provider> objects (the C<LOAD_TEMPLATES> posse) who themselves
|
||||
might get involved with a L<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
|
||||
L<template()|Template::Context#template()> method. You call it passing a
|
||||
template name as an argument, and it returns a compiled template in the form
|
||||
of a L<Template::Document> object, or otherwise raises an exception.
|
||||
|
||||
A L<Template::Document> is a thin object wrapper around a compiled template
|
||||
subroutine. The object implements a L<process()|Template::Document#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 L<block()|Template::Document#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
|
||||
L<template()|Template::Context#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 L<process()|Template::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 L<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);
|
||||
}
|
||||
|
||||
=head1 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 C<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
|
||||
L<Template::Exception> object. An exception object is really just a
|
||||
convenient wrapper for the 'C<type>' and 'C<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 L<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 L<Template::Service> object calls on
|
||||
L<Template::Context> to handle a L<process()|Template::Context#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 L<Template::Stash> object.
|
||||
This is a blessed hash array in which template variables are defined. The
|
||||
object wrapper provides L<get()|Template::Stash#get()> and
|
||||
L<set()|Template::Stash#set()> method which implement all the
|
||||
I<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 L<stash()|Template::Context#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 L<get()|Template::Stash#get()> method hides the details of the
|
||||
underlying variable types, automatically calling code references, checking
|
||||
return values, and performing other such tricks. If 'C<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 call:
|
||||
|
||||
$stash->get([ 'title', ['The Cat Sat on the Mat'] ]);
|
||||
|
||||
Dotted compound variables can be requested by passing a single
|
||||
list reference to the C<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 L<set()|Template::Stash#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 L<process()|Template::Context#process()> method lies the
|
||||
L<include()|Template::Context#include()> method. Just as with the C<PROCESS> /
|
||||
C<INCLUDE> directives, the key difference is in variable localisation. Before
|
||||
processing a template, the C<process()> method simply updates the stash to set
|
||||
any new variable definitions, overwriting any existing values. In contrast,
|
||||
the C<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 C<include()> method restores the previous variable state by I<decloning> the
|
||||
stash.
|
||||
|
||||
The context also provides an L<insert()|Template::Context#insert()> method to
|
||||
implement the C<INSERT> directive, but no C<wrapper()> method. This functionality
|
||||
can be implemented by rewriting the Perl code and calling C<include()>.
|
||||
|
||||
[% WRAPPER foo -%]
|
||||
blah blah [% x %]
|
||||
[%- END %]
|
||||
|
||||
$context->include('foo', {
|
||||
content => 'blah blah ' . $stash->get('x'),
|
||||
});
|
||||
|
||||
Other than the template processing methods C<process()>, C<include()> and
|
||||
C<insert()>, the context defines methods for fetching plugin objects,
|
||||
L<plugin()|Template::Context#plugin()>, and filters,
|
||||
L<filter()|Template::Context#filter()>.
|
||||
|
||||
# TT USE directive
|
||||
[% USE foo = Bar(10) %]
|
||||
|
||||
# equivalent Perl
|
||||
$stash->set('foo', $context->plugin('Bar', [10]));
|
||||
|
||||
# TT FILTER block
|
||||
[% FILTER bar(20) %]
|
||||
blah blah blah
|
||||
[% END %]
|
||||
|
||||
# equivalent Perl
|
||||
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 C<IF>, C<UNLESS>, C<FOREACH> and so on all have direct
|
||||
counterparts in Perl.
|
||||
|
||||
# TT IF directive
|
||||
[% IF msg %]
|
||||
Message: [% msg %]
|
||||
[% END %];
|
||||
|
||||
# equivalent Perl
|
||||
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 C<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 C<STDOUT> remains as you would expect:
|
||||
|
||||
The dog sat on the log
|
||||
|
||||
The output sent to C<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.
|
||||
|
||||
The source code repository for the Template Toolkit is hosted at Github.
|
||||
|
||||
https://github.com/abw/Template2
|
||||
|
||||
Clone the repository, make your changes, commit them, then send a pull
|
||||
request.
|
||||
|
||||
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 C<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 C<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 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 C<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).
|
||||
|
||||
Then add a line to the Changes file giving a very brief description of what
|
||||
you've done. There's no need to go into detail here (save that for the commit
|
||||
message, comments in code or docuemtation where appropriate).
|
||||
|
||||
Please also make sure you add your name to the lib/Template/Manual/Credits.pod
|
||||
file (if it isn't already there).
|
||||
|
||||
Then commit your changes and send a pull request.
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
242
database/perl/vendor/lib/Template/Manual/Intro.pod
vendored
Normal file
242
database/perl/vendor/lib/Template/Manual/Intro.pod
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Intro
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2020 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 NAME
|
||||
|
||||
Template::Manual::Intro - Introduction to the Template Toolkit
|
||||
|
||||
=head1 Introduction
|
||||
|
||||
The Template Toolkit is a collection of Perl modules which implement a
|
||||
fast, flexible, powerful and extensible template processing system.
|
||||
It is most often used for generating dynamic web content, although it can
|
||||
be used equally well for processing any kind of text documents.
|
||||
|
||||
At the simplest level it provides an easy way to process template
|
||||
files, filling in embedded variable references with their equivalent
|
||||
values. Here's an example of a template.
|
||||
|
||||
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 C<[%> ... C<%]> but you can change these and various other
|
||||
options to configure how the Template Toolkit looks, feels and works.
|
||||
You can set the C<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.
|
||||
|
||||
...etc...
|
||||
|
||||
=head1 The Template Perl Module
|
||||
|
||||
The L<Template> Perl module is the front end to the Template Toolkit for Perl
|
||||
programmers, 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 L<Template>
|
||||
constructor method, L<new()|Template#new()>, which are then used to
|
||||
configure the generate object.
|
||||
|
||||
use Template;
|
||||
|
||||
my $tt = Template->new({
|
||||
INCLUDE_PATH => '/usr/local/templates',
|
||||
INTERPOLATE => 1,
|
||||
}) || die "$Template::ERROR\n";
|
||||
|
||||
The L<Template> object implements a L<process()|Template#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 L<process()|Template#process()> method returns a true value (C<1>) on success
|
||||
and prints the template output to C<STDOUT>, by default. On error, the
|
||||
L<process()|Template#process()> method returns a false value (C<undef>).
|
||||
The L<error()|Template#error()> method can then be called to retrieve
|
||||
details of the error.
|
||||
|
||||
=head1 Component Based Content Construction
|
||||
|
||||
A number of special directives are provided, such as C<INSERT>, C<INCLUDE> and
|
||||
C<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>
|
||||
|
||||
=head1 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 'C<.>' is used to access into lists and hashes or to call object
|
||||
methods. The C<FOREACH> directive is provided for iterating through lists, and
|
||||
various logical tests are available using directives such as C<IF>, C<UNLESS>,
|
||||
C<ELSIF>, C<ELSE>, C<SWITCH>, C<CASE>, etc.
|
||||
|
||||
[% FOREACH section = menu %]
|
||||
<a href="[% root %]/[% section %]/index.html">[% section %]</a>
|
||||
[% END %]
|
||||
|
||||
<b>Client</b>: [% 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 %]
|
||||
|
||||
=head1 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.
|
||||
|
||||
=head1 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.
|
||||
|
||||
=head1 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.
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
313
database/perl/vendor/lib/Template/Manual/Plugins.pod
vendored
Normal file
313
database/perl/vendor/lib/Template/Manual/Plugins.pod
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Plugins
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 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 NAME
|
||||
|
||||
Template::Manual::Plugins - Standard plugins
|
||||
|
||||
=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 Assert
|
||||
|
||||
New in 2.20! The L<Assert|Template::Plugin::Assert> plugin adds an
|
||||
C<assert> virtual method that you can use to catch undefined values.
|
||||
|
||||
For example, consider this dotop:
|
||||
|
||||
[% user.name %]
|
||||
|
||||
If C<user.name> is an undefined value then TT will silently ignore the
|
||||
fact and print nothing. If you C<USE> the C<assert> plugin then you
|
||||
can add the C<assert> vmethod between the C<user> and C<name> elements,
|
||||
like so:
|
||||
|
||||
[% user.assert.name %]
|
||||
|
||||
Now, if C<user.name> is an undefined value, an exception will be thrown:
|
||||
|
||||
assert error - undefined value for name
|
||||
|
||||
=head2 CGI
|
||||
|
||||
The L<CGI|Template::Plugin::CGI> plugin is a wrapper around Lincoln Stein's
|
||||
CGI.pm module. The plugin is distributed with the Template Toolkit (see
|
||||
L<Template::Plugin::CGI>) and the L<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 in the 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 L<Date|Template::Plugin::Date> plugin provides an easy way to generate
|
||||
formatted time and date strings by delegating to the L<POSIX> C<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 L<Directory|Template::Plugin::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 C<DBI> plugin is no longer distributed as part of the Template Toolkit
|
||||
(as of version 2.15). It is now available as a separate L<Template::DBI>
|
||||
distribution from CPAN.
|
||||
|
||||
=head2 Dumper
|
||||
|
||||
The L<Dumper|Template::Plugin::Dumper> plugin provides an interface to the
|
||||
Data::Dumper module. See L<Template::Plugin::Dumper> and L<Data::Dumper> for
|
||||
further details.
|
||||
|
||||
[% USE dumper(indent=0, pad="<br>") %]
|
||||
[% dumper.dump(myvar, yourvar) %]
|
||||
|
||||
=head2 File
|
||||
|
||||
The L<File|Template::Plugin::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;
|
||||
}
|
||||
|
||||
Example of use:
|
||||
|
||||
# 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 L<Format|Template::Plugin::Format> plugin provides a simple way to format
|
||||
text according to a C<printf()>-like format. See L<Template::Plugin::Format> for
|
||||
further details.
|
||||
|
||||
[% USE bold = format('<b>%s</b>') %]
|
||||
[% bold('Hello') %]
|
||||
|
||||
=head2 GD
|
||||
|
||||
The C<GD> plugins are no longer part of the core Template Toolkit distribution.
|
||||
They are now available from CPAN in a separate L<Template::GD> distribution.
|
||||
|
||||
=head2 HTML
|
||||
|
||||
The L<HTML|Template::Plugin::HTML> plugin is 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.
|
||||
|
||||
[% 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 L<Iterator|Template::Plugin::Iterator> plugin provides a way to create a
|
||||
L<Template::Iterator> object to iterate over a data set. An iterator is
|
||||
created automatically by the C<FOREACH> directive and is aliased to the C<loop>
|
||||
variable. This plugin allows an iterator to be explicitly created with a given
|
||||
name, or the default plugin name, C<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 Scalar
|
||||
|
||||
The Template Toolkit calls user-defined subroutines and object methods
|
||||
using Perl's array context by default.
|
||||
|
||||
# TT2 calls object methods in array context by default
|
||||
[% object.method %]
|
||||
|
||||
This plugin module provides a way for you to call subroutines and methods
|
||||
in scalar context.
|
||||
|
||||
[% USE scalar %]
|
||||
|
||||
# force it to use scalar context
|
||||
[% object.scalar.method %]
|
||||
|
||||
# also works with subroutine references
|
||||
[% scalar.my_sub_ref %]
|
||||
|
||||
=head2 String
|
||||
|
||||
The L<String|Template::Plugin::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 L<Table|Template::Plugin::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 L<URL|Template::Plugin::URL> plugin provides a simple way of constructing
|
||||
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 L<Wrap|Template::Plugin::Wrap> plugin uses the L<Text::Wrap> module 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 C<Text::Wrap> module is available from CPAN:
|
||||
|
||||
http://www.cpan.org/modules/by-module/Text/
|
||||
|
||||
=head2 XML
|
||||
|
||||
The C<XML::DOM>, C<XML::RSS>, C<XML::Simple> and C<XML::XPath> plugins are no
|
||||
longer distributed with the Template Toolkit as of version 2.15
|
||||
|
||||
They are now available in a separate L<Template::XML> distribution.
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
327
database/perl/vendor/lib/Template/Manual/Syntax.pod
vendored
Normal file
327
database/perl/vendor/lib/Template/Manual/Syntax.pod
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Syntax
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 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 NAME
|
||||
|
||||
Template::Manual::Syntax - Directive syntax, structure and semantics
|
||||
|
||||
=head1 Tag Styles
|
||||
|
||||
Template directives are embedded between start and end markers tags.
|
||||
By default these tag markers are C<[%> and C<%]>.
|
||||
|
||||
[% 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 C<START_TAG>, C<END_TAG> and
|
||||
C<TAG_STYLE> configuration options. You can also use the C<TAGS> directive to
|
||||
define a new tag style for the current template file.
|
||||
|
||||
You can also set the C<INTERPOLATE> option to allow simple variable references
|
||||
to be embedded directly in templates, prefixed by a C<$>.
|
||||
|
||||
# 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%])
|
||||
|
||||
=head1 Outline Tags
|
||||
|
||||
As of version 2.26, the Template Toolkit supports "outline" tags. These have
|
||||
a designated marker at the start of a line (C<%%> by default) and continue to
|
||||
the end of a line. The newline character at the end of the line is discarded
|
||||
(aka "chomped").
|
||||
|
||||
So rather than writing something like this:
|
||||
|
||||
[% IF some.list.size -%]
|
||||
<ul>
|
||||
[% FOREACH item IN some.list -%]
|
||||
<li>[% item.html %]</li>
|
||||
[% END -%]
|
||||
</ul>
|
||||
[% END -%]
|
||||
|
||||
You can write it like this instead:
|
||||
|
||||
%% IF some.list.size
|
||||
<ul>
|
||||
%% FOREACH item IN some.list
|
||||
<li>[% item.html %]</li>
|
||||
%% END
|
||||
</ul>
|
||||
%% END
|
||||
|
||||
Outline tags aren't enabled by default. There are a numbers of ways you can
|
||||
enable them. The first is to use the C<TAGS> directive to set the tag style
|
||||
to C<outline> in any templates where you want to use them. This will enable
|
||||
outline tags from that point on.
|
||||
|
||||
[% TAGS outline -%]
|
||||
%% INCLUDE header
|
||||
|
||||
You can set the C<TAGS> back to the C<default> value at some point later in the
|
||||
template if you want to disable them:
|
||||
|
||||
[% TAGS default -%]
|
||||
|
||||
You can set the C<TAG_STYLE> configuration option if you want then enabled in
|
||||
all templates by default. You can always use the C<[% TAGS default %]>
|
||||
directive to disable them in any templates or parts of templates if necessary.
|
||||
|
||||
my $tt = Template->new({
|
||||
TAG_STYLE => 'outline',
|
||||
});
|
||||
|
||||
The C<OUTLINE_TAG> option allows you to set the outline tag marker to something
|
||||
else if you're not a fan of percent signs. Setting this option will
|
||||
automatically enable outline tags.
|
||||
|
||||
my $tt = Template->new({
|
||||
OUTLINE_TAG => '>>',
|
||||
});
|
||||
|
||||
You can also use the C<TAGS> directive to define your own custom tags (start,
|
||||
end and now optionally, outline) for a template or part of a template.
|
||||
|
||||
[% TAGS <* *> >> %]
|
||||
>> INCLUDE header # outline tag
|
||||
Hello <* name *> # inline tag
|
||||
|
||||
If you only specify a start and end tag then outline tags will be disabled.
|
||||
|
||||
[% TAGS <* *> %] # no outline tags
|
||||
|
||||
=head1 Comments
|
||||
|
||||
The C<#> 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>
|
||||
%]
|
||||
|
||||
=head1 Chomping Whitespace
|
||||
|
||||
You can add C<-> or C<+> to the immediate start or end of a directive
|
||||
tag to control the whitespace chomping options. See the C<PRE_CHOMP> and
|
||||
C<POST_CHOMP> options for further details.
|
||||
|
||||
[% BLOCK foo -%] # remove trailing newline
|
||||
This is block foo
|
||||
[%- END %] # remove leading newline
|
||||
|
||||
=head1 Implicit Directives: GET and SET
|
||||
|
||||
The simplest directives are C<GET> and C<SET> which retrieve and update
|
||||
variable values respectively. The C<GET> and C<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 C<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 C<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 C<stop> which is
|
||||
entirely separate from the C<STOP> directive.
|
||||
|
||||
[% stop = 'Clackett Lane Bus Depot' %]
|
||||
|
||||
The bus will next stop at [% stop %] # variable
|
||||
|
||||
[% STOP %] # directive
|
||||
|
||||
=head1 Block Directives
|
||||
|
||||
Directives such as C<FOREACH>, C<WHILE>, C<BLOCK>, C<FILTER>, etc., mark the
|
||||
start of a block which may contain text or other directives up to the matching
|
||||
C<END> directive. Blocks may be nested indefinitely. The C<IF>, C<UNLESS>,
|
||||
C<ELSIF> and C<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 %]
|
||||
|
||||
=head1 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 C<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 %] # does not work
|
||||
|
||||
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 C<IF> block which returns
|
||||
C<'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 %]
|
||||
|
||||
=head1 Chaining Filters
|
||||
|
||||
Multiple C<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, C<|>, can also be used as an alias for C<FILTER>.
|
||||
|
||||
[% PROCESS somefile | truncate(100) | html %]
|
||||
|
||||
=head1 Multiple Directive Blocks
|
||||
|
||||
Multiple directives can be included within a single tag when delimited
|
||||
by semi-colons. Note however that the C<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 %]
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
736
database/perl/vendor/lib/Template/Manual/VMethods.pod
vendored
Normal file
736
database/perl/vendor/lib/Template/Manual/VMethods.pod
vendored
Normal file
@@ -0,0 +1,736 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::VMethods
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2015 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 NAME
|
||||
|
||||
Template::Manual::VMethods - Virtual Methods
|
||||
|
||||
=head1 Scalar Virtual Methods
|
||||
|
||||
=head2 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
|
||||
|
||||
=head2 collapse
|
||||
|
||||
Returns the text with any leading and trailing whitespace removed and any
|
||||
internal sequences of whitespace converted to a single space
|
||||
|
||||
[% text = " The bird\n is the word" %]
|
||||
[% text.collapse %] # The bird is the word
|
||||
|
||||
=head2 defined
|
||||
|
||||
Returns true if the value is defined.
|
||||
|
||||
[% user = get_user(uid) IF uid.defined %]
|
||||
|
||||
=head2 dquote
|
||||
|
||||
Returns the text with any double quote characters escaped with a backslash
|
||||
prefix. Any newline characters in the text will be replaced with "\n".
|
||||
|
||||
[% quote = 'He said "Oh really?"' %]
|
||||
[% quote.dquote %] # He said \"Oh really?\"
|
||||
|
||||
=head2 hash
|
||||
|
||||
Return the value as a hash reference containing a single entry with
|
||||
the key C<value> indicating the original scalar value. As with the
|
||||
C<list> virtual method, this is generally used to help massage data
|
||||
into different formats.
|
||||
|
||||
=head2 lcfirst
|
||||
|
||||
Returns the text with the first letter converted to lower case.
|
||||
|
||||
[% word = 'BIRD' %]
|
||||
[% word.lcfirst %] # bIRD
|
||||
|
||||
=head2 length
|
||||
|
||||
Returns the length of the string representation of the item:
|
||||
|
||||
[% IF password.length < 8 %]
|
||||
Password too short, dumbass!
|
||||
[% END %]
|
||||
|
||||
=head2 empty
|
||||
|
||||
Returns true if the string is empty:
|
||||
|
||||
[% IF details.empty %]
|
||||
No details specified
|
||||
[% END %]
|
||||
|
||||
=head2 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 C<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
|
||||
|
||||
=head2 lower
|
||||
|
||||
Returns the text in lower case.
|
||||
|
||||
[% word = 'BIRD' %]
|
||||
[% word.lower %] # bird
|
||||
|
||||
=head2 match(pattern, global)
|
||||
|
||||
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);
|
||||
%]
|
||||
|
||||
To perform a global search to match the pattern as many times as it
|
||||
appears in the source string, provide a true value for the C<global>
|
||||
argument following the pattern.
|
||||
|
||||
[% text = 'bandanna';
|
||||
text.match('an+', 1).join(', ') # an, ann
|
||||
%]
|
||||
|
||||
=head2 repeat(n)
|
||||
|
||||
Repeat the string a specified number of times.
|
||||
|
||||
[% name = 'foo' %]
|
||||
[% name.repeat(3) %] # foofoofoo
|
||||
|
||||
=head2 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
|
||||
|
||||
You can use C<$1>, C<$2>, etc., to reference captured parts (in parentheses)
|
||||
in the regular expression. Just be careful to I<single> quote the replacement
|
||||
string. If you use I<double> quotes then TT will try and interpolate the
|
||||
variables before passing the string to the C<replace> vmethod.
|
||||
|
||||
[% name = 'FooBarBaz' %]
|
||||
[% name.replace('([A-Z])', ' $1') %] # Foo Bar Baz
|
||||
|
||||
=head2 remove(pattern)
|
||||
|
||||
Outputs the string with all instances of the pattern (specified
|
||||
as a Perl regular expression) removed.
|
||||
|
||||
[% name = 'foo, bar & baz' %]
|
||||
[% name.remove('\W+') %] # foobarbaz
|
||||
|
||||
=head2 search(pattern)
|
||||
|
||||
Performs a similar function to L<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 L<match>. Move along
|
||||
now, there's nothing more to see here.
|
||||
|
||||
=head2 size
|
||||
|
||||
Always returns 1 for scalar values. This method is provided for
|
||||
consistency with the hash and list size methods.
|
||||
|
||||
=head2 split(pattern)
|
||||
|
||||
Calls Perl's C<split()> function to split a string into a list of
|
||||
strings.
|
||||
|
||||
[% FOREACH dir IN mypath.split(':') %]
|
||||
[% dir %]
|
||||
[% END %]
|
||||
|
||||
=head2 substr(offset, length, replacement)
|
||||
|
||||
Returns a substring starting at C<offset>, for C<length> characters.
|
||||
|
||||
[% str 'foo bar baz wiz waz woz') %]
|
||||
[% str.substr(4, 3) %] # bar
|
||||
|
||||
If C<length> is not specified then it returns everything from the
|
||||
C<offset> to the end of the string.
|
||||
|
||||
[% str.substr(12) %] # wiz waz woz
|
||||
|
||||
If both C<length> and C<replacement> are specified, then the method
|
||||
replaces everything from C<offset> for C<length> characters with
|
||||
C<$replacement>. The substring removed from the string is then returned.
|
||||
|
||||
[% str.substr(0, 11, 'FOO') %] # foo bar baz
|
||||
[% str %] # FOO wiz waz woz
|
||||
|
||||
=head2 squote
|
||||
|
||||
Returns the text with any single quote characters escaped with a backslash
|
||||
prefix.
|
||||
|
||||
[% tim = "Tim O'Reilly" %]
|
||||
[% tim.squote %] # Tim O\'Reilly
|
||||
|
||||
=head2 trim
|
||||
|
||||
Returns the text with any leading and trailing whitespace removed.
|
||||
|
||||
[% text = ' hello world ' %]
|
||||
[% text.trim %] # hello world
|
||||
|
||||
=head2 ucfirst
|
||||
|
||||
Returns the text with the first letter converted to upper case.
|
||||
|
||||
[% word = 'bird' %]
|
||||
[% word.ucfirst %] # Bird
|
||||
|
||||
=head2 upper
|
||||
|
||||
Returns the text in upper case.
|
||||
|
||||
[% word = 'bird' %]
|
||||
[% word.upper %] # BIRD
|
||||
|
||||
=head1 Hash Virtual Methods
|
||||
|
||||
=head2 keys
|
||||
|
||||
Returns a list of keys in the hash. They are not returned in any
|
||||
particular order, but the order is the same as for the corresponding
|
||||
values method.
|
||||
|
||||
[% FOREACH key IN hash.keys %]
|
||||
* [% key %]
|
||||
[% END %]
|
||||
|
||||
If you want the keys in sorted order, use the list C<sort> method.
|
||||
|
||||
[% FOREACH key IN hash.keys.sort %]
|
||||
* [% key %]
|
||||
[% END %]
|
||||
|
||||
Having got the keys in sorted order, you can then use variable
|
||||
interpolation to fetch the value. This is shown in the following
|
||||
example by the use of C<$key> to fetch the item from C<hash> whose
|
||||
key is stored in the C<key> variable.
|
||||
|
||||
[% FOREACH key IN hash.keys.sort %]
|
||||
* [% key %] = [% hash.$key %]
|
||||
[% END %]
|
||||
|
||||
Alternately, you can use the C<pairs> method to get a list of
|
||||
key/value pairs in sorted order.
|
||||
|
||||
=head2 values
|
||||
|
||||
Returns a list of the values in the hash. As with the C<keys> method,
|
||||
they are not returned in any particular order, although it is the same
|
||||
order that the keys are returned in.
|
||||
|
||||
[% hash.values.join(', ') %]
|
||||
|
||||
=head2 items
|
||||
|
||||
Returns a list of both the keys and the values expanded into a single list.
|
||||
|
||||
[% hash = {
|
||||
a = 10
|
||||
b = 20
|
||||
};
|
||||
|
||||
hash.items.join(', ') # a, 10, b, 20
|
||||
%]
|
||||
|
||||
=head2 each
|
||||
|
||||
This method currently returns the same thing as the C<items> method.
|
||||
|
||||
However, please note that this method will change in the next major
|
||||
version of the Template Toolkit (v3) to return the same thing as the
|
||||
C<pairs> method. This will be done in an effort to make these virtual
|
||||
method more consistent with each other and how Perl works.
|
||||
|
||||
In anticipation of this, we recommend that you stop using C<hash.each>
|
||||
and instead use C<hash.items>.
|
||||
|
||||
=head2 pairs
|
||||
|
||||
This method returns a list of key/value pairs. They are returned in
|
||||
sorted order according to the keys.
|
||||
|
||||
[% FOREACH pair IN product.pairs %]
|
||||
* [% pair.key %] is [% pair.value %]
|
||||
[% END %]
|
||||
|
||||
=head2 list
|
||||
|
||||
Returns the contents of the hash in list form. An argument can be
|
||||
passed to indicate the desired items required in the list: C<keys> to
|
||||
return a list of the keys (same as C<hash.keys>), C<values> to return a
|
||||
list of the values (same as C<hash.values>), C<each> to return as list
|
||||
of key and values (same as C<hash.each>), or C<pairs> to return a list
|
||||
of key/value pairs (same as C<hash.pairs>).
|
||||
|
||||
[% keys = hash.list('keys') %]
|
||||
[% values = hash.list('values') %]
|
||||
[% items = hash.list('each') %]
|
||||
[% pairs = hash.list('pairs') %]
|
||||
|
||||
When called without an argument it currently returns the same thing as
|
||||
the C<pairs> method. However, please note that this method will change
|
||||
in the next major version of the Template Toolkit (v3) to return a
|
||||
reference to a list containing the single hash reference (as per the
|
||||
scalar list method).
|
||||
|
||||
In anticipation of this, we recommend that you stop using C<hash.list>
|
||||
and instead use C<hash.pairs>.
|
||||
|
||||
=head2 sort, nsort
|
||||
|
||||
Return a list of the keys, sorted alphabetically (C<sort>) or numerically
|
||||
(C<nsort>) according to the corresponding values in the hash.
|
||||
|
||||
[% FOREACH n IN phones.sort %]
|
||||
[% phones.$n %] is [% n %],
|
||||
[% END %]
|
||||
|
||||
=head2 import
|
||||
|
||||
The C<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 C<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
|
||||
|
||||
=head2 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' %]
|
||||
|
||||
When called without any argument, C<hash.defined> returns true if the hash
|
||||
itself is defined (e.g. the same effect as C<scalar.defined>).
|
||||
|
||||
=head2 delete
|
||||
|
||||
Delete one or more items from the hash.
|
||||
|
||||
[% hash.delete('foo', 'bar') %]
|
||||
|
||||
=head2 size
|
||||
|
||||
Returns the number of key/value pairs in the hash.
|
||||
|
||||
=head2 empty
|
||||
|
||||
Returns true if the hash is empty:
|
||||
|
||||
[% IF config.empty %]
|
||||
No configuration available
|
||||
[% END %]
|
||||
|
||||
=head2 item
|
||||
|
||||
Returns an item from the hash using a key passed as an argument.
|
||||
|
||||
[% hash.item('foo') %] # same as hash.foo
|
||||
|
||||
=head1 List Virtual Methods
|
||||
|
||||
=head2 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(", ") %].
|
||||
|
||||
=head2 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
|
||||
|
||||
=head2 empty
|
||||
|
||||
Returns true if the list is empty:
|
||||
|
||||
[% IF results.empty %]
|
||||
No results found
|
||||
[% END %]
|
||||
|
||||
=head2 defined
|
||||
|
||||
Returns a true or false value if the item in the list denoted by the
|
||||
argument is defined.
|
||||
|
||||
[% list.defined(3) ? 'yes' : 'no' %]
|
||||
|
||||
When called without any argument, C<list.defined> returns true if the list
|
||||
itself is defined (e.g. the same effect as C<scalar.defined>).
|
||||
|
||||
=head2 reverse
|
||||
|
||||
Returns the items of the list in reverse order.
|
||||
|
||||
[% FOREACH s IN scores.reverse %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
=head2 join
|
||||
|
||||
Joins the items in the list into a single string, using Perl's C<join()>
|
||||
function.
|
||||
|
||||
[% items.join(', ') %]
|
||||
|
||||
=head2 grep
|
||||
|
||||
Returns a list of the items in the list that match a regular expression
|
||||
pattern.
|
||||
|
||||
[% FOREACH directory.files.grep('\.txt$') %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
=head2 sort, nsort
|
||||
|
||||
Returns the items in alpha (C<sort>) or numerical (C<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 C<books> list can contains hash references with
|
||||
an C<author> key or objects with an C<author> method.
|
||||
|
||||
You can also specify multiple sort keys.
|
||||
|
||||
[% library = books.sort('author', 'title') %]
|
||||
|
||||
In this case the books will be sorted primarily by author. If two or more
|
||||
books have authors with the same name then they will be sorted by title.
|
||||
|
||||
=head2 unshift(item), push(item)
|
||||
|
||||
The C<push()> method adds an item or items to the end of list.
|
||||
|
||||
[% mylist.push(foo) %]
|
||||
[% mylist.push(foo, bar) %]
|
||||
|
||||
The C<unshift()> method adds an item or items to the start of a list.
|
||||
|
||||
[% mylist.unshift(foo) %]
|
||||
[% mylist.push(foo, bar) %]
|
||||
|
||||
=head2 shift, pop
|
||||
|
||||
Removes the first/last item from the list and returns it.
|
||||
|
||||
[% first = mylist.shift %]
|
||||
[% last = mylist.pop %]
|
||||
|
||||
=head2 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 %]
|
||||
|
||||
=head2 import
|
||||
|
||||
Appends the contents of one or more other lists to the end of the
|
||||
current list.
|
||||
|
||||
[% one = [ 1 2 3 ];
|
||||
two = [ 4 5 6 ];
|
||||
three = [ 7 8 9 ];
|
||||
one.import(two, three);
|
||||
one.join(', '); # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
%]
|
||||
|
||||
Import also allows chaining. The below syntax is equivalent.
|
||||
|
||||
[% one = [ 1 2 3 ];
|
||||
two = [ 4 5 6 ];
|
||||
three = [ 7 8 9 ];
|
||||
one.import(two, three).join(', '); # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
# or: one.import(two).import(three).join(', '); # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
%]
|
||||
|
||||
=head2 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.
|
||||
|
||||
=head2 slice(from, to)
|
||||
|
||||
Returns a slice of items in the list between the bounds passed as
|
||||
arguments. If the second argument, C<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) %]
|
||||
|
||||
=head2 splice(offset, length, list)
|
||||
|
||||
Behaves just like Perl's C<splice()> function allowing you to selectively
|
||||
remove and/or replace elements in a list. It removes C<length> items
|
||||
from the list, starting at C<offset> and replaces them with the items
|
||||
in C<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 C<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 ]);
|
||||
%]
|
||||
|
||||
=head2 hash
|
||||
|
||||
Returns a reference to a hash array comprised of the elements in the
|
||||
list. The even-numbered elements (0, 2, 4, etc) become the keys and
|
||||
the odd-numbered elements (1, 3, 5, etc) the values.
|
||||
|
||||
[% list = ['pi', 3.14, 'e', 2.718] %]
|
||||
[% hash = list.hash %]
|
||||
[% hash.pi %] # 3.14
|
||||
[% hash.e %] # 2.718
|
||||
|
||||
If a numerical argument is provided then the hash returned will have
|
||||
keys generated for each item starting at the number specified.
|
||||
|
||||
[% list = ['beer', 'peanuts'] %]
|
||||
[% hash = list.hash(1) %]
|
||||
[% hash.1 %] # beer
|
||||
[% hash.2 %] # peanuts
|
||||
|
||||
=head2 item
|
||||
|
||||
Returns an item from the list using an index passed as an argument.
|
||||
|
||||
[% list.item(0) %] # same as list.0
|
||||
|
||||
=head1 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). C<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 C<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 the C<something> variable is bound to a subroutine which
|
||||
may return one or more items:
|
||||
|
||||
[% FOREACH item IN 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 C<first> method, for example, then that
|
||||
will be called, as expected, in preference to the list virtual method.
|
||||
|
||||
=head1 Defining Custom Virtual Methods
|
||||
|
||||
You can define your own virtual methods for scalars, lists and hash arrays.
|
||||
The L<Template::Stash> package variables C<$SCALAR_OPS>, C<$LIST_OPS> and
|
||||
C<$HASH_OPS> are references to hash arrays that define these virtual methods.
|
||||
C<HASH_OPS> and C<LIST_OPS> methods are subroutines that accept a hash/list
|
||||
reference as the first item. C<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 ];
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% primes = [ 2, 3, 5, 7, 9 ] %]
|
||||
[% primes.odd.join(', ') %] # 3, 5, 7, 9
|
||||
|
||||
TODO: document the define_vmethod() method which makes this even easier
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
838
database/perl/vendor/lib/Template/Manual/Variables.pod
vendored
Normal file
838
database/perl/vendor/lib/Template/Manual/Variables.pod
vendored
Normal file
@@ -0,0 +1,838 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Variables
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 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 NAME
|
||||
|
||||
Template::Manual::Variables - Template variables and code bindings
|
||||
|
||||
=head1 Template Variables
|
||||
|
||||
A reference to a hash array may be passed as the second argument to the
|
||||
L<process()|Template#process()> method, containing definitions of template
|
||||
variables. The C<VARIABLES> (a.k.a. C<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);
|
||||
|
||||
F<myfile> template:
|
||||
|
||||
This is version [% version %] ([% release %]).
|
||||
Serial number: [% serial_no %]
|
||||
|
||||
Generated 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 'C<foo>', 'C<Foo>' and
|
||||
'C<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 data:
|
||||
|
||||
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'),
|
||||
};
|
||||
|
||||
Example 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') %]
|
||||
|
||||
Generated 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 'C<.>' operator.
|
||||
|
||||
Example data:
|
||||
|
||||
my $vars = {
|
||||
'home' => 'http://www.myserver.com/homepage.html',
|
||||
'page' => {
|
||||
'this' => 'mypage.html',
|
||||
'next' => 'nextpage.html',
|
||||
'prev' => 'prevpage.html',
|
||||
},
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
<a href="[% home %]">Home</a>
|
||||
<a href="[% page.prev %]">Previous Page</a>
|
||||
<a href="[% page.next %]">Next Page</a>
|
||||
|
||||
Generated 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 'C<_>' or 'C<.>' 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
|
||||
C<DEBUG> option is enabled).
|
||||
|
||||
Example data:
|
||||
|
||||
my $vars = {
|
||||
message => 'Hello World!',
|
||||
_secret => "On the Internet, no-one knows you're a dog",
|
||||
thing => {
|
||||
public => 123,
|
||||
_private => 456,
|
||||
'.hidden' => 789,
|
||||
},
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% message %] # outputs "Hello World!"
|
||||
[% _secret %] # no output
|
||||
[% thing.public %] # outputs "123"
|
||||
[% thing._private %] # no output
|
||||
[% thing..hidden %] # ERROR: unexpected token (..)
|
||||
|
||||
You can disable this feature by setting the C<$Template::Stash::PRIVATE>
|
||||
package variable to a false value.
|
||||
|
||||
$Template::Stash::PRIVATE = undef; # now you can thing._private
|
||||
|
||||
To access a hash entry using a key stored in another variable, prefix
|
||||
the key variable with 'C<$>' 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 'C<.>' characters in the name),
|
||||
any hashes required to represent intermediate namespaces will be
|
||||
created automatically. In this following example, the C<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
|
||||
|
||||
Generated output:
|
||||
|
||||
The XYZ-2000 Bogon Generator
|
||||
costs $666.00
|
||||
|
||||
You can use Perl's familiar C<{> ... C<}> construct to explicitly create
|
||||
a hash and assign it to a variable. Note that commas are optional
|
||||
between key/value pairs and C<=> can be used in place of C<=E<gt>>.
|
||||
|
||||
# minimal TT style
|
||||
[% product = {
|
||||
id = 'XYZ-2000'
|
||||
desc = 'Bogon Generator'
|
||||
price = 666
|
||||
}
|
||||
%]
|
||||
|
||||
# perl style
|
||||
[% product = {
|
||||
id => 'XYZ-2000',
|
||||
desc => 'Bogon Generator',
|
||||
price => 666,
|
||||
}
|
||||
%]
|
||||
|
||||
=head2 List References
|
||||
|
||||
Items in lists are also accessed by use of the dot operator.
|
||||
|
||||
Example data:
|
||||
|
||||
my $vars = {
|
||||
people => [ 'Tom', 'Dick', 'Larry' ],
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% people.0 %] # Tom
|
||||
[% people.1 %] # Dick
|
||||
[% people.2 %] # Larry
|
||||
|
||||
The C<FOREACH> directive can be used to iterate through items in a list.
|
||||
|
||||
[% FOREACH person IN people %]
|
||||
Hello [% person %]
|
||||
[% END %]
|
||||
|
||||
Generated output:
|
||||
|
||||
Hello Tom
|
||||
Hello Dick
|
||||
Hello Larry
|
||||
|
||||
Lists can be constructed in-situ using the regular anonymous list
|
||||
C<[> ... C<]> construct. Commas between items are optional.
|
||||
|
||||
[% cols = [ 'red', 'green', 'blue' ] %]
|
||||
|
||||
[% FOREACH c IN cols %]
|
||||
[% c %]
|
||||
[% END %]
|
||||
|
||||
or:
|
||||
|
||||
[% FOREACH c IN [ 'red', 'green', 'blue' ] %]
|
||||
[% c %]
|
||||
[% END %]
|
||||
|
||||
You can also create simple numerical sequences using the C<..> range
|
||||
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!', @_) },
|
||||
};
|
||||
|
||||
Example 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'),
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% FOREACH p IN cgi.param %] # returns list of param keys
|
||||
[% p %] => [% cgi.param(p) %] # fetch each param value
|
||||
[% END %]
|
||||
|
||||
Generated 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 Passing Parameters and Returning 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 C<=E<gt>> or C<=> 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 } || ' + ', @_);
|
||||
}
|
||||
|
||||
Example template:
|
||||
|
||||
[% myjoin(10, 20, 30) %]
|
||||
[% myjoin(10, 20, 30, joint = ' - ' %]
|
||||
[% myjoin(joint => ' * ', 10, 20, 30 %]
|
||||
|
||||
Generated 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' ) },
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% FOREACH i IN items1 %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
[% FOREACH i IN items2 %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
=head2 Error Handling
|
||||
|
||||
Errors can be reported from user code by calling C<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 C<error>
|
||||
variable.
|
||||
|
||||
my $vars = {
|
||||
barf => sub {
|
||||
die "a sick error has occurred\n";
|
||||
},
|
||||
};
|
||||
|
||||
Example 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 C<die()> are converted to exceptions of type
|
||||
C<undef> (the literal string "undef" rather than the undefined value).
|
||||
Exceptions of user-defined types can be thrown by calling C<die()> with
|
||||
a reference to a L<Template::Exception> object.
|
||||
|
||||
use Template::Exception;
|
||||
|
||||
my $vars = {
|
||||
login => sub {
|
||||
...do something...
|
||||
die Template::Exception->new( badpwd => 'password too silly' );
|
||||
},
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% TRY %]
|
||||
[% login %]
|
||||
[% CATCH badpwd %]
|
||||
Bad password: [% error.info %]
|
||||
[% CATCH %]
|
||||
Some other '[% error.type %]' error: [% error.info %]
|
||||
[% END %]
|
||||
|
||||
The exception types C<stop> and C<return> are used to implement the
|
||||
C<STOP> and C<RETURN> directives. Throwing an exception as:
|
||||
|
||||
die (Template::Exception->new('stop'));
|
||||
|
||||
has the same effect as the directive:
|
||||
|
||||
[% STOP %]
|
||||
|
||||
=head1 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 C<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 C<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.
|
||||
|
||||
=head1 Variable Interpolation
|
||||
|
||||
The Template Toolkit uses C<$> 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 C<INTERPOLATE> option is set:
|
||||
|
||||
Dear $honorific $firstname $surname,
|
||||
|
||||
The same rules apply within directives. If a variable is prefixed
|
||||
with a C<$> 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' %]
|
||||
[% users.$uid %] # same as 'users.abw'
|
||||
|
||||
Curly braces can be used to delimit interpolated variable names where
|
||||
necessary.
|
||||
|
||||
[% users.${me.id}.name %]
|
||||
|
||||
Directives such as C<INCLUDE>, C<PROCESS>, etc., that accept a template name
|
||||
as the first argument, will automatically quote it for convenience.
|
||||
|
||||
[% INCLUDE foo/bar.txt %]
|
||||
|
||||
The above example is equivalent to:
|
||||
|
||||
[% INCLUDE "foo/bar.txt" %]
|
||||
|
||||
To C<INCLUDE> a template whose name is stored in a variable, simply
|
||||
prefix the variable name with C<$> to have it interpolated.
|
||||
|
||||
[% myfile = 'header' %]
|
||||
[% INCLUDE $myfile %]
|
||||
|
||||
This is equivalent to:
|
||||
|
||||
[% INCLUDE header %]
|
||||
|
||||
Note also that a variable containing a reference to a L<Template::Document>
|
||||
object can also be processed in this way.
|
||||
|
||||
my $vars = {
|
||||
header => Template::Document->new({ ... }),
|
||||
};
|
||||
|
||||
Example template:
|
||||
|
||||
[% INCLUDE $header %]
|
||||
|
||||
=head1 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 C<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 C<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 %]
|
||||
|
||||
=head1 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 C<CONSTANTS> hash as a
|
||||
constructor item as per C<VARIABLES>. The C<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 C<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
|
||||
C<joint> is a runtime variable and cannot be determined at compile
|
||||
time.
|
||||
|
||||
# ERROR: runtime variable argument!
|
||||
[% constants.col.keys.sort.join(joint) %]
|
||||
|
||||
The C<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 %]
|
||||
|
||||
=head1 Special Variables
|
||||
|
||||
A number of special variables are automatically defined by the Template
|
||||
Toolkit.
|
||||
|
||||
=head2 template
|
||||
|
||||
The C<template> variable contains a reference to the main template being
|
||||
processed, in the form of a L<Template::Document> object. This variable is
|
||||
correctly defined within C<PRE_PROCESS>, C<PROCESS> and C<POST_PROCESS>
|
||||
templates, allowing standard headers, footers, etc., to access metadata items
|
||||
from the main template. The C<name> and C<modtime> metadata items are
|
||||
automatically provided, giving the template name and modification time in
|
||||
seconds since the epoch.
|
||||
|
||||
Note that the C<template> variable always references the top-level
|
||||
template, even when processing other template components via C<INCLUDE>,
|
||||
C<PROCESS>, etc.
|
||||
|
||||
=head2 component
|
||||
|
||||
The C<component> variable is like C<template> but always contains a
|
||||
reference to the current, innermost template component being processed.
|
||||
In the main template, the C<template> and C<component> variable will
|
||||
reference the same L<Template::Document> object. In any other template
|
||||
component called from the main template, the C<template> variable
|
||||
will remain unchanged, but C<component> will contain a new reference
|
||||
to the current component.
|
||||
|
||||
This example should demonstrate the difference:
|
||||
|
||||
$template->process('foo')
|
||||
|| die $template->error(), "\n";
|
||||
|
||||
F<foo> template:
|
||||
|
||||
[% template.name %] # foo
|
||||
[% component.name %] # foo
|
||||
[% PROCESS footer %]
|
||||
|
||||
F<footer> template:
|
||||
|
||||
[% template.name %] # foo
|
||||
[% component.name %] # footer
|
||||
|
||||
Additionally, the C<component> variable has two special fields:
|
||||
C<caller> and C<callers>. C<caller> contains the name of the template
|
||||
that called the current template (or undef if the values of C<template>
|
||||
and C<component> are the same). C<callers> contains a reference to a
|
||||
list of all the templates that have been called on the road to calling
|
||||
the current component template (like a call stack), with the
|
||||
outer-most template first.
|
||||
|
||||
Here's an example:
|
||||
|
||||
F<outer.tt2> template:
|
||||
|
||||
[% component.name %] # 'outer.tt2'
|
||||
[% component.caller %] # undef
|
||||
[% component.callers %] # undef
|
||||
[% PROCESS 'middle.tt2' %]
|
||||
|
||||
F<middle.tt2> template:
|
||||
|
||||
[% component.name %] # 'middle.tt2'
|
||||
[% component.caller %] # 'outer.tt2'
|
||||
[% component.callers %] # [ 'outer.tt2' ]
|
||||
[% PROCESS 'inner.tt2' %]
|
||||
|
||||
F<inner.tt2> template:
|
||||
|
||||
[% component.name %] # 'inner.tt2'
|
||||
[% component.caller %] # 'middle.tt2'
|
||||
[% component.callers %] # [ 'outer.tt2', 'middle.tt2' ]
|
||||
|
||||
=head2 loop
|
||||
|
||||
Within a C<FOREACH> loop, the C<loop> variable references the
|
||||
L<Template::Iterator> object responsible for controlling the loop.
|
||||
|
||||
[% FOREACH item = [ 'foo', 'bar', 'baz' ] -%]
|
||||
[% "Items:\n" IF loop.first -%]
|
||||
[% loop.count %]/[% loop.size %]: [% item %]
|
||||
[% END %]
|
||||
|
||||
=head2 error
|
||||
|
||||
Within a C<CATCH> block, the C<error> variable contains a reference to the
|
||||
L<Template::Exception> object thrown from within the C<TRY> block. The
|
||||
C<type> and C<info> methods can be called or the variable itself can
|
||||
be printed for automatic stringification into a message of the form
|
||||
"C<$type error - $info>". See L<Template::Exception> for further details.
|
||||
|
||||
[% TRY %]
|
||||
...
|
||||
[% CATCH %]
|
||||
[% error %]
|
||||
[% END %]
|
||||
|
||||
=head2 content
|
||||
|
||||
The C<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 %]
|
||||
<blockquote class="prose">
|
||||
[% content %]
|
||||
</blockquote>
|
||||
[% END %]
|
||||
|
||||
=head1 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.
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
586
database/perl/vendor/lib/Template/Manual/Views.pod
vendored
Normal file
586
database/perl/vendor/lib/Template/Manual/Views.pod
vendored
Normal file
@@ -0,0 +1,586 @@
|
||||
#============================================================= -*-perl-*-
|
||||
#
|
||||
# Template::Manual::Views
|
||||
#
|
||||
# AUTHOR
|
||||
# Andy Wardley <abw@wardley.org>
|
||||
#
|
||||
# COPYRIGHT
|
||||
# Copyright (C) 1996-2007 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 NAME
|
||||
|
||||
Template::Manual::Views - Template Toolkit views (experimental)
|
||||
|
||||
=head1 Overview
|
||||
|
||||
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
|
||||
C<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 independent, 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.
|
||||
|
||||
=head1 Views as Template Collectors/Providers
|
||||
|
||||
The C<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 C<END> directive.
|
||||
|
||||
[% VIEW myview %]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
The first role of a view is to act as a collector and provider of templates.
|
||||
The C<include()> method can be called on a view to effectively do the same
|
||||
thing as the C<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 'C<prefix>' and 'C<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 C<AUTOLOAD> method which maps method names to the
|
||||
C<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') %]
|
||||
|
||||
=head1 Local BLOCK Definitions
|
||||
|
||||
A C<VIEW> definition can include C<BLOCK> definitions which remain local to
|
||||
the view. A request for a particular template will return a C<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 C<BLOCK> definitions, a C<VIEW> can contain any other
|
||||
template directives. The entire C<VIEW> definition block is processed to
|
||||
initialise the view but no output is generated (this may change RSN -
|
||||
and get stored as 'C<output>' item, subsequently accessible as C<[%
|
||||
view.output %]>). However, directives that have side-effects, such as
|
||||
those that update a variable, will have noticeable consequences.
|
||||
|
||||
=head1 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 (C<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 C<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 'C<title>' as a simple variable, a template
|
||||
defined in an external file, possibly with a prefix/suffix automatically
|
||||
appended, or as a local C<BLOCK> definition within the C<[% VIEW %] ... [% END %]>
|
||||
definition. If you use the syntax above then the view will Do The Right
|
||||
Thing to return the appropriate output.
|
||||
|
||||
At the C<END> of the C<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 C<END> of the C<VIEW> definition block then
|
||||
a C<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 C<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 C<base>
|
||||
parameter. This example shows how a base class view is defined which
|
||||
applies a C<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 C<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 C<INCLUDE/PROCESS/WRAPPER> directives work entirely
|
||||
independently 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
|
||||
C<VIEW ... END> block by its specified name and also by the special name
|
||||
'C<view>' (similar to the C<my $self = shift;> in a Perl method or the
|
||||
'C<this>' pointer in C++, etc). The view is initially unsealed allowing
|
||||
any data items to be defined and updated within the C<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 (C<SEALED>), it should be possible to set an option in the view to
|
||||
allow external contexts to update existing variables (C<UPDATE>) or even
|
||||
create totally new view variables (C<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, 'C<fancy>', or by the general name, 'C<view>'. Outside of the
|
||||
view block, however, you should always use the given name, 'C<fancy>':
|
||||
|
||||
[% fancy.title %]
|
||||
[% fancy.author %]
|
||||
[% fancy.col.bg %]
|
||||
|
||||
The choice of given name or 'C<view>' is much more important when it
|
||||
comes to C<BLOCK> definitions within a C<VIEW>. It is generally recommended
|
||||
that you use 'C<view>' inside a C<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 'C<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 C<foo> variable, the header
|
||||
block still correctly accesses the C<title> attribute of the view to
|
||||
which it belongs. Whenever a view C<BLOCK> is processed, the C<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 C<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 C<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 'C<::>' converted to a single 'C<_>'.
|
||||
|
||||
[% 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 ('C<thingies>' and 'C<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 C<default> map entry, specified as part of the C<map>
|
||||
hash or as a parameter by itself.
|
||||
|
||||
[% VIEW foo
|
||||
map = { ... },
|
||||
default = 'whatever'
|
||||
%]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
or
|
||||
|
||||
[% VIEW foo %]
|
||||
[% view.map = { ... }
|
||||
view.default = 'whatever'
|
||||
%]
|
||||
...
|
||||
[% END %]
|
||||
|
||||
The C<print()> method provides one more piece of magic. If you pass it a
|
||||
reference to an object which provides a C<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 C<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 I<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 C<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 C<XML::DOM> trees. The documentation for the
|
||||
C<Template::Plugin::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 C<File>/C<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 C<pod/html/head1>, C<pod/html/head2>, C<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: F<t/pod.t> and
|
||||
F<t/view.t> which may shed some more light on this. See the distribution
|
||||
sub-directory F<examples/pod/html> for examples of Pod -E<gt> HTML templates.
|
||||
|
||||
=cut
|
||||
|
||||
# Local Variables:
|
||||
# mode: perl
|
||||
# perl-indent-level: 4
|
||||
# indent-tabs-mode: nil
|
||||
# End:
|
||||
#
|
||||
# vim: expandtab shiftwidth=4:
|
||||
Reference in New Issue
Block a user