Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / i486-linux-gnu-thread-multi / Template / Manual / Views.pod
CommitLineData
3fea05b9 1#============================================================= -*-perl-*-
2#
3# Template::Manual::Views
4#
5# AUTHOR
6# Andy Wardley <abw@wardley.org>
7#
8# COPYRIGHT
9# Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
10#
11# This module is free software; you can redistribute it and/or
12# modify it under the same terms as Perl itself.
13#
14#========================================================================
15
16=head1 NAME
17
18Template::Manual::Views - Template Toolkit views (experimental)
19
20=head1 Overview
21
22A view is effectively a collection of templates and/or variable
23definitions which can be passed around as a self-contained unit. This
24then represents a particular interface or presentation style for other
25objects or items of data.
26
27You can use views to implement custom "skins" for an application or
28content set. You can use them to help simplify the presentation of
29common objects or data types. You can even use then to automate the
30presentation of complex data structures such as that generated in an
31C<XML::DOM> tree or similar. You let an iterator do the walking, and the
32view does the talking (or in this case, the presenting). Voila - you
33have view independant, structure shy traversal using templates.
34
35In general, views can be used in a number of different ways to achieve
36several different things. They elegantly solve some problems which
37were otherwise difficult or complicated, and make easy some things
38that were previously hard.
39
40At the moment, they're still very experimental. The directive syntax
41and underlying API are likely to change quite considerably over the
42next version or two. Please be very wary about building your
43multi-million dollar e-commerce solutions based around this feature.
44
45=head1 Views as Template Collectors/Providers
46
47The C<VIEW> directive starts a view definition and includes a name by
48which the view can be referenced. The view definition continues up to
49the matching C<END> directive.
50
51 [% VIEW myview %]
52 ...
53 [% END %]
54
55The first role of a view is to act as a collector and provider of templates.
56The C<include()> method can be called on a view to effectively do the same
57thing as the C<INCLUDE> directive. The template name is passed as the first
58argument, followed by any local variable definitions for the template.
59
60 [% myview.include('header', title='The Title') %]
61
62 # equivalent to
63 [% INCLUDE header title='The Title' %]
64
65Views accept a number of configuration options which can be used to control
66different aspects of their behaviour. The 'C<prefix>' and 'C<suffix>' options
67can be specified to add a fixed prefix and/or suffix to the name of each template.
68
69 [% VIEW myview
70 prefix = 'my/'
71 suffix = '.tt2' ;
72 END
73 %]
74
75Now the call
76
77 [% myview.include('header', title='The Title') %]
78
79is equivalent to
80
81 [% INCLUDE my/header.tt2 title='The Title' %]
82
83Views provide an C<AUTOLOAD> method which maps method names to the
84C<include()> method. Thus, the following are all equivalent:
85
86 [% myview.include('header', title='Hello World') %]
87 [% myview.include_header(title='Hello World') %]
88 [% myview.header(title='Hello World') %]
89
90=head1 Local BLOCK Definitions
91
92A C<VIEW> definition can include C<BLOCK> definitions which remain local to
93the view. A request for a particular template will return a C<BLOCK>,
94if defined, in preference to any other template of the same name.
95
96 [% BLOCK foo %]
97 public foo block
98 [% END %]
99
100 [% VIEW plain %]
101 [% BLOCK foo %]
102 plain foo block
103 [% END %]
104 [% END %]
105
106 [% VIEW fancy %]
107 [% BLOCK foo %]
108 fancy foo block
109 [% END %]
110 [% END %]
111
112 [% INCLUDE foo %] # public foo block
113 [% plain.foo %] # plain foo block
114 [% fancy.foo %] # fancy foo block
115
116In addition to C<BLOCK> definitions, a C<VIEW> can contain any other
117template directives. The entire C<VIEW> definition block is processed to
118initialise the view but no output is generated (this may change RSN -
119and get stored as 'C<output>' item, subsequently accessible as C<[%
120view.output %]>). However, directives that have side-effects, such as
121those that update a variable, will have noticable consequences.
122
123=head1 Preserving Variable State within Views
124
125Views can also be used to save the values of any existing variables,
126or to create new ones at the point at which the view is defined.
127Unlike simple template metadata (C<META>) which can only contain static
128string values, the view initialisation block can contain any template
129directives and generate any kind of dynamic output and/or data items.
130
131 [% VIEW my_web_site %]
132 [% view.title = title or 'My Cool Web Site' %]
133 [% view.author = "$abw.name, $abw.email" %]
134 [% view.sidebar = INCLUDE my/sidebar.tt2 %]
135 [% END %]
136
137Note that additional data items can be specified as arguments to the C<VIEW>
138directive. Anything that doesn't look like a configuration parameter is
139assumed to be a data item. This can be a little hazardous, of course, because
140you never know when a new configuration item might get added which interferes
141with your data.
142
143 [% VIEW my_web_site
144 # config options
145 prefix = 'my/'
146 # misc data
147 title = title or 'My Cool Web Site'
148 author = "$abw.name, $abw.email"
149 sidebar = INCLUDE my/sidebar.tt2
150 %]
151 ...
152 [% END %]
153
154Outside of the view definition you can access the view variables as, for
155example:
156
157 [% my_web_site.title %]
158
159One important feature is the equivalence of simple variables and templates.
160You can implement the view item 'C<title>' as a simple variable, a template
161defined in an external file, possibly with a prefix/suffix automatically
162appended, or as a local C<BLOCK> definition within the C<[% VIEW %] ... [% END %]>
163definition. If you use the syntax above then the view will Do The Right
164Thing to return the appropriate output.
165
166At the C<END> of the C<VIEW> definition the view is "sealed" to prevent you
167from accidentally updating any variable values. If you attempt to change
168the value of a variable after the C<END> of the C<VIEW> definition block then
169a C<view> error will be thrown.
170
171 [% TRY;
172 my_web_site.title = 'New Title';
173 CATCH;
174 error;
175 END
176 %]
177
178The error above will be reported as:
179
180 view error - cannot update item in sealed view: title
181
182The same is true if you pass a parameter to a view variable. This is
183interpreted as an attempt to update the variable and will raise the same
184warning.
185
186 [% my_web_site.title('New Title') %] # view error!
187
188You can set the C<silent> parameter to have the view ignore these
189parameters and simply return the variable value.
190
191 [% VIEW my_web_site
192 silent = 1
193 title = title or 'My Cool Web Site'
194 # ... ;
195 END
196 %]
197
198 [% my_web_site.title('Blah Blah') %] # My Cool Web Site
199
200Alternately, you can specify that a view is unsealed allowing existing
201variables to be updated and new variables defined.
202
203 [% VIEW my_web_site
204 sealed = 0
205 title = title or 'My Cool Web Site'
206 # ... ;
207 END
208 %]
209
210 [% my_web_site.title('Blah Blah') %] # Blah Blah
211 [% my_web_site.title %] # Blah Blah
212
213=head2 Inheritance, Delegation and Reuse
214
215Views can be inherited from previously defined views by use of the C<base>
216parameter. This example shows how a base class view is defined which
217applies a C<view/default/> prefix to all template names.
218
219 [% VIEW my.view.default
220 prefix = 'view/default/';
221 END
222 %]
223
224Thus the directive:
225
226 [% my.view.default.header(title='Hello World') %]
227
228is now equivalent to:
229
230 [% INCLUDE view/default/header title='Hello World' %]
231
232A second view can be defined which specifies the default view as a
233base.
234
235 [% VIEW my.view.fancy
236 base = my.view.default
237 prefix = 'view/fancy/';
238 END
239 %]
240
241Now the directive:
242
243 [% my.view.fancy.header(title='Hello World') %]
244
245will resolve to:
246
247 [% INCLUDE view/fancy/header title='Hello World' %]
248
249or if that doesn't exist, it will be handled by the base view as:
250
251 [% INCLUDE view/default/header title='Hello World' %]
252
253When a parent view is specified via the C<base> parameter, the
254delegation of a view to its parent for fetching templates and accessing
255user defined variables is automatic. You can also implement your own
256inheritance, delegation or other reuse patterns by explicitly
257delegating to other views.
258
259 [% BLOCK foo %]
260 public foo block
261 [% END %]
262
263 [% VIEW plain %]
264 [% BLOCK foo %]
265 <plain>[% PROCESS foo %]</plain>
266 [% END %]
267 [% END %]
268
269 [% VIEW fancy %]
270 [% BLOCK foo %]
271 [% plain.foo | replace('plain', 'fancy') %]
272 [% END %]
273 [% END %]
274
275 [% plain.foo %] # <plain>public foo block</plain>
276 [% fancy.foo %] # <fancy>public foo block</fancy>
277
278Note that the regular C<INCLUDE/PROCESS/WRAPPER> directives work entirely
279independantly of views and will always get the original, unaltered
280template name rather than any local per-view definition.
281
282=head2 Self-Reference
283
284A reference to the view object under definition is available with the
285C<VIEW ... END> block by its specified name and also by the special name
286'C<view>' (similar to the C<my $self = shift;> in a Perl method or the
287'C<this>' pointer in C++, etc). The view is initially unsealed allowing
288any data items to be defined and updated within the C<VIEW ... END>
289block. The view is automatically sealed at the end of the definition
290block, preventing any view data from being subsequently changed.
291
292(NOTE: sealing should be optional. As well as sealing a view to prevent
293updates (C<SEALED>), it should be possible to set an option in the view to
294allow external contexts to update existing variables (C<UPDATE>) or even
295create totally new view variables (C<CREATE>)).
296
297 [% VIEW fancy %]
298 [% fancy.title = 'My Fancy Title' %]
299 [% fancy.author = 'Frank Open' %]
300 [% fancy.col = { bg => '#ffffff', bar => '#a0a0ff' } %]
301 [% END %]
302
303or
304
305 [% VIEW fancy %]
306 [% view.title = 'My Fancy Title' %]
307 [% view.author = 'Frank Open' %]
308 [% view.col = { bg => '#ffffff', bar => '#a0a0ff' } %]
309 [% END %]
310
311It makes no real difference in this case if you refer to the view by
312its name, 'C<fancy>', or by the general name, 'C<view>'. Outside of the
313view block, however, you should always use the given name, 'C<fancy>':
314
315 [% fancy.title %]
316 [% fancy.author %]
317 [% fancy.col.bg %]
318
319The choice of given name or 'C<view>' is much more important when it
320comes to C<BLOCK> definitions within a C<VIEW>. It is generally recommended
321that you use 'C<view>' inside a C<VIEW> definition because this is guaranteed
322to be correctly defined at any point in the future when the block gets
323called. The original name of the view might have long since been changed
324or reused but the self-reference via 'C<view>' should always be intact and
325valid.
326
327Take the following VIEW as an example:
328
329 [% VIEW foo %]
330 [% view.title = 'Hello World' %]
331 [% BLOCK header %]
332 Title: [% view.title %]
333 [% END %]
334 [% END %]
335
336Even if we rename the view, or create a new C<foo> variable, the header
337block still correctly accesses the C<title> attribute of the view to
338which it belongs. Whenever a view C<BLOCK> is processed, the C<view>
339variable is always updated to contain the correct reference to the
340view object to which it belongs.
341
342 [% bar = foo %]
343 [% foo = { title => "New Foo" } %] # no problem
344 [% bar.header %] # => Title: Hello World
345
346=head2 Saving References to External Views
347
348When it comes to view inheritance, it's always a good idea to take a
349local copy of a parent or delegate view and store it as an attribute
350within the view for later use. This ensures that the correct view
351reference is always available, even if the external name of a view
352has been changed.
353
354 [% VIEW plain %]
355 ...
356 [% END %]
357
358 [% VIEW fancy %]
359 [% view.plain = plain %]
360 [% BLOCK foo %]
361 [% view.plain.foo | replace('plain', 'fancy') %]
362 [% END %]
363 [% END %]
364
365 [% plain.foo %] # => <plain>public foo block</plain>
366 [% plain = 'blah' %] # no problem
367 [% fancy.foo %] # => <fancy>public foo block</fancy>
368
369=head2 Views as Data Presenters
370
371Another key role of a view is to act as a dispatcher to automatically
372apply the correct template to present a particular object or data
373item. This is handled via the C<print()> method.
374
375Here's an example:
376
377 [% VIEW foo %]
378
379 [% BLOCK text %]
380 Some text: [% item %]
381 [% END %]
382
383 [% BLOCK hash %]
384 a hash:
385 [% FOREACH key = item.keys.sort -%]
386 [% key %] => [% item.$key %]
387 [% END -%]
388 [% END %]
389
390 [% BLOCK list %]
391 a list: [% item.sort.join(', ') %]
392 [% END %]
393
394 [% END %]
395
396We can now use the view to print text, hashes or lists. The C<print()>
397method includes the right template depending on the typing of the
398argument (or arguments) passed.
399
400 [% some_text = 'I read the news today, oh boy.' %]
401 [% a_hash = { house => 'Lords', hall => 'Albert' } %]
402 [% a_list = [ 'sure', 'Nobody', 'really' ] %]
403
404 [% view.print(some_text) %]
405 # Some text: I read the news today, oh boy.
406
407 [% view.print(a_hash) %]
408 # a hash:
409 hall => Albert
410 house => Lords
411 [% view.print(a_list) %]
412 # a list: Nobody, really, sure
413
414You can also provide templates to print objects of any other class.
415The class name is mapped to a template name with all non-word
416character sequences such as 'C<::>' converted to a single 'C<_>'.
417
418 [% VIEW foo %]
419 [% BLOCK Foo_Bar %]
420 a Foo::Bar object:
421 thingies: [% view.print(item.thingies) %]
422 doodahs: [% view.print(item.doodahs) %]
423 [% END %]
424 [% END %]
425
426 [% USE fubar = Foo::Bar(...) %]
427
428 [% foo.print(fubar) %]
429
430Note how we use the view object to display various items within the
431objects ('C<thingies>' and 'C<doodahs>'). We don't need to worry what
432kind of data these represent (text, list, hash, etc) because we can
433let the view worry about it, automatically mapping the data type to
434the correct template.
435
436Views may define their own type =E<gt> template map.
437
438 [% VIEW foo
439 map = { TEXT => 'plain_text',
440 ARRAY => 'show_list',
441 HASH => 'show_hash',
442 My::Module => 'template_name'
443 default => 'any_old_data'
444 }
445 %]
446 [% BLOCK plain_text %]
447 ...
448 [% END %]
449
450 ...
451 [% END %]
452
453They can also provide a C<default> map entry, specified as part of the C<map>
454hash or as a parameter by itself.
455
456 [% VIEW foo
457 map = { ... },
458 default = 'whatever'
459 %]
460 ...
461 [% END %]
462
463or
464
465 [% VIEW foo %]
466 [% view.map = { ... }
467 view.default = 'whatever'
468 %]
469 ...
470 [% END %]
471
472The C<print()> method provides one more piece of magic. If you pass it a
473reference to an object which provides a C<present()> method, then the method
474will be called passing the view as an argument. This then gives any object a
475chance to determine how it should be presented via the view.
476
477 package Foo::Bar;
478 ...
479 sub present {
480 my ($self, $view) = @_;
481 return "a Foo::Bar object:\n"
482 . "thingies: " . $view->print($self->{ _THINGIES }) . "\n"
483 . "doodahs: " . $view->print($self->{ _DOODAHS }) . "\n";
484 }
485
486The object is free to delve deeply into its innards and mess around with
487its own private data, before presenting the relevant data via the view.
488In a more complex example, a C<present()> method might walk part of a tree
489making calls back against the view to present different nodes within the
490tree. We may not want to expose the internal structure of the tree
491(because that would break encapsulation and make our presentation code
492dependant on it) but we want to have some way of walking the tree and
493presenting items found in a particular manner.
494
495This is known as I<Structure Shy Traversal>. Our view object doesn't require
496prior knowledge about the internal structure of any data set to be able
497to traverse it and present the data contained therein. The data items
498themselves, via the C<present()> method, can implement the internal iterators
499to guide the view along the right path to presentation happiness.
500
501The upshot is that you can use views to greatly simplify the display
502of data structures like C<XML::DOM> trees. The documentation for the
503C<Template::Plugin::XML::DOM> module contains an example of this. In
504essence, it looks something like this:
505
506XML source:
507
508 <user name="Andy Wardley">
509 <project id="iCan" title="iCan, but theyCan't"/>
510 <project id="p45" title="iDid, but theyDidn't"/>
511 </user>
512
513TT View:
514
515 [% VIEW fancy %]
516 [% BLOCK user %]
517 User: [% item.name %]
518 [% item.content(myview) %]
519 [% END %]
520
521 [% BLOCK project %]
522 Project: [% project.id %] - [% project.name %]
523 [% END %]
524 [% END %]
525
526Generate view:
527
528 [% USE dom = XML.DOM %]
529 [% fancy.print(dom.parse(xml_source)) %]
530
531Output:
532
533 User: Andy Wardley
534 Project: iCan - iCan, but theyCan't
535 Project: p45 - iDid, but theyDidn't
536
537The same approach can be applied to many other areas. Here's an example from
538the C<File>/C<Directory> plugins.
539
540 [% VIEW myview %]
541 [% BLOCK file %]
542 - [% item.name %]
543 [% END %]
544
545 [% BLOCK directory %]
546 * [% item.name %]
547 [% item.content(myview) FILTER indent %]
548 [% END %]
549 [% END %]
550
551 [% USE dir = Directory(dirpath) %]
552 [% myview.print(dir) %]
553
554And here's the same approach use to convert POD documentation to any
555other format via template.
556
557 [% # load Pod plugin and parse source file into Pod Object Model
558 USE Pod;
559 pom = Pod.parse_file(my_pod_file);
560
561 # define view to map all Pod elements to "pod/html/xxx" templates
562 VIEW pod2html
563 prefix='pod/html';
564 END;
565
566 # now print document via view (i.e. as HTML)
567 pod2html.print(pom)
568 %]
569
570Here we simply define a template prefix for the view which causes the
571view to look for C<pod/html/head1>, C<pod/html/head2>, C<pod/html/over>
572as templates to present the different sections of the parsed Pod document.
573
574There are some examples in the Template Toolkit test suite: F<t/pod.t> and
575F<t/view.t> which may shed some more light on this. See the distribution
576sub-directory F<examples/pod/html> for examples of Pod -E<gt> HTML templates.
577
578=cut
579
580# Local Variables:
581# mode: perl
582# perl-indent-level: 4
583# indent-tabs-mode: nil
584# End:
585#
586# vim: expandtab shiftwidth=4: