1017 lines
31 KiB
Plaintext
1017 lines
31 KiB
Plaintext
|
|
=head1 NAME
|
|
|
|
GT::Template::Tutorial - Gossamer Threads template syntax documentation
|
|
|
|
=head1 Template Syntax
|
|
|
|
At its most basic level, the template parser replaces tags with content. By
|
|
default a tag is anything enclosed between C<E<lt>%> and C<%E<gt>>. For the
|
|
purposes of this document, these two values will be assumed.
|
|
|
|
=head2 Variable Substitution
|
|
|
|
At the simplest level of GT::Template templates are simple variable
|
|
replacements. For example, consider the following template code:
|
|
|
|
You are <%age%> years old.
|
|
|
|
This would be displayed with '<%age%>' replaced with a value. For example, if
|
|
C<age> was given a value of 35, the above would be displayed as:
|
|
|
|
You are 35 years old.
|
|
|
|
A more complex form of variable access is also available, which is covered
|
|
later in the
|
|
L<Advanced variables using references|/"Advanced variables using references">
|
|
section of this document.
|
|
|
|
=head2 Sets
|
|
|
|
You can set values from within a template by using:
|
|
|
|
<%set Title = 'Login'%>
|
|
|
|
and now <%Title%> will be equal to Login. This is especially useful for
|
|
C<include>s, where you could, for example, set a Title variable to a string
|
|
that will be displayed in an included template.
|
|
|
|
You can also set one variable to the value of another, such as:
|
|
|
|
<%set title = $return_title%>
|
|
|
|
This will set the variable "title" with the value of the variable "return_title."
|
|
|
|
Note that when using " " for a string, you may include variables by using the
|
|
$variable or ${variable} syntaxes, such as:
|
|
|
|
<%set title = "A $main_title page: ${secondary_title}Z"%>
|
|
|
|
Additionally, the sequence "\n", "\t", and "\r" produce a linefeed character,
|
|
tab, and carriage return, respectively. Additionally, a \ may precede any
|
|
non-letter/word character to mean just the character:
|
|
|
|
<%set price_display = "Price:\n\tTotal: \"\$3.40\""%>
|
|
|
|
which would set price_display to:
|
|
|
|
Price:
|
|
Total: "$3.40"
|
|
|
|
Note that the interpolation of variables and \ escapes do *not* apply when
|
|
using 'single quotes' as the string delimiter. In such cases, only \\ and \'
|
|
have a special meaning - they are used for a literal \ and ' character.
|
|
|
|
=head2 Operators
|
|
|
|
GT::Template is capable of performing some basic math calculations and one
|
|
string-multiple function in templates displaying the results in the parsed template.
|
|
|
|
For example, if the 'age' variable is 15, the following tag:
|
|
|
|
<%age + 10%>
|
|
|
|
will display 25 in the template. Besides addition there are the following
|
|
operators, which work as expected:
|
|
-
|
|
*
|
|
/
|
|
% (remainder)
|
|
^ (raised to the power of)
|
|
|
|
The following operators are also worth explaining:
|
|
|
|
i/
|
|
/N
|
|
~ (Remainder difference)
|
|
x (String multiplier)
|
|
|
|
i/ performs integral division between the two numbers. For example, '4' i/ 3
|
|
will result in 1, '100' i/ 3 would result in 33, etc.
|
|
|
|
/N does not actually use a literal N, instead N should be replaced by a number.
|
|
The result will be formatted (and rounded) to N decimal places. For example,
|
|
'4' /3 3 would result in: 1.333, while '5' /3 3 would give you: 1.667.
|
|
'3' /3 3 would be 1.000.
|
|
|
|
Note that i/ and /0 are not the same, as can be illustrated here:
|
|
38 i/ '3.8' => 12 - becomes 38 i/ 3
|
|
38 /0 '3.8' => 10 - 38 / 3.8 is calculated, then rounded with 0 decimal place
|
|
precision.
|
|
|
|
You should be sure of which one you mean to use, or you may end up with
|
|
unexpected results.
|
|
|
|
~ is used to get a remainder difference. Where 8 % 5 would return 3, 8 ~ 5
|
|
will return 2. This is calculated as the divisor (5) minus the remainder (3).
|
|
This is useful when generating tables in a loop - when you hit the end of the
|
|
loop, you want to be able to put an empty cell with a colspan of however many
|
|
rows are left. Something like: <%row_num ~ 5%> will give you the proper value.
|
|
|
|
As mentioned, there is also one string operator, 'x'. When you use 'x', the
|
|
variable (or value as we'll see in a second) will be displayed "n" times, where
|
|
"n" is the integral value of the right hand side.
|
|
|
|
Assuming that the 'name' variable is 'Jason', this tag:
|
|
|
|
<%name x 2%>
|
|
|
|
will display JasonJason in the parsed template. Like this, it isn't all that
|
|
useful because you could simply put C<E<lt>%name%E<gt>E<lt>%name%E<gt>> in your
|
|
template. However, the right hand side may instead use the value of a
|
|
variable, such as in this example:
|
|
|
|
<%name x $print%>
|
|
|
|
Assuming that 'name' is still 'Jason', and that 'print' is 3, this would display:
|
|
|
|
JasonJasonJason
|
|
|
|
Though this is useful as is, this is taken a step furthur: the first does not
|
|
always have to be a variable. By using 'single quotation marks' or "double
|
|
quotation marks" we can display fixed text a variable number of times.
|
|
|
|
For example:
|
|
|
|
<%'My Text' x $print%>
|
|
|
|
Again assuming that the variable C<print> is 3, this will print:
|
|
|
|
My TextMy TextMy Text
|
|
|
|
this comes in handy when doing things like indentation.
|
|
|
|
The same string quoting interpolation rules mentioned in L</Sets> apply here -
|
|
both " and ' are accepted as delimiters, with different interpolation rules.
|
|
|
|
=head2 Set modifiers
|
|
|
|
You can add, subtract, etc. to your variables with the following syntax:
|
|
|
|
<%set variable += 3%>
|
|
|
|
+= can be changed to the following:
|
|
|
|
+= - Adds to a variable
|
|
-= - Subtracts from a variable
|
|
*= - Multiplies a variable
|
|
/= - Divides a variable
|
|
%= - Set a variable to a remainder
|
|
^= - Raise a variable to a power
|
|
.= - Appends to a string
|
|
x= - "Multiplies" a string - "ab" x 3 is "ababab"
|
|
||= - sets a variable if not already set
|
|
&&= - sets a variable if already set
|
|
|
|
=head2 Set + Operators
|
|
|
|
You can combine the above operator functions with sets (including sets with modifiers) by simply adding C<set foo => to the beginning of the operator tag. For example:
|
|
|
|
<%set foo += 3 * 3%> # foo is now set to whatever it was, + 9
|
|
<%set foo *= 3 + 3%> # foo has been multiplied by 9
|
|
<%set foo = $bar /0 2%> # foo is now set to half of $bar, rounded to an integer (see /N above)
|
|
|
|
=head2 Conditionals
|
|
|
|
You can use conditionals C<if>, C<ifnot> (or C<unless>), C<elseif>, and C<else>
|
|
as in:
|
|
|
|
<%if age%>
|
|
You are <%age%> years old.
|
|
<%elseif sex%>
|
|
You are <%sex%>.
|
|
<%else%>
|
|
I know nothing about you!
|
|
<%endif%>
|
|
|
|
|
|
<%ifnot login%>
|
|
You are not logged in!
|
|
<%endif%>
|
|
|
|
|
|
<%unless age%>
|
|
I don't know how old you are!
|
|
<%endif%>
|
|
|
|
If you like you may use C<elsif> instead of C<elseif> (drop the 'e').
|
|
C<unless> and C<endunless> are aliases for C<ifnot> and C<endif>, respectively,
|
|
and may be used interchangeably.
|
|
|
|
All conditionals must be ended with an C<endif> tag, although may contain any
|
|
number of C<elseif> conditionals and/or a single C<else> conditional between
|
|
the C<if> and C<endif> tags.
|
|
|
|
Conditionals may be nested within each other, to arbitrary depth:
|
|
|
|
<%if age%>
|
|
You are <%age%> years old
|
|
<%if sex%>
|
|
and you are <%sex%>
|
|
<%endif%>
|
|
<%endif%>
|
|
|
|
=head2 Comparisons
|
|
|
|
Inside conditionals you can use C<E<lt>>, C<E<gt>>, C<E<lt>=>, C<E<gt>=>,
|
|
C<==>, C<!=>, C<lt>, C<gt>, C<le>, C<ge>, C<eq>, C<ne>, C<contains>, C<starts>,
|
|
and C<ends>. This allows you to do things like:
|
|
|
|
<%if age == 15%>
|
|
You're 15!
|
|
<%endif%>
|
|
|
|
where the == can be replaced with any operator listed above. If the right hand
|
|
side of the equation starts with a '$', the string will be interpolated as a
|
|
variable. If you wish to use a string starting with a literal $, you can avoid
|
|
this interpolation by adding quotes around the right hand value. The left hand
|
|
side is always a variable.
|
|
|
|
C<lt>, C<gt>, C<le>, C<ge>, C<eq>, and C<ne> are the alphabetical equivelants
|
|
of C<E<lt>>, C<E<gt>>, C<E<lt>=>, C<E<gt>=>, C<==>, and C<!=>, respectively.
|
|
In terms of less-than and greater-than comparisons, the comparison is similar
|
|
to a dictionary: C<aa> is less than C<b>, but greater than C<a>; C<10> is
|
|
greater than C<1>, but less than C<2>; C<Z> is less than C<a>, due to
|
|
capitalization (unless using C<ilt>, C<ige>, etc.). C<contains> will be true
|
|
if the variable contains the right-hand side. C<starts> and C<ends> will be
|
|
true if the variable starts with, or ends with, respectively, the right-hand
|
|
value.
|
|
|
|
There are also case-insensitive versions of the string comparisons - they are:
|
|
C<ilt>, C<igt>, C<ile>, C<ige>, C<ieq>, C<ine>, C<icontains>, C<istarts>, and
|
|
C<iends>. These comparisons work exactly like the versions _without_ the i
|
|
except that the comparison is case-insensitive.
|
|
|
|
C<start>, C<istart>, C<end>, and C<iend> are aliases for the comparison with an
|
|
added C<s>. C<like> and C<ilike> are deprecated aliases for C<contains> and
|
|
C<icontains> and should no longer be used.
|
|
|
|
=head2 Logical Operators
|
|
|
|
If statements (including elseif statements) may contain multiple conditions
|
|
using one of the two booleans operators C<or> and C<and>. For example:
|
|
|
|
<%if age and sex and color%>
|
|
I know your age, sex and hair color.
|
|
<%else%>
|
|
I don't have enough information about you!
|
|
<%endif%>
|
|
|
|
<%if age < 10 or age > 90 or status eq banned%>
|
|
You are not permitted to view this page.
|
|
<%endif%>
|
|
|
|
It should be noted that it is currently not possible to mix both C<or> and
|
|
C<and> in a single if statement - you may, however, use the same boolean
|
|
multiple times in a single statement. (Brackets) are also not currently
|
|
supported.
|
|
|
|
Internally, if statements will be short-circuited as soon as possible. That
|
|
means that for the following tag:
|
|
<%if foo = 1 or foo = 2 or foo = 3%>
|
|
the following will occur:
|
|
|
|
First, variable "foo" will be tested to see if it is numerically equal to 1.
|
|
If it is, the rest of the checks are aborted since the if will pass regardless.
|
|
If it is not, foo = 2 will be checked, and if true, will abort the next check,
|
|
and so on until a condition is true or the end of the list of statements is
|
|
encountered.
|
|
|
|
Likewise with C<and>, except that with C<and> the parser will stop checking as
|
|
soon as the first false value is encountered (since a false value means the
|
|
entire condition will be false).
|
|
|
|
=head2 Loops
|
|
|
|
Inside your template you can use loops to loop through an array reference, code
|
|
reference, or through a fixed set of numbers. If using an array reference, each
|
|
element should be either a hash reference or a scalar value, and when using a
|
|
code reference every return should be a hash reference or scalar value, or
|
|
C<undef> to end the loop. The variables in the hash reference will then be
|
|
available for that iteration of the loop, or, if using scalar values, the value
|
|
will be available as the <%loop_value%> variable.
|
|
|
|
For example:
|
|
|
|
<%loop people%>
|
|
<%if name eq 'Jason'%>
|
|
I have <%color%> hair.
|
|
<%else%>
|
|
<%name%> has <%color%> hair.
|
|
<%endif%>
|
|
<%endloop%>
|
|
|
|
would loop through all values of pens, and for each one would print the
|
|
sentence substituting the color of the pen. Also, inside your loop you can use
|
|
the following tags:
|
|
|
|
<%row_num%> - a counter for what row is being looped, starts at 1.
|
|
<%first%> - boolean value that is true if this is the first row, false otherwise.
|
|
<%last%> - boolean value that is true if this is the last row, false otherwise.
|
|
<%inner%> - boolean value that is true if this is not first and not last.
|
|
<%even%> - boolean value is true if row_num is even.
|
|
<%odd%> - boolean value is true if row_num is odd.
|
|
|
|
You could use even and odd tags to produce alternating colors like:
|
|
|
|
<%loop results%>
|
|
<tr><td bgcolor="<%if even%>white<%else%>silver<%endif%>">..</td></tr>
|
|
<%endloop%>
|
|
|
|
Also, you can use <%lastloop%> to abort the loop and skip straight to the
|
|
current loop's <%endloop%> tag, and <%nextloop%> to load the next loop
|
|
variables and jump back to the beginning of the loop.
|
|
|
|
The 6 built-in variables (row_num, first, last, ...) and any variables set via
|
|
the loop variable will only be available for the current loop iteration, after
|
|
which the variables of the next loop iteration will be set, or, for variables
|
|
that exist in one iteration but not the next, the variables that existed prior
|
|
to the loop being called will be restored.
|
|
|
|
When using array reference-based loops (which are much more common than and
|
|
preferred to the alternative code reference-based loops), you can use the
|
|
C<loopvar.length> variable which will contain the number of items contained
|
|
within the loop.
|
|
|
|
To loop through a particular range of numbers, you can use the following syntax:
|
|
|
|
<%loop 1 to 5%>
|
|
...
|
|
<%endloop%>
|
|
|
|
This can alternatively be written as:
|
|
|
|
<%loop 1 .. 5%>
|
|
...
|
|
<%endloop%>
|
|
|
|
Additionally, either or both of the two values may be a variable, such as:
|
|
|
|
<%loop $start to $finish%>
|
|
...
|
|
<%endloop%>
|
|
|
|
Inside the loop, the current value is accessible via the <%loop_value%>
|
|
variable, as if you were simply looping over an array of integers. The looping
|
|
always occurs in increments of C<1>, and the start and end values will have any
|
|
fractional value truncated.
|
|
|
|
=head2 Filters
|
|
|
|
Filters can be used to alter the appearance of a tag. The general format of
|
|
a filter is:
|
|
|
|
<%filtername variable%>
|
|
|
|
Multiple filternames can be chained together as well, such as:
|
|
|
|
<%filtername1 filtername2 filtername3 variable%>
|
|
|
|
The filter closest to the variable name will be applied first. In the above
|
|
example, that means C<filtername3> will be applied, then
|
|
C<filtername2> applied to the result, then C<filtername1> applied to that
|
|
result.
|
|
|
|
The filters available include:
|
|
|
|
=over 4
|
|
|
|
=item escape_html
|
|
|
|
This filter will perform HTML-escaping of the variable. Specifically,
|
|
C<E<lt>>, C<E<gt>>, C<&>, and C<"> are converted to their HTML equivelants
|
|
(C<<>, C<>>, C<&>, and C<">, respectively).
|
|
|
|
Assuming that C<somevar> contains the value C<abc&def"ghi>, the following:
|
|
|
|
<%escape_html somevar%>
|
|
|
|
will become:
|
|
|
|
abc&def"ghi
|
|
|
|
If the template parser has escape mode turned on, this would cause variables to
|
|
be escaped *twice* -- unless, of course, the variable is passed as a scalar
|
|
reference.
|
|
|
|
=item unescape_html
|
|
|
|
This filter will unescape the HTML escapes C<&>, C<<>, C<>>, and
|
|
C<"> back to their original forms of C<E<lt>>, C<E<gt>>, C<&>, and C<">,
|
|
respectively.
|
|
|
|
=item escape_url
|
|
|
|
When adding a value to a URL is necessary, C<escape_url> can be used to convert
|
|
characters other than alphanumeric (a-z, A-Z, 0-9) C<.>, and <-> to the
|
|
URL-escaped %XX form (where XX is a two-digit hexadecimal value).
|
|
|
|
For example, if you want to use the tag C<E<lt>%name%E<gt>> in a URL, it is
|
|
recommended to instead use C<E<lt>%escape_url name%E<gt>>. In particular, this
|
|
avoids the possibility of the CGI parameters being passed incorrectly when a
|
|
variable contains letters such as C<?>, C<;>, C<=>, etc.
|
|
|
|
=item unescape_url
|
|
|
|
This filter performs the opposite of escape_url - that is, any sequence of
|
|
C<%XX>, where C<XX> is any two hexadecimal characters, and the C<+> character
|
|
will be converted to the appropriate character - a single space in the case of
|
|
the C<+>.
|
|
|
|
=item escape_js
|
|
|
|
This filter will safely escape a javascript variable so that it can be used
|
|
inside a javascript string delimited with either "double quotes" or 'single
|
|
quotes'. Specifically, it puts a C<\> in front of every C<\>, C<'> and C<">
|
|
character and converts newlines to C<\n>.
|
|
|
|
var javascriptVariable = '<%escape_js somevar%>';
|
|
|
|
=item nbsp
|
|
|
|
This filter will display the variable with all whitespace converted to HTML
|
|
non-breaking space escapes (C< >). This is particularly useful when
|
|
attempting to display something accurately which may contain spaces, or when
|
|
attempting to ensure that a value containing spaces does not wrap over multiple
|
|
lines.
|
|
|
|
=item uc
|
|
|
|
=item lc
|
|
|
|
These filters display the variable with all letters changed to uppercase
|
|
(C<uc>) or lowercase (C<lc>).
|
|
|
|
=item ucfirst
|
|
|
|
=item lcfirst
|
|
|
|
These filters convert the first character of the variable to uppercase
|
|
(C<ucfirst>) or lowercase (C<lcfirst>).
|
|
|
|
=back
|
|
|
|
Some filter examples, assuming the following variables have been set:
|
|
|
|
var1 => "<html>",
|
|
var2 => "test<b>&</b>two",
|
|
var3 => "test't<hr>ee",
|
|
fname => "john",
|
|
lname => "DOE"
|
|
|
|
Examples:
|
|
|
|
Template code --> Becomes
|
|
============= =======
|
|
|
|
<tag attr="<%escape_html var1%>"> --> <tag attr="<html>">
|
|
<%unescape_html var2%> --> test<b>&</b>two
|
|
var jsVar = '<%escape_js var3%>'; --> var jsVar = 'test\'three';
|
|
<a href="a?f=<%escape_url unescape_html var2">
|
|
--> <a href="a?f=test%3Cb%3E%26%3C%2Fb%3Etwo">
|
|
<a onclick="jsVar = '<%escape_html escape_js var3%>'">
|
|
--> <a onclick="jsVar = 'test\'t<hr>ee'">
|
|
|
|
=head2 Includes
|
|
|
|
You can include other files. Any tags inside the includes will be evaluated as
|
|
if the content of the included file were included in the current file (although
|
|
there is one exception: unclosed if tags inside the include will be implicitly
|
|
ended). Includes can occur anywhere - inside if statements, for loops, other
|
|
includes, etc. The following tag:
|
|
|
|
<%if info%>
|
|
<%include info.txt%>
|
|
<%else%>
|
|
<%include noinfo.txt%>
|
|
<%endif%>
|
|
|
|
will include either the file info.txt (if info is true) or noinfo.txt (if info
|
|
is false or not set). It must be in the template's root directory which is
|
|
defined using $obj->root, or '.' by default.
|
|
|
|
A useful application of the include tag is to include files inside a loop, as in:
|
|
|
|
<%loop people%>
|
|
<%include person.txt%>
|
|
<%endloop%>
|
|
|
|
Another useful example is in including a common header or footer to all pages.
|
|
If, for example, you have a header.htm that you wish to be included, but it
|
|
needs a variable title, you could combine the C<include> with a C<set>, such
|
|
as:
|
|
|
|
<%set Title = 'Login'%>
|
|
<%include header.htm%>
|
|
|
|
and then in your header.htm:
|
|
|
|
<html>
|
|
<head>
|
|
<title><%Title%></title>
|
|
</head>
|
|
|
|
This would allow you to have different titles, but still include the same
|
|
header template on each page.
|
|
|
|
GT::Template also supports including a file based on the value of a variable by
|
|
specifying the variable name (starting with a $) for the filename:
|
|
|
|
<%include $var%>
|
|
|
|
This allows for more powerful include abilities. For example, if you wanted
|
|
to have a single outer template which includes another, variable template you
|
|
could use an outer template (for the purposes of this example, assume this
|
|
template is named 'outer.html') something like:
|
|
|
|
<html>
|
|
<head><title><%title%></title></head>
|
|
<body>
|
|
<div style="border: 5px solid black">
|
|
<%include $inner_template%>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
|
|
Then, inside other templates, you would do:
|
|
|
|
abc.html:
|
|
=========
|
|
|
|
<%set inner_template = 'abc_content.html'%>
|
|
<%set title = 'ABC'%>
|
|
<%include layout.html%>
|
|
|
|
xyz.html:
|
|
=========
|
|
|
|
<%set inner_template = 'xyz_content.html'%>
|
|
<%set title = 'XYZ'%>
|
|
<%include layout.html%>
|
|
|
|
Now both abc.html and xyz.html would show up with the same page layout defined
|
|
in layout.html, with a content section coming from their respective
|
|
*_content.html templates.
|
|
|
|
If an included template does not exist in the current template set, inherited
|
|
template sets will be checked as well. For details on template set
|
|
inheritance, see L<GT::Template::Inheritance>.
|
|
|
|
=head2 Functions
|
|
|
|
You can call functions in either the variable substitution or in the
|
|
comparison. The function must reside in a package, and you must do the full
|
|
qualification.
|
|
|
|
A script header normally looks like <%CGI::header%>
|
|
|
|
which would call C<CGI::header()>. You can pass arguments to this as in:
|
|
|
|
A script header normally looks like <%CGI::header('text/html')%>.
|
|
|
|
Also, you can pass any currently available template variable to the function
|
|
by prefixing it with a $, such as:
|
|
|
|
<%CGI::header($variable)%>
|
|
|
|
Multiple arguments may be passed by comma separating the arguments, as in:
|
|
<%Mypackage::mysub($age, 'Title')%>
|
|
|
|
If a function returns a hash reference, those values will be added to the
|
|
current substitution set. Suppose you have a function:
|
|
|
|
package Mypackage;
|
|
sub load_globals {
|
|
..
|
|
return { age => 15, color => red };
|
|
}
|
|
|
|
You could then do:
|
|
|
|
<%Mypackage::load_globals%>
|
|
You are <%age%> years old, with <%color%> hair!
|
|
|
|
Functions are loaded while parsing, so calling the function with different
|
|
arguments (to set your variables to different values) is possible.
|
|
|
|
Since package names can make functions rather long and ugly, you can call
|
|
-E<gt>parse() with an "alias" key in the options hash. This key should contain
|
|
shortcut => function pairs. For example, if you want to call Foo::Bar::blah()
|
|
in your template, you could pass: asdf => 'Foo::Bar::blah', and when <%asdf%>
|
|
or <%asdf(...)%> is encountered, Foo::Bar::blah will be called.
|
|
|
|
=head2 Comparisons with Functions
|
|
|
|
You can combine use a function for an if/elseif statement I<value>, as in:
|
|
|
|
<%if age == My::years_old%>
|
|
You are the same age as me!
|
|
<%endif%>
|
|
|
|
which would call My::years_old() and compare the return value to the value of
|
|
the "age" variable.
|
|
|
|
=head2 Sets with Functions
|
|
|
|
You may use a function call as the I<value> of a "set" instruction to set a
|
|
template variable based on the return value of the function. The following
|
|
code will set a variable named "age" to the return value of Mypackage::age():
|
|
|
|
<%set age = Mypackage::age%>
|
|
|
|
Arguments passed are the same as the arguments to a regular function.
|
|
|
|
=head2 Comments
|
|
|
|
Comments can be used to add comments about a template, or comment out existing
|
|
sections of template code. Comments start with the template opening tag
|
|
followed by C<--> (typically C<E<lt>%-->) and end with C<--> followed by the
|
|
template closing tag (typically C<--%E<gt>>). Additionally, comments may
|
|
contain other template tags, including other comments.
|
|
|
|
A simple comment:
|
|
|
|
<%-- This is a comment, and will not be displayed --%>
|
|
|
|
A comment example demonstrating included tags and nested comments:
|
|
|
|
<%--
|
|
<%template_tag%>
|
|
<%-- This is a comment, and will not be displayed <%-- another comment --%>--%>
|
|
<%if test%>example<%endif%>
|
|
--%>
|
|
|
|
=head2 Advanced variables using references
|
|
|
|
A more complex form of variable access is available which allows you to access
|
|
values contained within hash and/or array reference variables. These variables
|
|
can be used anywhere ordinary variables are permitted - including C<set>s.
|
|
|
|
For example, assume a variable named "person" has been passed to the template
|
|
parser with a value of:
|
|
|
|
{
|
|
name => "John Doe",
|
|
age => 35,
|
|
hair => "brown"
|
|
}
|
|
|
|
The following example:
|
|
|
|
<%person.name%> is <%person.age%> and has <%person.hair%> hair.
|
|
|
|
Would display:
|
|
|
|
John Doe is 35 and has brown hair.
|
|
|
|
Arrays are accessed in exactly the same way, using the array index (starting
|
|
from 0). Assume for the following example that a variable C<phone> has been
|
|
provided, with the following value:
|
|
|
|
['(555) 555-5678', '(555) 555-6789', '(555) 555-7890']
|
|
|
|
The following example:
|
|
|
|
Primary phone number: <%phone.0%>
|
|
Secondary numbers: <%loop phone%><%unless first%><%loop_value%> <%endunless%><%endloop%>
|
|
|
|
Will display:
|
|
|
|
Primary phone number: (555) 555-5678
|
|
Secondary numbers: (555) 555-6789 (555) 555-7890
|
|
|
|
Furthurmore, the size of array reference values (such as array reference-based
|
|
loops) may be determined by adding C<.length> to the end of the tag. Using the
|
|
same "phone" value above, the following:
|
|
|
|
Primary phone number: <%phone.0%>
|
|
<%if phone.length > 1%>Secondary numbers: <%loop phone%><%unless first%><%loop_value%> <%endunless%><%endloop%><%endif%>
|
|
|
|
Would display the same content, however if the "phone" value contained only a
|
|
single value, the "Secondary numbers" line would not be displayed at all:
|
|
|
|
Primary phone number: (555) 555-5678
|
|
|
|
Data structures of abitrary depth are supported, and can consist of any
|
|
combination of array and hash references.
|
|
|
|
Consider the following more complex example, with a C<people> variable set to
|
|
the following loop:
|
|
|
|
[
|
|
{
|
|
name => "John Doe",
|
|
age => 35,
|
|
hair => "no",
|
|
phone => {
|
|
work => "(555) 555-5678",
|
|
home => "(555) 555-6789"
|
|
}
|
|
},
|
|
{
|
|
name => "Jane Doe",
|
|
age => 25,
|
|
hair => "brown",
|
|
phone => {
|
|
work => "(555) 555-5678",
|
|
home => "(555) 555-1234"
|
|
}
|
|
}
|
|
]
|
|
|
|
The following template code:
|
|
|
|
<%loop person%><%row_num%>. <%name%>, <%age%> years of age, <%hair%> hair. Phone: work: <%phone.work%>, home: <%phone.home%>.
|
|
<%endloop%>
|
|
The first person on the list, <%person.0.name%>, can be reached at either <%person.0.phone.work%> or <%person.0.phone.home%>.
|
|
|
|
Will display:
|
|
|
|
1. John Doe, 35 years of age, no hair. Phone: work: (555) 555-5678, home: (555) 555-6789.
|
|
2. Jane Doe, 25 years of age, brown hair. Phone: work: (555) 555-5678, home: (555) 555-1234.
|
|
|
|
The first person on the list, John Doe, can be reached at either (555) 555-5678 or (555) 555-6789.
|
|
|
|
In addition to hash reference support, L<GT::Config|GT::Config> objects and
|
|
L<GT::CGI|GT::CGI> objects can be accessed as if they were hashes. So with:
|
|
|
|
config => $gt_config_object,
|
|
in => $cgi_object
|
|
|
|
The following:
|
|
|
|
<%config.variable1%>
|
|
<%in.parameter1%>
|
|
|
|
would access C<$gt_config_object-E<gt>{variable1}> and
|
|
C<$cgi_object-E<gt>param('parameter1')>. If used in a C<E<lt>%set ...%E<gt>>
|
|
command, the following:
|
|
|
|
<%set config.variable1 = 4%>
|
|
<%set in.parameter1 = 5%>
|
|
|
|
would set C<$gt_config_object-E<gt>{variable1}> to 4, and call
|
|
C<$cgi_object-E<gt>param('parameter1', '5')>, thereby setting it to 5.
|
|
|
|
Furthermore, complex variable expressions may contain other variables, such as:
|
|
|
|
<%set parameter = 'variable1'%>
|
|
<%config.$parameter%>
|
|
|
|
which would display the same thing as C<E<lt>%config.variable1%E<gt>>. Note
|
|
that complex variables cannot be used here - that is:
|
|
|
|
<%set abc.def = 'ghi'%>
|
|
<%config.$abc.def%>
|
|
|
|
will read the value of abc, then access config.(value).def. It I<is>, however,
|
|
possible to put a . inside a value, such as:
|
|
|
|
<%set abc = 'def.ghi'%>
|
|
<%config.$abc%>
|
|
|
|
would be equivalent to:
|
|
|
|
<%config.def.ghi%>
|
|
|
|
Complex variables can be used inside double quoted strings (wherever
|
|
double-quoted strings are accepted) but only in the form ${a.b}. Specifically,
|
|
the following:
|
|
|
|
<%set var1.key1 = 3%><%set var2 = "$var1.key1"%>
|
|
|
|
does not actually set var2 to "3" - the following achieves the desired effect:
|
|
|
|
<%set var1.key1 = 3%><%set var2 = "${var1.key1}"%>
|
|
|
|
Complex variables containing other variables are also supported, such as:
|
|
|
|
<%set var1 = "${var1.$keyvar}"%>
|
|
|
|
=head2 Whitespace compression
|
|
|
|
Normally, template tags do not affect the whitespace around them, however it is
|
|
sometimes desirable or necessary to remove the whitespace immediately before or
|
|
immediately after the tag. Consider the following example, which is intended
|
|
to print the values in 'values' that are odd and less than 10, separated by
|
|
-'s:
|
|
|
|
<%set found_one = 0%>
|
|
<%loop values%>
|
|
<%set odd = loop_value % 2%>
|
|
<%if loop_value < 10 and odd%>
|
|
<%if found_one%>
|
|
<%-- We've seen one before, so print the '-' --%>
|
|
-
|
|
<%else%>
|
|
<%-- We haven't seen one, so don't print the '-', but print it next time --%>
|
|
<%set found_one = 1%>
|
|
<%endif%>
|
|
<%loop_value%>
|
|
<%endif%>
|
|
<%endloop%>
|
|
|
|
will actually produce, given a loopvar containing the values 1 through 15,
|
|
the following output (where _'s are actually spaces):
|
|
|
|
|
|
|
|
____
|
|
____
|
|
________
|
|
____________
|
|
____________
|
|
________
|
|
________1
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
________
|
|
____________
|
|
____________-
|
|
________
|
|
________3
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
________
|
|
____________
|
|
____________-
|
|
________
|
|
________5
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
________
|
|
____________
|
|
____________-
|
|
________
|
|
________7
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
________
|
|
____________
|
|
____________-
|
|
________
|
|
________9
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
____
|
|
____
|
|
|
|
|
|
There are, of course, various ways around this - for instance, you could put
|
|
all the tags on one line with no spaces between them. However, such an
|
|
approach becomes very difficult to look at and use. The alternative is to use
|
|
GT::Templates's whitespace compression tags.
|
|
|
|
Any tag (including comments) may start or end (or start I<and> end) with a ~ -
|
|
if present, leading (if at the beginning of the tag) and/or trailing (if at the
|
|
end of the tag) spaces, tabs, and newline characters will be removed. So, you
|
|
could change the above code to the following:
|
|
|
|
<%set found_one = 0 ~%>
|
|
<%loop values ~%>
|
|
|
|
<%set odd = loop_value % 2 ~%>
|
|
<%if loop_value < 10 and odd ~%>
|
|
<%if found_one ~%>
|
|
<%-- We've seen one before, so print the '-' --~%>
|
|
-
|
|
<%~ else ~%>
|
|
<%-- We haven't seen one, so don't print the '-', but print it next time --~%>
|
|
<%set found_one = 1 ~%>
|
|
<%endif ~%>
|
|
|
|
<%loop_value ~%>
|
|
<%endif ~%>
|
|
|
|
<%endloop%>
|
|
|
|
Assuming the same data, this would give you a result of:
|
|
|
|
1-3-5-7-9
|
|
|
|
The spaces around the tags are not necessary - that is, you could write
|
|
C<E<lt>%~tag_name ~%E<gt>> C<E<lt>%~ tag_name ~ %E<gt>> C<E<lt>% ~ tagname ~ %E<gt>>
|
|
or any other variants. The style in the example above is used only for
|
|
improved readability.
|
|
|
|
Note that this option only affects whitespace in the current template, and does
|
|
not affect the value of variables or the content of includes. Example:
|
|
|
|
abc <%~ varname ~%> def
|
|
|
|
Assuming 'varname' contains the value C<' value '>, the above will produce the
|
|
output:
|
|
|
|
abc value def
|
|
|
|
but I<not>:
|
|
|
|
abcvaluedef
|
|
|
|
Likewise with includes:
|
|
|
|
abc <%~ include page.html ~%> def
|
|
|
|
Assuming page.html contains the following (with a space before "a" and after
|
|
"z"):
|
|
|
|
az
|
|
|
|
you will get the following output:
|
|
|
|
abc az def
|
|
|
|
or possibly, if the include contains a newline character at the end:
|
|
|
|
abc az
|
|
def
|
|
|
|
but I<not>:
|
|
|
|
abcazdef
|
|
|
|
Additionally, you may use the special tag C<E<lt>%~%E<gt>> to eliminate both
|
|
leading and trailing whitespace without needing a tag. For example:
|
|
|
|
a
|
|
<%~%>
|
|
b
|
|
<% ~ %>
|
|
c
|
|
|
|
will output:
|
|
|
|
abc
|
|
|
|
=head2 Variable Dumping
|
|
|
|
Often it is useful to dump the value of all tags available on the current page,
|
|
or the value of a single variable. For this, there is a built-in DUMP function
|
|
to dump a variable:
|
|
|
|
<%DUMP%>
|
|
|
|
<%DUMP variable%>
|
|
|
|
<%DUMP variable.key%>
|
|
|
|
The first example will display a dump of all the tags available wherever the
|
|
C<E<lt>%DUMP%E<gt>> tag is added, while the second and third examples will
|
|
display a dump of the 'variable' and 'variable.key' values, respectively.
|
|
|
|
C<DUMP> tags should only be used for debugging purposes; they are not intended
|
|
to be used on live, publically accessible templates as they may contain
|
|
sensitive data that should not be made publically available.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright (c) 2005 Gossamer Threads, Inc. All Rights Reserved.
|
|
http://www.gossamer-threads.com/
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<GT::Template> - for documentation on invoking the template parser.
|
|
|
|
L<GT::Template::Inheritance> - for documentation on template inheritance.
|
|
|
|
=head1 VERSION
|
|
|
|
Revision: $Id: Tutorial.pod,v 2.11 2005/04/23 23:11:33 brewt Exp $
|
|
|
|
=cut
|