Commit | Line | Data |
3fea05b9 |
1 | #============================================================= -*-perl-*- |
2 | # |
3 | # Template::FAQ |
4 | # |
5 | # DESCRIPTION |
6 | |
7 | # |
8 | # AUTHOR |
9 | # Andy Wardley <abw@wardley.org> |
10 | # |
11 | # COPYRIGHT |
12 | # Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. |
13 | # |
14 | # This module is free software; you can redistribute it and/or |
15 | # modify it under the same terms as Perl itself. |
16 | #======================================================================== |
17 | |
18 | =head1 NAME |
19 | |
20 | Template::FAQ - Frequently Asked Questions about the Template Toolkit |
21 | |
22 | =head1 Template Toolkit Language |
23 | |
24 | =head2 Why doesn't [% a = b IF c %] work as expected? |
25 | |
26 | There's a limitation in the TT2 parser which means that the following code |
27 | doesn't work as you might expect: |
28 | |
29 | [% a = b IF c %] |
30 | |
31 | The parser interprets it as an attempt to set C<a> to the result of |
32 | C<b IF c>, like this: |
33 | |
34 | [% a = (b IF c) %] |
35 | |
36 | If you want to set C<a = b> only if C<c> is true, then do this instead: |
37 | |
38 | [% SET a = b IF c %] |
39 | |
40 | The explicit C<SET> keyword gives the parser the clue it needs to do the |
41 | right thing. |
42 | |
43 | NOTE: this will be fixed in TT3 |
44 | |
45 | =head2 If I'm using TT to write out a TT template, is there a good way to escape [% and %]? |
46 | |
47 | You can do something like this: |
48 | |
49 | [% stag = "[\%" |
50 | etag = "%\]" |
51 | %] |
52 | |
53 | and then: |
54 | |
55 | [% stag; 'hello'; etag %] |
56 | |
57 | Or you can use the C<TAGS> directive, like so: |
58 | |
59 | [% TAGS [- -] %] |
60 | [- INCLUDE foo -] # is a directive |
61 | [% INCLUDE foo %] # not a directive |
62 | |
63 | =head2 How do I iterate over a hash? |
64 | |
65 | This is covered in the L<Template::Manual::VMethods> section of the |
66 | manual. A list of all the keys that are in the hash can be obtained with the |
67 | C<keys> virtual method. You can then iterate over that list and by looking up |
68 | each key in turn get the value. |
69 | |
70 | [% FOREACH key = product.keys %] |
71 | [% key %] => [% product.$key %] |
72 | [% END %] |
73 | |
74 | =head1 Plugins |
75 | |
76 | =head2 How do I get the Table plugin to order data across rather than down? |
77 | |
78 | Order the data into rows: |
79 | |
80 | Steve Karen Jeff |
81 | Brooklyn Nantucket Fairfax |
82 | NY MA VA |
83 | |
84 | [% USE table(data, rows=3) %] |
85 | |
86 | Then ask for each column |
87 | |
88 | [% FOREACH column = table.cols %] |
89 | |
90 | And then print each item in the column going across the output rows |
91 | |
92 | [% FOREACH item = column %] |
93 | <td>[% item %]</td> |
94 | [% END %] |
95 | |
96 | =head2 Accessing Cookies |
97 | |
98 | Jeff Boes E<lt>jboes@nexcerpt.comE<gt> asks: |
99 | |
100 | Does anyone have a quick-n-dirty approach to accessing |
101 | cookies from templates? |
102 | |
103 | Jonas Liljegren answers: |
104 | |
105 | [% USE CGI %] |
106 | |
107 | <p>The value is [% CGI.cookie('cookie_name') | html %] |
108 | |
109 | |
110 | =head1 Extending the Template Toolkit |
111 | |
112 | =head2 Can I serve templates from a database? |
113 | |
114 | Short answer: yes, Chris Nandor has done this for Slash. You need to |
115 | subclass L<Template::Provider>. See the mailing list archives for further |
116 | info. |
117 | |
118 | =head2 Can I fetch templates via http? |
119 | |
120 | To do the job properly, you should subclass L<Template::Provider> to |
121 | C<Template::Provider::HTTP> and use a C<PREFIX_MAP> option to bind the C<http> |
122 | template prefix to that particular provider (you may want to go digging around |
123 | in the F<Changes> file around version 2.01 for more info on C<PREFIX_MAP> - it |
124 | may not be properly documented anywhere else...yet!). e.g. |
125 | |
126 | use Template::Provider::HTTP; |
127 | |
128 | my $file = Template::Provider( INCLUDE_PATH => [...] ); |
129 | my $http = Template::Provider::HTTP->new(...); |
130 | my $tt2 = Template->new({ |
131 | LOAD_TEMPLATES => [ $file, $http ], |
132 | PREFIX_MAP => { |
133 | file => '0', # file:foo.html |
134 | http => '1', # http:foo.html |
135 | default => '0', # foo.html => file:foo.html |
136 | } |
137 | }); |
138 | |
139 | Now a template specified as: |
140 | |
141 | [% INCLUDE foo %] |
142 | |
143 | will be served by the 'file' provider (the default). Otherwise you |
144 | can explicitly add a prefix: |
145 | |
146 | [% INCLUDE file:foo.html %] |
147 | [% INCLUDE http:foo.html %] |
148 | [% INCLUDE http://www.xyz.com/tt2/header.tt2 %] |
149 | |
150 | This same principal can be used to create a DBI template provider. e.g. |
151 | |
152 | [% INCLUDE dbi:foo.html %] |
153 | |
154 | Alas, we don't yet have a DBI provider as part of the Template Toolkit. There |
155 | has been some talk on the mailing list about efforts to develop DBI and/or |
156 | HTTP providers but as yet no-one has stepped forward to take up the |
157 | challenge... |
158 | |
159 | In the mean time, Craig Barrat's post from the mailing list has some useful |
160 | pointers on how to achieve this using existing modules. See |
161 | L<http://tt2.org/pipermail/templates/2001-May/000954.html> |
162 | |
163 | =head1 Miscellaneous |
164 | |
165 | =head2 How can I find out the name of the main template being processed? |
166 | |
167 | The C<template> variable contains a reference to the |
168 | Template::Document object for the main template you're processing |
169 | (i.e. the one provided as the first argument to the Template process() |
170 | method). The C<name> method returns its name. |
171 | |
172 | [% template.name %] # e.g. index.html |
173 | |
174 | =head2 How can I find out the name of the current template being processed? |
175 | |
176 | The C<template> variable always references the I<main> template being processed. |
177 | So even if you call [% INCLUDE header %], and that calls [% INCLUDE menu %], |
178 | the C<template> variable will be unchanged. |
179 | |
180 | index.html: |
181 | |
182 | [% template.name %] # index.html |
183 | [% INCLUDE header %] |
184 | |
185 | header: |
186 | |
187 | [% template.name %] # index.html |
188 | [% INCLUDE menu %] |
189 | |
190 | menu: |
191 | |
192 | [% template.name %] # index.html |
193 | |
194 | In constrast, the C<component> variable always references the I<current> |
195 | template being processed. |
196 | |
197 | index.html |
198 | |
199 | [% component.name %] # index.html |
200 | [% INCLUDE header %] |
201 | |
202 | header: |
203 | |
204 | [% component.name %] # header |
205 | [% INCLUDE menu %] |
206 | |
207 | menu: |
208 | |
209 | [% component.name %] # menu |
210 | |
211 | =head2 How do I print the modification time of the template or component? |
212 | |
213 | The C<template> and C<component> variables reference the main template |
214 | and the current template being processed (see previous questions). |
215 | The C<modtime> method returns the modification time of the |
216 | corresponding template file as a number of seconds since the Unix |
217 | epoch (00:00:00 GMT 1st January 1970). |
218 | |
219 | This number doesn't mean much to anyone (except perhaps serious Unix |
220 | geeks) so you'll probably want to use the Date plugin to format it for |
221 | human consumption. |
222 | |
223 | [% USE Date %] |
224 | [% template.name %] last modified [% Date.format(template.modtime) %] |
225 | |
226 | =head2 How can I configure variables on a per-request basis? |
227 | |
228 | One easy way to achieve this is to define a single C<PRE_PROCESS> template |
229 | which loads in other configuration files based on variables defined or other |
230 | conditions. |
231 | |
232 | For example, my setup usually looks something like this: |
233 | |
234 | PRE_PROCESS => 'config/main' |
235 | |
236 | config/main: |
237 | |
238 | [% DEFAULT style = 'text' |
239 | section = template.section or 'home'; |
240 | |
241 | PROCESS config/site |
242 | + config/urls |
243 | + config/macros |
244 | + "config/style/$style" |
245 | + "config/section/$section" |
246 | + ... |
247 | %] |
248 | |
249 | This allows me to set a single 'style' variable to control which config |
250 | file gets pre-processed to set my various style options (colours, img paths, |
251 | etc). For example: |
252 | |
253 | config/style/basic: |
254 | |
255 | [% style = { |
256 | name = style # save existing 'style' var as 'style.name' |
257 | |
258 | # define various other style variables.... |
259 | col = { |
260 | back => '#ffffff' |
261 | text => '#000000' |
262 | # ...etc... |
263 | } |
264 | |
265 | logo = { |
266 | # ...etc... |
267 | } |
268 | |
269 | # ...etc... |
270 | } |
271 | %] |
272 | |
273 | Each source template can declare which section it's in via a META |
274 | directive: |
275 | |
276 | [% META |
277 | title = 'General Information' |
278 | section = 'info' |
279 | %] |
280 | ... |
281 | |
282 | This controls which section configuration file gets loaded to set various |
283 | other variables for defining the section title, menu, etc. |
284 | |
285 | config/section/info: |
286 | |
287 | [% section = { |
288 | name = section # save 'section' var as 'section.name' |
289 | title = 'Information' |
290 | menu = [ ... ] |
291 | # ...etc... |
292 | } |
293 | %] |
294 | |
295 | This illustrates the basic principal but you can extend it to perform |
296 | pretty much any kind of per-document initialisation that you require. |
297 | |
298 | =head2 Why do I get rubbish for my utf-8 templates? |
299 | |
300 | First of all, make sure that your template files define a Byte Order |
301 | Mark L<http://en.wikipedia.org/wiki/Byte_Order_Mark> |
302 | |
303 | If you for some reason don't want to add BOM to your templates, you can |
304 | force Template to use a particular encoding (e.g. C<utf8>) for your |
305 | templates with the C<ENCODING> option. |
306 | |
307 | my $template = Template->new({ |
308 | ENCODING => 'utf8' |
309 | }); |
310 | |
311 | =head1 Questions About This FAQ |
312 | |
313 | =head2 Why is this FAQ so short? |
314 | |
315 | Because we don't have anyone maintaining it. |
316 | |
317 | =head2 Can I help? |
318 | |
319 | Yes please :-) |
320 | |
321 | =cut |
322 | |
323 | # Local Variables: |
324 | # mode: perl |
325 | # perl-indent-level: 4 |
326 | # indent-tabs-mode: nil |
327 | # End: |
328 | # |
329 | # vim: expandtab shiftwidth=4: |