Fixed soem typos in tt view
[catagits/Catalyst-View-TT.git] / lib / Catalyst / View / TT.pm
CommitLineData
8077080c 1package Catalyst::View::TT;
2
3use strict;
7d8aa5ec 4use base qw/Catalyst::View/;
8077080c 5use Template;
6use Template::Timer;
7use NEXT;
8
be7c1afa 9our $VERSION = '0.17';
8077080c 10
11__PACKAGE__->mk_accessors('template');
8077080c 12
13=head1 NAME
14
15Catalyst::View::TT - Template View Class
16
17=head1 SYNOPSIS
18
8cd017a8 19# use the helper to create View
722fede4 20 myapp_create.pl view TT TT
8077080c 21
8cd017a8 22# configure in lib/MyApp.pm
23
8cd017a8 24 MyApp->config({
25 name => 'MyApp',
7d8aa5ec 26 root => MyApp->path_to('root');,
7d607671 27 'V::TT' => {
8cd017a8 28 # any TT configurations items go here
29 INCLUDE_PATH => [
93f25382 30 MyApp->path_to( 'root', 'src' ),
31 MyApp->path_to( 'root', 'lib' ),
8cd017a8 32 ],
33 PRE_PROCESS => 'config/main',
34 WRAPPER => 'site/wrapper',
be7c1afa 35 TEMPLATE_EXTENSION => '.tt',
8cd017a8 36
37 # two optional config items
38 CATALYST_VAR => 'Catalyst',
39 TIMER => 1,
40 },
41 });
42
43# render view from lib/MyApp.pm or lib/MyApp::C::SomeController.pm
44
45 sub message : Global {
94b3529a 46 my ( $self, $c ) = @_;
47 $c->stash->{template} = 'message.tt2';
48 $c->stash->{message} = 'Hello World!';
8cd017a8 49 $c->forward('MyApp::V::TT');
50 }
8077080c 51
8cd017a8 52# access variables from template
53
54 The message is: [% message %].
55
56 # example when CATALYST_VAR is set to 'Catalyst'
57 Context is [% Catalyst %]
58 The base is [% Catalyst.req.base %]
59 The name is [% Catalyst.config.name %]
60
61 # example when CATALYST_VAR isn't set
62 Context is [% c %]
63 The base is [% base %]
64 The name is [% name %]
65
66=head1 DESCRIPTION
67
68This is the Catalyst view class for the L<Template Toolkit|Template>.
69Your application should defined a view class which is a subclass of
70this module. The easiest way to achieve this is using the
71F<myapp_create.pl> script (where F<myapp> should be replaced with
72whatever your application is called). This script is created as part
73of the Catalyst setup.
74
75 $ script/myapp_create.pl view TT TT
76
77This creates a MyApp::V::TT.pm module in the F<lib> directory (again,
78replacing C<MyApp> with the name of your application) which looks
79something like this:
80
81 package FooBar::V::TT;
82
83 use strict;
84 use base 'Catalyst::View::TT';
8077080c 85
86 __PACKAGE__->config->{DEBUG} = 'all';
87
8cd017a8 88Now you can modify your action handlers in the main application and/or
89controllers to forward to your view class. You might choose to do this
90in the end() method, for example, to automatically forward all actions
91to the TT view class.
722fede4 92
8cd017a8 93 # In MyApp or MyApp::Controller::SomeController
8077080c 94
8cd017a8 95 sub end : Private {
94b3529a 96 my( $self, $c ) = @_;
8cd017a8 97 $c->forward('MyApp::V::TT');
98 }
8077080c 99
8cd017a8 100=head2 CONFIGURATION
4687ac0d 101
8cd017a8 102There are a three different ways to configure your view class. The
103first way is to call the C<config()> method in the view subclass. This
104happens when the module is first loaded.
8077080c 105
8cd017a8 106 package MyApp::V::TT;
107
108 use strict;
109 use base 'Catalyst::View::TT';
722fede4 110
8cd017a8 111 MyApp::V::TT->config({
7d8aa5ec 112 INCLUDE_PATH => [
113 MyApp->path_to( 'root', 'templates', 'lib' ),
114 MyApp->path_to( 'root', 'templates', 'src' ),
115 ],
8cd017a8 116 PRE_PROCESS => 'config/main',
117 WRAPPER => 'site/wrapper',
118 });
119
120The second way is to define a C<new()> method in your view subclass.
121This performs the configuration when the view object is created,
122shortly after being loaded. Remember to delegate to the base class
123C<new()> method (via C<$self-E<gt>NEXT::new()> in the example below) after
124performing any configuration.
125
126 sub new {
127 my $self = shift;
128 $self->config({
7d8aa5ec 129 INCLUDE_PATH => [
130 MyApp->path_to( 'root', 'templates', 'lib' ),
131 MyApp->path_to( 'root', 'templates', 'src' ),
132 ],
8cd017a8 133 PRE_PROCESS => 'config/main',
134 WRAPPER => 'site/wrapper',
135 });
136 return $self->NEXT::new(@_);
137 }
138
94b3529a 139The final, and perhaps most direct way, is to define a class
8cd017a8 140item in your main application configuration, again by calling the
94b3529a 141uniquitous C<config()> method. The items in the class hash are
8cd017a8 142added to those already defined by the above two methods. This happens
143in the base class new() method (which is one reason why you must
144remember to call it via C<NEXT> if you redefine the C<new()> method in a
145subclass).
146
147 package MyApp;
148
149 use strict;
150 use Catalyst;
151
8cd017a8 152 MyApp->config({
153 name => 'MyApp',
7d8aa5ec 154 root => MyApp->path_to('root'),
7d607671 155 'V::TT' => {
7d8aa5ec 156 INCLUDE_PATH => [
157 MyApp->path_to( 'root', 'templates', 'lib' ),
158 MyApp->path_to( 'root', 'templates', 'src' ),
159 ],
8cd017a8 160 PRE_PROCESS => 'config/main',
161 WRAPPER => 'site/wrapper',
162 },
163 });
164
165Note that any configuration items defined by one of the earlier
166methods will be overwritten by items of the same name provided by the
167latter methods.
168
169=head2 RENDERING VIEWS
170
171The view plugin renders the template specified in the C<template>
172item in the stash.
173
174 sub message : Global {
94b3529a 175 my ( $self, $c ) = @_;
176 $c->stash->{template} = 'message.tt2';
8cd017a8 177 $c->forward('MyApp::V::TT');
178 }
722fede4 179
94b3529a 180If a class item isn't defined, then it instead uses the
8cd017a8 181current match, as returned by C<$c-E<gt>match>. In the above
182example, this would be C<message>.
183
184The items defined in the stash are passed to the Template Toolkit for
185use as template variables.
186
187sub message : Global {
188 sub default : Private {
94b3529a 189 my ( $self, $c ) = @_;
190 $c->stash->{template} = 'message.tt2';
191 $c->stash->{message} = 'Hello World!';
8cd017a8 192 $c->forward('MyApp::V::TT');
193 }
7b592fc7 194
8cd017a8 195A number of other template variables are also added:
8077080c 196
8cd017a8 197 c A reference to the context object, $c
198 base The URL base, from $c->req->base()
199 name The application name, from $c->config->{ name }
200
201These can be accessed from the template in the usual way:
202
203<message.tt2>:
204
205 The message is: [% message %]
206 The base is [% base %]
207 The name is [% name %]
208
8cd017a8 209
210The output generated by the template is stored in
211C<$c-E<gt>response-E<gt>output>.
212
213=head2 TEMPLATE PROFILING
214
caa61517 215=head2 METHODS
8077080c 216
2774dc77 217=over 4
218
219=item new
220
221The constructor for the TT view. Sets up the template provider,
222and reads the application config.
223
8077080c 224=cut
225
226sub new {
9300af5b 227 my ( $class, $c, $arguments ) = @_;
228
229 my $root = $c->config->{root};
230
94b3529a 231 my $config = {
7d8aa5ec 232 EVAL_PERL => 0,
4729c102 233 TEMPLATE_EXTENSION => '',
7d8aa5ec 234 INCLUDE_PATH => [ $root, "$root/base" ],
9300af5b 235 %{ $class->config },
8cd017a8 236 %{$arguments}
94b3529a 237 };
62728755 238
8cd017a8 239 # if we're debugging and/or the TIMER option is set, then we install
240 # Template::Timer as a custom CONTEXT object, but only if we haven't
241 # already got a custom CONTEXT defined
242
dccfa0ff 243 if ( $config->{TIMER} ) {
94b3529a 244 if ( $config->{CONTEXT} ) {
8cd017a8 245 $c->log->error(
246 'Cannot use Template::Timer - a TT CONFIG is already defined');
247 }
248 else {
94b3529a 249 $config->{CONTEXT} = Template::Timer->new(%$config);
8cd017a8 250 }
251 }
252
94b3529a 253 if ( $c->debug && $config->{DUMP_CONFIG} ) {
8cd017a8 254 use Data::Dumper;
94b3529a 255 $c->log->debug( "TT Config: ", Dumper($config) );
62728755 256 }
257
8cd017a8 258 return $class->NEXT::new(
259 $c,
260 {
94b3529a 261 template => Template->new($config) || do {
8cd017a8 262 my $error = Template->error();
263 $c->log->error($error);
264 $c->error($error);
265 return undef;
266 }
be7c1afa 267 },
268 %{$config},
8cd017a8 269 );
8077080c 270}
271
2774dc77 272=item process
8077080c 273
722fede4 274Renders the template specified in C<$c-E<gt>stash-E<gt>{template}> or
275C<$c-E<gt>request-E<gt>match>. Template variables are set up from the
276contents of C<$c-E<gt>stash>, augmented with C<base> set to
277C<$c-E<gt>req-E<gt>base>, C<c> to C<$c> and C<name> to
8cd017a8 278C<$c-E<gt>config-E<gt>{name}>. Alternately, the C<CATALYST_VAR>
279configuration item can be defined to specify the name of a template
280variable through which the context reference (C<$c>) can be accessed.
281In this case, the C<c>, C<base> and C<name> variables are omitted.
282Output is stored in C<$c-E<gt>response-E<gt>output>.
8077080c 283
284=cut
285
286sub process {
287 my ( $self, $c ) = @_;
23042c3c 288
7d8aa5ec 289 my $template = $c->stash->{template}
290 || $c->request->match . $self->config->{TEMPLATE_EXTENSION};
23042c3c 291
292 unless ($template) {
8077080c 293 $c->log->debug('No template specified for rendering') if $c->debug;
294 return 0;
295 }
23042c3c 296
297 $c->log->debug(qq/Rendering template "$template"/) if $c->debug;
23042c3c 298
8cd017a8 299 my $output;
300 my $cvar = $self->config->{CATALYST_VAR};
301 my $vars = {
302 defined $cvar
303 ? ( $cvar => $c )
304 : (
305 c => $c,
306 base => $c->req->base,
307 name => $c->config->{name}
308 ),
309 %{ $c->stash() }
310 };
311
312 unless ( $self->template->process( $template, $vars, \$output ) ) {
8077080c 313 my $error = $self->template->error;
314 $error = qq/Couldn't render template "$error"/;
315 $c->log->error($error);
becb7ac2 316 $c->error($error);
23042c3c 317 return 0;
318 }
8cd017a8 319
23042c3c 320 unless ( $c->response->content_type ) {
321 $c->response->content_type('text/html; charset=utf-8');
8077080c 322 }
23042c3c 323
324 $c->response->body($output);
325
8077080c 326 return 1;
327}
328
2774dc77 329=item config
8077080c 330
8cd017a8 331This method allows your view subclass to pass additional settings to
4729c102 332the TT configuration hash, or to set the options as below:
333
334=over 2
335
336=item C<CATALYST_VAR>
337
338Allows you to change the name of the Catalyst context object. If set, it will also
339remove the base and name aliases, so you will have access them through <context>.
340
341For example:
342
343 MyApp->config({
344 name => 'MyApp',
7d8aa5ec 345 root => MyApp->path_to('root'),
4729c102 346 'V::TT' => {
347 CATALYST_VAR => 'Catalyst',
348 },
349 });
350
351F<message.tt2>:
352
353 The base is [% Catalyst.req.base %]
354 The name is [% Catalyst.config.name %]
355
356=item C<TIMER>
357
358If you have configured Catalyst for debug output, and turned on the TIMER setting,
359C<Catalyst::View::TT> will enable profiling of template processing
360(using L<Template::Timer>). This will embed HTML comments in the
361output from your templates, such as:
362
363 <!-- TIMER START: process mainmenu/mainmenu.ttml -->
364 <!-- TIMER START: include mainmenu/cssindex.tt -->
365 <!-- TIMER START: process mainmenu/cssindex.tt -->
366 <!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) -->
367 <!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) -->
368
369 ....
370
371 <!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
372
373
be7c1afa 374=item C<TEMPLATE_EXTENSION>
4729c102 375
747f2b6d 376a sufix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>.
4729c102 377
378For example:
379
380 package MyApp::C::Test;
381 sub test : Local { .. }
382
383Would by default look for a template in <root>/test/test. If you set TEMPLATE_EXTENSION to '.tt', it will look for
384<root>/test/test.tt.
385
386=back
8077080c 387
2774dc77 388=back
8077080c 389
8cd017a8 390=head2 HELPERS
391
392The L<Catalyst::Helper::View::TT> and
393L<Catalyst::Helper::View::TTSite> helper modules are provided to create
394your view module. There are invoked by the F<myapp_create.pl> script:
395
396 $ script/myapp_create.pl view TT TT
397
398 $ script/myapp_create.pl view TT TTSite
399
400The L<Catalyst::Helper::View::TT> module creates a basic TT view
401module. The L<Catalyst::Helper::View::TTSite> module goes a little
402further. It also creates a default set of templates to get you
403started. It also configures the view module to locate the templates
404automatically.
405
8077080c 406=head1 SEE ALSO
407
8cd017a8 408L<Catalyst>, L<Catalyst::Helper::View::TT>,
409L<Catalyst::Helper::View::TTSite>, L<Template::Manual>
8077080c 410
c0eb0527 411=head1 AUTHORS
8077080c 412
413Sebastian Riedel, C<sri@cpan.org>
c0eb0527 414
d938377b 415Marcus Ramberg, C<mramberg@cpan.org>
c0eb0527 416
722fede4 417Jesse Sheidlower, C<jester@panix.com>
c0eb0527 418
8cd017a8 419Andy Wardley, C<abw@cpan.org>
8077080c 420
421=head1 COPYRIGHT
422
2774dc77 423This program is free software, you can redistribute it and/or modify it
424under the same terms as Perl itself.
8077080c 425
426=cut
427
4281;