1CGI::Application::PlugiUns:e:rTTC(o3n)tributed Perl DocuCmGeIn:t:aAtpipolnication::Plugin::TT(3)
2
3
4
6 CGI::Application::Plugin::TT - Add Template Toolkit support to
7 CGI::Application
8
10 use base qw(CGI::Application);
11 use CGI::Application::Plugin::TT;
12
13 sub myrunmode {
14 my $self = shift;
15
16 my %params = (
17 email => 'email@company.com',
18 menu => [
19 { title => 'Home', href => '/home.html' },
20 { title => 'Download', href => '/download.html' },
21 ],
22 session_obj => $self->session,
23 );
24
25 return $self->tt_process('template.tmpl', \%params);
26 }
27
29 CGI::Application::Plugin::TT adds support for the popular Template
30 Toolkit engine to your CGI::Application modules by providing several
31 helper methods that allow you to process template files from within
32 your runmodes.
33
34 It compliments the support for HTML::Template that is built into
35 CGI::Application through the load_tmpl method. It also provides a few
36 extra features than just the ability to load a template.
37
39 tt_process
40 This is a simple wrapper around the Template Toolkit process method.
41 It accepts zero, one or two parameters; an optional template filename,
42 and an optional hashref of template parameters (the template filename
43 is optional, and will be autogenerated by a call to
44 $self->tt_template_name if not provided). The return value will be a
45 scalar reference to the output of the template.
46
47 package My::App::Browser
48 sub myrunmode {
49 my $self = shift;
50
51 return $self->tt_process( 'Browser/myrunmode.tmpl', { foo => 'bar' } );
52 }
53
54 sub myrunmode2 {
55 my $self = shift;
56
57 return $self->tt_process( { foo => 'bar' } ); # will process template 'My/App/Browser/myrunmode2.tmpl'
58 }
59
60 tt_config
61 This method can be used to customize the functionality of the
62 CGI::Application::Plugin::TT module, and the Template Toolkit module
63 that it wraps. The recommended place to call "tt_config" is as a class
64 method in the global scope of your module (See SINGLETON SUPPORT for an
65 explanation of why this is a good idea). If this method is called
66 after a call to tt_process or tt_obj, then it will die with an error
67 message.
68
69 It is not a requirement to call this method, as the module will work
70 without any configuration. However, most will find it useful to set at
71 least a path to the location of the template files ( or you can set the
72 path later using the tt_include_path method).
73
74 our $TEMPLATE_OPTIONS = {
75 COMPILE_DIR => '/tmp/tt_cache',
76 DEFAULT => 'notfound.tmpl',
77 PRE_PROCESS => 'defaults.tmpl',
78 };
79 __PACKAGE__->tt_config( TEMPLATE_OPTIONS => $TEMPLATE_OPTIONS );
80
81 The following parameters are accepted:
82
83 TEMPLATE_OPTIONS
84 This allows you to customize how the Template object is created by
85 providing a list of options that will be passed to the Template
86 constructor. Please see the documentation for the Template module
87 for the exact syntax of the parameters, or see below for an
88 example.
89
90 TEMPLATE_NAME_GENERATOR
91 This allows you to provide your own method for auto-generating the
92 template filename. It requires a reference to a function that will
93 be passed the $self object as it's only parameter. This function
94 will be called everytime $self->tt_process is called without
95 providing the filename of the template to process. This can
96 standardize the way templates are organized and structured by
97 making the template filenames follow a predefined pattern.
98
99 The default template filename generator uses the current module
100 name, and the name of the calling function to generate a filename.
101 This means your templates are named by a combination of the module
102 name, and the runmode.
103
104 TEMPLATE_PRECOMPILE_DIR
105 This options allows you to specify a directory (or an array of
106 directories) to search when this module is loaded and then compile
107 all files found into memory. This provides a speed boost in
108 persistant environments (mod_perl, fast-cgi) and can improve memory
109 usage in environments that use shared memory (mod_perl).
110
111 TEMPLATE_PRECOMPILE_FILETEST
112 This option allows you to specify exactly which files will get
113 compiled when using the TEMPLATE_PRECOMPILE_DIR option. You can
114 provide it with one of 3 different variable types:
115
116 STRING
117 A filename extension that can specify what type of files will
118 be loaded (eg 'tmpl').
119
120 REGEXP
121 Filenames that match the regular expression will be precompiled
122 ( eg qr/\.(tt|tmpl|html)$/ ).
123
124 CODEREF
125 A code reference that will be called once for each filename and
126 directory found, and if it returns true, the template will be
127 precompiled (eg sub { my $file = shift; ... } ).
128
129 tt_obj
130 This method will return the underlying Template Toolkit object that is
131 used behind the scenes. It is usually not necesary to use this object
132 directly, as you can process templates and configure the Template
133 object through the tt_process and tt_config methods. Every call to
134 this method will return the same object during a single request.
135
136 It may be useful for debugging purposes.
137
138 tt_params
139 This method will accept a hash or hashref of parameters that will be
140 included in the processing of every call to tt_process. It is
141 important to note that the parameters defined using tt_params will be
142 passed to every template that is processed during a given request
143 cycle. Usually only one template is processed per request, but it is
144 entirely possible to call tt_process multiple times with different
145 templates. Everytime tt_process is called, the hashref of parameters
146 passed to tt_process will be merged with the parameters set using the
147 tt_params method. Parameters passed through tt_process will have
148 precidence in case of duplicate parameters.
149
150 This can be useful to add global values to your templates, for example
151 passing the user's name automatically if they are logged in.
152
153 sub cgiapp_prerun {
154 my $self = shift;
155
156 $self->tt_params(username => $ENV{REMOTE_USER}) if $ENV{REMOTE_USER};
157 }
158
159 tt_clear_params
160 This method will clear all the currently stored parameters that have
161 been set with tt_params.
162
163 tt_pre_process
164 This is an overridable method that works in the spirit of
165 cgiapp_prerun. The method will be called just before a template is
166 processed, and will be passed the template filename, and a hashref of
167 template parameters. It can be used to make last minute changes to the
168 template, or the parameters before the template is processed.
169
170 sub tt_pre_process {
171 my ($self, $file, $vars) = @_;
172 $vars->{user} = $ENV{REMOTE_USER};
173 return;
174 }
175
176 If you are using CGI::Application 4.0 or greater, you can also register
177 this as a callback.
178
179 __PACKAGE__->add_callback('tt_pre_process', sub {
180 my ($self, $file, $vars) = @_;
181 $vars->{user} = $ENV{REMOTE_USER};
182 return;
183 });
184
185 tt_post_process
186 This, like it's counterpart cgiapp_postrun, is called right after a
187 template has been processed. It will be passed a scalar reference to
188 the processed template.
189
190 sub tt_post_process {
191 my ($self, $htmlref) = shift;
192
193 require HTML::Clean;
194 my $h = HTML::Clean->new($htmlref);
195 $h->strip;
196 my $newref = $h->data;
197 $$htmlref = $$newref;
198 return;
199 }
200
201 If you are using CGI::Application 4.0 or greater, you can also register
202 this as a callback (See tt_pre_process for an example of how to use
203 it).
204
205 tt_template_name
206 This method will generate a template name for you based on two pieces
207 of information: the method name of the caller, and the package name of
208 the caller. It allows you to consistently name your templates based on
209 a directory hierarchy and naming scheme defined by the structure of the
210 code. This can simplify development and lead to more consistent,
211 readable code.
212
213 If you do not want the template to be named after the method that
214 called tt_template_name, you can pass in an integer, and the method
215 used to generate the template name will be that many levels above the
216 caller. It defaults to zero.
217
218 For example:
219
220 package My::App::Browser
221
222 sub dummy_call {
223 my $self = shift;
224 return $self->tt_template_name(1); # parent callers name
225 }
226
227 sub view {
228 my $self = shift;
229 my $template;
230
231 $template = $self->tt_template_name; # returns 'My/App/Browser/view.tmpl'
232 $template = $self->dummy_call; # also returns 'My/App/Browser/view.tmpl'
233 return $self->tt_process($template, { var1 => param1 });
234 }
235
236 To simplify things even more, tt_process automatically calls
237 $self->tt_template_name for you if you do not pass a template name, so
238 the above can be reduced to this:
239
240 package MyApp::Example
241
242 sub view {
243 my $self = shift;
244
245 return $self->tt_process({ var1 => param1 }); # process template 'MyApp/Example/view.tmpl'
246 }
247
248 Since the path is generated based on the name of the module, you could
249 place all of your templates in the same directory as your perl modules,
250 and then pass @INC as your INCLUDE_PATH parameter. Whether that is
251 actually a good idea is left up to the reader.
252
253 $self->tt_include_path(\@INC);
254
255 tt_include_path
256 This method will allow you to set the include path for the Template
257 Toolkit object after the object has already been created. Normally you
258 set the INCLUDE_PATH option when creating the Template Toolkit object,
259 but sometimes it can be useful to change this value after the object
260 has already been created. This method will allow you to do that
261 without needing to create an entirely new Template Toolkit object.
262 This can be especially handy when using the Singleton support mentioned
263 below, where a Template Toolkit object may persist across many request.
264 It is important to note that a call to tt_include_path will change the
265 INCLUDE_PATH for all subsequent calls to this object, until
266 tt_include_path is called again. So if you change the INCLUDE_PATH
267 based on the user that is connecting to your site, then make sure you
268 call tt_include_path on every request.
269
270 my $root = '/var/www/';
271 $self->tt_include_path( [$root.$ENV{SERVER_NAME}, $root.'default'] );
272
273 When called with no parameters tt_include_path returns an arrayref
274 containing the current INCLUDE_PATH.
275
277 By default, the TT plugin will automatically add a parameter 'c' to the
278 template that will return to your CGI::Application object $self. This
279 allows you to access any methods in your CGI::Application module that
280 you could normally call on $self from within your template. This
281 allows for some powerful actions in your templates. For example, your
282 templates will be able to access query parameters, or if you use the
283 CGI::Application::Plugin::Session module, you can access session
284 parameters.
285
286 Hello [% c.session.param('username') || 'Anonymous User' %]
287
288 <a href="[% c.query.self_url %]">Reload this page</a>
289
290 Another useful plugin that can use this feature is the
291 CGI::Application::Plugin::HTMLPrototype plugin, which gives easy access
292 to the very powerful prototype.js JavaScript library.
293
294 [% c.prototype.define_javascript_functions %]
295 <a href="#" onclick="javascript:[% c.prototype.visual_effect( 'Appear', 'extra_info' ) %] return false;">Extra Info</a>
296 <div style="display: none" id="extra_info">Here is some more extra info</div>
297
298 With this extra flexibility comes some responsibilty as well. It could
299 lead down a dangerous path if you start making alterations to your
300 object from within the template. For example you could call
301 c.header_add to add new outgoing headers, but that is something that
302 should be left in your code, not in your template. Try to limit
303 yourself to pulling in information into your templates (like the
304 session example above does).
305
307 In a CGI::Application module:
308
309 package My::App
310
311 use CGI::Application::Plugin::TT;
312 use base qw(CGI::Application);
313
314 # configure the template object once during the init stage
315 sub cgiapp_init {
316 my $self = shift;
317
318 # Configure the template
319 $self->tt_config(
320 TEMPLATE_OPTIONS => {
321 INCLUDE_PATH => '/path/to/template/files',
322 POST_CHOMP => 1,
323 FILTERS => {
324 'currency' => sub { sprintf('$ %0.2f', @_) },
325 },
326 },
327 );
328 }
329
330 sub cgiapp_prerun {
331 my $self = shift;
332
333 # Add the username to all templates if the user is logged in
334 $self->tt_params(username => $ENV{REMOTE_USER}) if $ENV{REMOTE_USER};
335 }
336
337 sub tt_pre_process {
338 my $self = shift;
339 my $template = shift;
340 my $params = shift;
341
342 # could add the username here instead if we want
343 $params->{username} = $ENV{REMOTE_USER}) if $ENV{REMOTE_USER};
344
345 return;
346 }
347
348 sub tt_post_process {
349 my $self = shift;
350 my $htmlref = shift;
351
352 # clean up the resulting HTML
353 require HTML::Clean;
354 my $h = HTML::Clean->new($htmlref);
355 $h->strip;
356 my $newref = $h->data;
357 $$htmlref = $$newref;
358 return;
359 }
360
361
362 sub my_runmode {
363 my $self = shift;
364
365 my %params = (
366 foo => 'bar',
367 );
368
369 # return the template output
370 return $self->tt_process('my_runmode.tmpl', \%params);
371 }
372
373 sub my_otherrunmode {
374 my $self = shift;
375
376 my %params = (
377 foo => 'bar',
378 );
379
380 # Since we don't provide the name of the template to tt_process, it
381 # will be auto-generated by a call to $self->tt_template_name,
382 # which will result in a filename of 'Example/my_otherrunmode.tmpl'.
383 return $self->tt_process(\%params);
384 }
385
387 Creating a Template Toolkit object can be an expensive operation if it
388 needs to be done for every request. This startup cost increases
389 dramatically as the number of templates you use increases. The reason
390 for this is that when TT loads and parses a template, it generates
391 actual perlcode to do the rendering of that template. This means that
392 the rendering of the template is extremely fast, but the initial
393 parsing of the templates can be inefficient. Even by using the
394 builting caching mechanism that TT provides only writes the generated
395 perl code to the filesystem. The next time a TT object is created, it
396 will need to load these templates from disk, and eval the sourcecode
397 that they contain.
398
399 So to improve the efficiency of Template Toolkit, we should keep the
400 object (and hence all the compiled templates) in memory across multiple
401 requests. This means you only get hit with the startup cost the first
402 time the TT object is created.
403
404 All you need to do to use this module as a singleton is to call
405 tt_config as a class method instead of as an object method. All the
406 same parameters can be used when calling tt_config as a class method.
407
408 When creating the singleton, the Template Toolkit object will be saved
409 in the namespace of the module that created it. The singleton will
410 also be inherited by any subclasses of this module. So in effect this
411 is not a traditional Singleton, since an instance of a Template Toolkit
412 object is only shared by a module and it's children. This allows you
413 to still have different configurations for different CGI::Application
414 modules if you require it. If you want all of your CGI::Application
415 applications to share the same Template Toolkit object, just create a
416 Base class that calls tt_config to configure the plugin, and have all
417 of your applications inherit from this Base class.
418
420 package My::App;
421
422 use base qw(CGI::Application);
423 use CGI::Application::Plugin::TT;
424 My::App->tt_config(
425 TEMPLATE_OPTIONS => {
426 POST_CHOMP => 1,
427 },
428 );
429
430 sub cgiapp_prerun {
431 my $self = shift;
432
433 # Set the INCLUDE_PATH (will change the INCLUDE_PATH for
434 # all subsequent requests as well, until tt_include_path is called
435 # again)
436 my $basedir = '/path/to/template/files/',
437 $self->tt_include_path( [$basedir.$ENV{SERVER_NAME}, $basedir.'default'] );
438 }
439
440 sub my_runmode {
441 my $self = shift;
442
443 # Will use the same TT object across multiple request
444 return $self->tt_process({ param1 => 'value1' });
445 }
446
447 package My::App::Subclass;
448
449 use base qw(My::App);
450
451 sub my_other_runmode {
452 my $self = shift;
453
454 # Uses the TT object from the parent class (My::App)
455 return $self->tt_process({ param2 => 'value2' });
456 }
457
459 Cees Hek <ceeshek@gmail.com>
460
462 Please report any bugs or feature requests to
463 "bug-cgi-application-plugin-tt@rt.cpan.org", or through the web
464 interface at <http://rt.cpan.org>. I will be notified, and then you'll
465 automatically be notified of progress on your bug as I make changes.
466
468 Patches, questions and feedback are welcome.
469
471 CGI::Application, Template, perl(1)
472
474 Copyright (C) 2005 Cees Hek, All Rights Reserved.
475
476 This library is free software; you can redistribute it and/or modify it
477 under the same terms as Perl itself.
478
479
480
481perl v5.32.0 2020-07-28 CGI::Application::Plugin::TT(3)