=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%> and C<%E>. 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 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 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 Cs, 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%name%EE%name%E> 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 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 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 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, C (or C), C, and C 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 instead of C (drop the 'e'). C and C are aliases for C and C, respectively, and may be used interchangeably. All conditionals must be ended with an C tag, although may contain any number of C conditionals and/or a single C conditional between the C and C 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>, C>, C=>, C=>, C<==>, C, C, C, C, C, C, C, C, C, and C. 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, C, C, C, C, and C are the alphabetical equivelants of C>, C>, C=>, C=>, C<==>, and C, respectively. In terms of less-than and greater-than comparisons, the comparison is similar to a dictionary: C is less than C, but greater than C; C<10> is greater than C<1>, but less than C<2>; C is less than C, due to capitalization (unless using C, C, etc.). C will be true if the variable contains the right-hand side. C and C 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, C, C, C, C, C, C, C, and C. These comparisons work exactly like the versions _without_ the i except that the comparison is case-insensitive. C, C, C, and C are aliases for the comparison with an added C. C and C are deprecated aliases for C and C 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 and C. 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 and C 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, except that with C 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 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%> .. <%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 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 will be applied, then C applied to the result, then C applied to that result. The filters available include: =over 4 =item escape_html This filter will perform HTML-escaping of the variable. Specifically, C>, C>, C<&>, and C<"> are converted to their HTML equivelants (C<<>, C<>>, C<&>, and C<">, respectively). Assuming that C contains the value C, 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>, C>, C<&>, and C<">, respectively. =item escape_url When adding a value to a URL is necessary, C 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%name%E> in a URL, it is recommended to instead use C%escape_url name%E>. 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 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) or lowercase (C). =item ucfirst =item lcfirst These filters convert the first character of the variable to uppercase (C) or lowercase (C). =back Some filter examples, assuming the following variables have been set: var1 => "", var2 => "test<b>&</b>two", var3 => "test't
ee", fname => "john", lname => "DOE" Examples: Template code --> Becomes ============= ======= --> <%unescape_html var2%> --> test&two var jsVar = '<%escape_js var3%>'; --> var jsVar = 'test\'three';
--> --> =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 with a C, such as: <%set Title = 'Login'%> <%include header.htm%> and then in your header.htm: <%Title%> 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: <%title%>
<%include $inner_template%>
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. =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. 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 -Eparse() 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, 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 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%-->) and end with C<--> followed by the template closing tag (typically C<--%E>). 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 Cs. 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 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 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 objects and L 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{variable1}> and C<$cgi_object-Eparam('parameter1')>. If used in a C%set ...%E> command, the following: <%set config.variable1 = 4%> <%set in.parameter1 = 5%> would set C<$gt_config_object-E{variable1}> to 4, and call C<$cgi_object-Eparam('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%config.variable1%E>. 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, 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 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%~tag_name ~%E> C%~ tag_name ~ %E> C% ~ tagname ~ %E> 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: 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: abcazdef Additionally, you may use the special tag C%~%E> 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%DUMP%E> tag is added, while the second and third examples will display a dump of the 'variable' and 'variable.key' values, respectively. C 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 - for documentation on invoking the template parser. L - for documentation on template inheritance. =head1 VERSION Revision: $Id: Tutorial.pod,v 2.11 2005/04/23 23:11:33 brewt Exp $ =cut