File Coverage

blib/lib/Catalyst/View/TT.pm
Criterion Covered Total %
statement 131 148 88.5
branch 44 68 64.7
condition 12 22 54.5
subroutine 16 16 100.0
pod 4 4 100.0
total 207 258 80.2


line stmt bran cond sub pod time code
1              
2             use strict;
3 12     12   16021481 use warnings;
  12         48  
  12         318  
4 12     12   98  
  12         27  
  12         370  
5             use base qw/Catalyst::View/;
6 12     12   66 use Data::Dump 'dump';
  12         27  
  12         5040  
7 12     12   1325719 use Template;
  12         13879  
  12         835  
8 12     12   7410 use Template::Timer;
  12         204957  
  12         407  
9 12     12   4766 use MRO::Compat;
  12         67898  
  12         304  
10 12     12   88 use Scalar::Util qw/blessed weaken/;
  12         25  
  12         275  
11 12     12   69  
  12         25  
  12         16042  
12             our $VERSION = '0.46';
13             $VERSION =~ tr/_//d;
14              
15             __PACKAGE__->mk_accessors('template');
16             __PACKAGE__->mk_accessors('expose_methods');
17             __PACKAGE__->mk_accessors('include_path');
18             __PACKAGE__->mk_accessors('content_type');
19              
20             *paths = \&include_path;
21              
22             =head1 NAME
23              
24             Catalyst::View::TT - Template View Class
25              
26             =head1 SYNOPSIS
27              
28             # use the helper to create your View
29              
30             myapp_create.pl view Web TT
31              
32             # add custom configuration in View/Web.pm
33              
34             __PACKAGE__->config(
35             # any TT configuration items go here
36             TEMPLATE_EXTENSION => '.tt',
37             CATALYST_VAR => 'c',
38             TIMER => 0,
39             ENCODING => 'utf-8'
40             # Not set by default
41             PRE_PROCESS => 'config/main',
42             WRAPPER => 'site/wrapper',
43             render_die => 1, # Default for new apps, see render method docs
44             expose_methods => [qw/method_in_view_class/],
45             );
46              
47             # add include path configuration in MyApp.pm
48              
49             __PACKAGE__->config(
50             'View::Web' => {
51             INCLUDE_PATH => [
52             __PACKAGE__->path_to( 'root', 'src' ),
53             __PACKAGE__->path_to( 'root', 'lib' ),
54             ],
55             },
56             );
57              
58             # render view from lib/MyApp.pm or lib/MyApp::Controller::SomeController.pm
59              
60             sub message : Global {
61             my ( $self, $c ) = @_;
62             $c->stash->{template} = 'message.tt2';
63             $c->stash->{message} = 'Hello World!';
64             $c->forward( $c->view('Web') );
65             }
66              
67             # access variables from template
68              
69             The message is: [% message %].
70              
71             # example when CATALYST_VAR is set to 'Catalyst'
72             Context is [% Catalyst %]
73             The base is [% Catalyst.req.base %]
74             The name is [% Catalyst.config.name %]
75              
76             # example when CATALYST_VAR isn't set
77             Context is [% c %]
78             The base is [% base %]
79             The name is [% name %]
80              
81             =cut
82              
83             my ( $paths, $dlim ) = shift;
84             return () if ( !$paths );
85 92     92   235 return @{$paths} if ( ref $paths eq 'ARRAY' );
86 92 100       294  
87 21 50       118 # tweak delim to ignore C:/
  0         0  
88             unless ( defined $dlim ) {
89             $dlim = ( $^O eq 'MSWin32' ) ? ':(?!\\/)' : ':';
90 21 50       59 }
91 21 50       99 return split( /$dlim/, $paths );
92             }
93 21         220  
94             my ( $class, $c, $arguments ) = @_;
95             my $config = {
96             EVAL_PERL => 0,
97 112     112 1 1964327 TEMPLATE_EXTENSION => '',
98             CLASS => 'Template',
99             %{ $class->config },
100             %{$arguments},
101             };
102 112         341 if ( ! (ref $config->{INCLUDE_PATH} eq 'ARRAY') ) {
103 112         241 my $delim = $config->{DELIMITER};
  112         36592  
104             my @include_path
105 112 100       407 = _coerce_paths( $config->{INCLUDE_PATH}, $delim );
106 92         282 if ( !@include_path ) {
107             my $root = $c->config->{root};
108 92         288 my $base = Path::Class::dir( $root, 'base' );
109 92 100       541 @include_path = ( "$root", "$base" );
110 71         248 }
111 71         5080 $config->{INCLUDE_PATH} = \@include_path;
112 71         4148 }
113              
114 92         2722 # if we're debugging and/or the TIMER option is set, then we install
115             # Template::Timer as a custom CONTEXT object, but only if we haven't
116             # already got a custom CONTEXT defined
117              
118             if ( $config->{TIMER} ) {
119             if ( $config->{CONTEXT} ) {
120             $c->log->error(
121 112 50       331 'Cannot use Template::Timer - a TT CONTEXT is already defined'
122 0 0       0 );
123 0         0 }
124             else {
125             $config->{CONTEXT} = Template::Timer->new(%$config);
126             }
127             }
128 0         0  
129             if ( $c->debug && $config->{DUMP_CONFIG} ) {
130             $c->log->debug( "TT Config: ", dump($config) );
131             }
132 112 0 33     404  
133 0         0 my $self = $class->next::method(
134             $c, { %$config },
135             );
136 112         1056  
137             # Set base include paths. Local'd in render if needed
138             $self->include_path($config->{INCLUDE_PATH});
139              
140             $self->expose_methods($config->{expose_methods});
141 112         170140 $self->config($config);
142              
143 112         36299 # Creation of template outside of call to new so that we can pass [ $self ]
144 112         29506 # as INCLUDE_PATH config item, which then gets ->paths() called to get list
145             # of include paths to search for templates.
146              
147             # Use a weakened copy of self so we don't have loops preventing GC from working
148             my $copy = $self;
149             Scalar::Util::weaken($copy);
150             $config->{INCLUDE_PATH} = [ sub { $copy->paths } ];
151 112         13300  
152 112         363 if ( $config->{PROVIDERS} ) {
153 112     19   582 my @providers = ();
  19         4607  
154             if ( ref($config->{PROVIDERS}) eq 'ARRAY') {
155 112 100       344 foreach my $p (@{$config->{PROVIDERS}}) {
156 10         37 my $pname = $p->{name};
157 10 50       53 my $prov = 'Template::Provider';
158 10         20 if($pname eq '_file_')
  10         64  
159 10         29 {
160 10         43 $p->{args} = { %$config };
161 10 50       46 }
162             else
163 0         0 {
164             if($pname =~ s/^\+//) {
165             $prov = $pname;
166             }
167 10 50       68 else
168 10         26 {
169             $prov .= "::$pname";
170             }
171             # We copy the args people want from the config
172 0         0 # to the args
173             $p->{args} ||= {};
174             if ($p->{copy_config}) {
175             map { $p->{args}->{$_} = $config->{$_} }
176 10   50     39 grep { exists $config->{$_} }
177 10 50       46 @{ $p->{copy_config} };
178 0         0 }
179 0         0 }
180 0         0 local $@;
  0         0  
181             eval "require $prov";
182             if(!$@) {
183 10         25 push @providers, "$prov"->new($p->{args});
184 10         770 }
185 10 50       2600 else
186 10         126 {
187             $c->log->warn("Can't load $prov, ($@)");
188             }
189             }
190 0         0 }
191             delete $config->{PROVIDERS};
192             if(@providers) {
193             $config->{LOAD_TEMPLATES} = \@providers;
194 10         803 }
195 10 50       42 }
196 10         29  
197             $self->{template} =
198             $config->{CLASS}->new($config) || do {
199             my $error = $config->{CLASS}->error();
200             $c->log->error($error);
201 112   33     652 $c->error($error);
202             return undef;
203             };
204              
205              
206             return $self;
207             }
208              
209 112         216122 my ( $self, $c ) = @_;
210              
211             my $template = $c->stash->{template}
212             || $c->action . $self->config->{TEMPLATE_EXTENSION};
213 20     20 1 1023103  
214             unless (defined $template) {
215             $c->log->debug('No template specified for rendering') if $c->debug;
216 20   66     76 return 0;
217             }
218 20 50       1990  
219 0 0       0 local $@;
220 0         0 my $output = eval { $self->render($c, $template) };
221             if (my $err = $@) {
222             return $self->_rendering_error($c, $template . ': ' . $err);
223 20         40 }
224 20         42 if (blessed($output) && $output->isa('Template::Exception')) {
  20         142  
225 20 50       311 $self->_rendering_error($c, $output);
226 0         0 }
227              
228 20 100 66     137 unless ( $c->response->content_type ) {
229 2         12 my $default = $self->content_type || 'text/html; charset=UTF-8';
230             $c->response->content_type($default);
231             }
232 20 50       530  
233 20   100     4766 $c->response->body($output);
234 20         2800  
235             return 1;
236             }
237 20         3603  
238             my ($self, $c, $err) = @_;
239 20         631 my $error = qq/Couldn't render template "$err"/;
240             $c->log->error($error);
241             $c->error($error);
242             return 0;
243 2     2   5 }
244 2         8  
245 2         84 my ($self, $c, $template, $args) = @_;
246 2         67  
247 2         26 $c->log->debug(qq/Rendering template "$template"/) if $c && $c->debug;
248              
249             my $output;
250             my $vars = {
251 24     24 1 135470 (ref $args eq 'HASH' ? %$args : %{ $c->stash() }),
252             $self->template_vars($c)
253 24 50 66     154 };
254              
255 24         131 local $self->{include_path} =
256             [ @{ $vars->{additional_template_paths} }, @{ $self->{include_path} } ]
257 24 100       98 if ref $vars->{additional_template_paths};
  21         54  
258              
259             unless ( $self->template->process( $template, $vars, \$output ) ) {
260             if (exists $self->{render_die}) {
261             die $self->template->error if $self->{render_die};
262 2         6 return $self->template->error;
  2         11  
263 24 100       100 }
264             $c->log->debug('The Catalyst::View::TT render() method will start dying on error in a future release. Unless you are calling the render() method manually, you probably want the new behaviour, so set render_die => 1 in config for ' . blessed($self) . '. If you wish to continue to return the exception rather than throwing it, add render_die => 0 to your config.') if $c && $c->debug;
265 24 100       136 return $self->template->error;
266 3 100       1337 }
267 1 50       6 return $output;
268 0         0 }
269              
270 2 50 33     13 my ( $self, $c ) = @_;
271 2         18  
272             return () unless $c;
273 21         241446 my $cvar = $self->config->{CATALYST_VAR};
274              
275             my %vars = defined $cvar
276             ? ( $cvar => $c )
277 24     24 1 1302 : (
278             c => $c,
279 24 100       79 base => $c->req->base,
280 23         79 name => $c->config->{name}
281             );
282              
283             if ($self->expose_methods) {
284             my $meta = $self->meta;
285             foreach my $method_name (@{$self->expose_methods}) {
286             my $method = $meta->find_method_by_name( $method_name );
287             unless ($method) {
288 23 50       1559 Catalyst::Exception->throw( "$method_name not found in TT view" );
289             }
290 23 100       2856 my $method_body = $method->body;
291 4         522 my $weak_ctx = $c;
292 4         66 weaken $weak_ctx;
  4         11  
293 8         398 my $sub = sub {
294 8 50       643 my @args = @_;
295 0         0 my $ret;
296             eval {
297 8         47 $ret = $self->$method_body($weak_ctx, @args);
298 8         20 };
299 8         23 if ($@) {
300             if (blessed($@)) {
301 4     4   31355 die $@;
302 4         7 } else {
303 4         5 Catalyst::Exception->throw($@);
304 4         18 }
305             }
306 4 100       278 return $ret;
307 2 100       94 };
308 1         5 $vars{$method_name} = $sub;
309             }
310 1         6 }
311             return %vars;
312             }
313 2         9  
314 8         40 1;
315 8         21  
316              
317             =head1 DESCRIPTION
318 23         2477  
319             This is the Catalyst view class for the L<Template Toolkit|Template>.
320             Your application should defined a view class which is a subclass of
321             this module. Throughout this manual it will be assumed that your application
322             is named F<MyApp> and you are creating a TT view named F<Web>; these names
323             are placeholders and should always be replaced with whatever name you've
324             chosen for your application and your view. The easiest way to create a TT
325             view class is through the F<myapp_create.pl> script that is created along
326             with the application:
327              
328             $ script/myapp_create.pl view Web TT
329              
330             This creates a F<MyApp::View::Web.pm> module in the F<lib> directory (again,
331             replacing C<MyApp> with the name of your application) which looks
332             something like this:
333              
334             package FooBar::View::Web;
335             use Moose;
336              
337             extends 'Catalyst::View::TT';
338              
339             __PACKAGE__->config(DEBUG => 'all');
340              
341             Now you can modify your action handlers in the main application and/or
342             controllers to forward to your view class. You might choose to do this
343             in the end() method, for example, to automatically forward all actions
344             to the TT view class.
345              
346             # In MyApp or MyApp::Controller::SomeController
347              
348             sub end : Private {
349             my( $self, $c ) = @_;
350             $c->forward( $c->view('Web') );
351             }
352              
353             But if you are using the standard auto-generated end action, you don't even need
354             to do this!
355              
356             # in MyApp::Controller::Root
357             sub end : ActionClass('RenderView') {} # no need to change this line
358              
359             # in MyApp.pm
360             __PACKAGE__->config(
361             ...
362             default_view => 'Web',
363             );
364              
365             This will Just Work. And it has the advantages that:
366              
367             =over 4
368              
369             =item *
370              
371             If you want to use a different view for a given request, just set
372             << $c->stash->{current_view} >>. (See L<Catalyst>'s C<< $c->view >> method
373             for details.
374              
375             =item *
376              
377             << $c->res->redirect >> is handled by default. If you just forward to
378             C<View::Web> in your C<end> routine, you could break this by sending additional
379             content.
380              
381             =back
382              
383             See L<Catalyst::Action::RenderView> for more details.
384              
385             =head2 CONFIGURATION
386              
387             There are a three different ways to configure your view class. The
388             first way is to call the C<config()> method in the view subclass. This
389             happens when the module is first loaded.
390              
391             package MyApp::View::Web;
392             use Moose;
393             extends 'Catalyst::View::TT';
394              
395             __PACKAGE__->config({
396             PRE_PROCESS => 'config/main',
397             WRAPPER => 'site/wrapper',
398             });
399              
400             You may also override the configuration provided in the view class by adding
401             a 'View::Web' section to your application config.
402              
403             This should generally be used to inject the include paths into the view to
404             avoid the view trying to load the application to resolve paths.
405              
406             .. inside MyApp.pm ..
407             __PACKAGE__->config(
408             'View::Web' => {
409             INCLUDE_PATH => [
410             __PACKAGE__->path_to( 'root', 'templates', 'lib' ),
411             __PACKAGE__->path_to( 'root', 'templates', 'src' ),
412             ],
413             },
414             );
415              
416             You can also configure your view from within your config file if you're
417             using L<Catalyst::Plugin::ConfigLoader>. This should be reserved for
418             deployment-specific concerns. For example:
419              
420             # MyApp_local.conf (Config::General format)
421              
422             <View Web>
423             WRAPPER "custom_wrapper"
424             INCLUDE_PATH __path_to('root/templates/custom_site')__
425             INCLUDE_PATH __path_to('root/templates')__
426             </View>
427              
428             might be used as part of a simple way to deploy different instances of the
429             same application with different themes.
430              
431             =head2 DYNAMIC INCLUDE_PATH
432              
433             Sometimes it is desirable to modify INCLUDE_PATH for your templates at run time.
434              
435             Additional paths can be added to the start of INCLUDE_PATH via the stash as
436             follows:
437              
438             $c->stash->{additional_template_paths} =
439             [$c->config->{root} . '/test_include_path'];
440              
441             If you need to add paths to the end of INCLUDE_PATH, there is also an
442             include_path() accessor available:
443              
444             push( @{ $c->view('Web')->include_path }, qw/path/ );
445              
446             Note that if you use include_path() to add extra paths to INCLUDE_PATH, you
447             MUST check for duplicate paths. Without such checking, the above code will add
448             "path" to INCLUDE_PATH at every request, causing a memory leak.
449              
450             A safer approach is to use include_path() to overwrite the array of paths
451             rather than adding to it. This eliminates both the need to perform duplicate
452             checking and the chance of a memory leak:
453              
454             @{ $c->view('Web')->include_path } = qw/path another_path/;
455              
456             If you are calling C<render> directly then you can specify dynamic paths by
457             having a C<additional_template_paths> key with a value of additional directories
458             to search. See L</CAPTURING TEMPLATE OUTPUT> for an example showing this.
459              
460             =head2 Unicode (pre Catalyst v5.90080)
461              
462             B<NOTE> Starting with L<Catalyst> v5.90080 unicode and encoding has been
463             baked into core, and the default encoding is UTF-8. The following advice
464             is for older versions of L<Catalyst>.
465              
466             Be sure to set C<< ENCODING => 'utf-8' >> and use
467             L<Catalyst::Plugin::Unicode::Encoding> if you want to use non-ascii
468             characters (encoded as utf-8) in your templates. This is only needed if
469             you actually have UTF8 literals in your templates and the BOM is not
470             properly set. Setting encoding here does not magically encode your
471             template output. If you are using this version of L<Catalyst> you need
472             to all the Unicode plugin, or upgrade (preferred)
473              
474             =head2 Unicode (Catalyst v5.90080+)
475              
476             This version of L<Catalyst> will automatically encode your body output
477             to UTF8. This means if your variables contain multibyte characters you don't
478             need top do anything else to get UTF8 output. B<However> if your templates
479             contain UTF8 literals (like, multibyte characters actually in the template
480             text), then you do need to either set the BOM mark on the template file or
481             instruct TT to decode the templates at load time via the ENCODING configuration
482             setting. Most of the time you can just do:
483              
484             MyApp::View::HTML->config(
485             ENCODING => 'UTF-8');
486              
487             and that will just take care of everything. This configuration setting will
488             force L<Template> to decode all files correctly, so that when you hit
489             the finalize_encoding step we can properly encode the body as UTF8. If you
490             fail to do this you will get double encoding issues in your output (but again,
491             only for the UTF8 literals in your actual template text.)
492              
493             Again, this ENCODING configuration setting only instructs template toolkit
494             how (and if) to decode the contents of your template files when reading them from
495             disk. It has no other effect.
496              
497             =head2 RENDERING VIEWS
498              
499             The view plugin renders the template specified in the C<template>
500             item in the stash.
501              
502             sub message : Global {
503             my ( $self, $c ) = @_;
504             $c->stash->{template} = 'message.tt2';
505             $c->forward( $c->view('Web') );
506             }
507              
508             If a stash item isn't defined, then it instead uses the
509             stringification of the action dispatched to (as defined by $c->action)
510             in the above example, this would be C<message>, but because the default
511             is to append '.tt', it would load C<root/message.tt>.
512              
513             The items defined in the stash are passed to the Template Toolkit for
514             use as template variables.
515              
516             sub default : Private {
517             my ( $self, $c ) = @_;
518             $c->stash->{template} = 'message.tt2';
519             $c->stash->{message} = 'Hello World!';
520             $c->forward( $c->view('Web') );
521             }
522              
523             A number of other template variables are also added:
524              
525             c A reference to the context object, $c
526             base The URL base, from $c->req->base()
527             name The application name, from $c->config->{ name }
528              
529             These can be accessed from the template in the usual way:
530              
531             <message.tt2>:
532              
533             The message is: [% message %]
534             The base is [% base %]
535             The name is [% name %]
536              
537              
538             The output generated by the template is stored in C<< $c->response->body >>.
539              
540             =head2 CAPTURING TEMPLATE OUTPUT
541              
542             If you wish to use the output of a template for some other purpose than
543             displaying in the response, e.g. for sending an email, this is possible using
544             other views, such as L<Catalyst::View::Email::Template>.
545              
546             =head2 TEMPLATE PROFILING
547              
548             See L</C<TIMER>> property of the L</config> method.
549              
550             =head1 METHODS
551              
552             =head2 new
553              
554             The constructor for the TT view. Sets up the template provider,
555             and reads the application config.
556              
557             =head2 process($c)
558              
559             Renders the template specified in C<< $c->stash->{template} >> or
560             C<< $c->action >> (the private name of the matched action). Calls
561             L<render|/render($c, $template, \%args)> to
562             perform actual rendering. Output is stored in C<< $c->response->body >>.
563              
564             It is possible to forward to the process method of a TT view from inside
565             Catalyst like this:
566              
567             $c->forward('View::Web');
568              
569             N.B. This is usually done automatically by L<Catalyst::Action::RenderView>.
570              
571             =head2 render($c, $template, \%args)
572              
573             Renders the given template and returns output. Throws a L<Template::Exception>
574             object upon error.
575              
576             The template variables are set to C<%$args> if C<$args> is a hashref, or
577             C<< $c->stash >> otherwise. In either case the variables are augmented with
578             C<base> set to C<< $c->req->base >>, C<c> to C<$c>, and C<name> to
579             C<< $c->config->{name} >>. Alternately, the C<CATALYST_VAR> configuration item
580             can be defined to specify the name of a template variable through which the
581             context reference (C<$c>) can be accessed. In this case, the C<c>, C<base>, and
582             C<name> variables are omitted.
583              
584             C<$template> can be anything that Template::process understands how to
585             process, including the name of a template file or a reference to a test string.
586             See L<Template::process|Template/process> for a full list of supported formats.
587              
588             To use the render method outside of your Catalyst app, just pass a undef context.
589             This can be useful for tests, for instance.
590              
591             It is possible to forward to the render method of a TT view from inside Catalyst
592             to render page fragments like this:
593              
594             my $fragment = $c->forward("View::Web", "render", $template_name, $c->stash->{fragment_data});
595              
596             =head3 Backwards compatibility note
597              
598             The render method used to just return the Template::Exception object, rather
599             than just throwing it. This is now deprecated and instead the render method
600             will throw an exception for new applications.
601              
602             This behaviour can be activated (and is activated in the default skeleton
603             configuration) by using C<< render_die => 1 >>. If you rely on the legacy
604             behaviour then a warning will be issued.
605              
606             To silence this warning, set C<< render_die => 0 >>, but it is recommended
607             you adjust your code so that it works with C<< render_die => 1 >>.
608              
609             In a future release, C<< render_die => 1 >> will become the default if
610             unspecified.
611              
612             =head2 template_vars
613              
614             Returns a list of keys/values to be used as the catalyst variables in the
615             template.
616              
617             =head2 config
618              
619             This method allows your view subclass to pass additional settings to
620             the TT configuration hash, or to set the options as below:
621              
622             =head2 paths
623              
624             The list of paths TT will look for templates in.
625              
626             =head2 expose_methods
627              
628             The list of methods in your View class which should be made available to the templates.
629              
630             For example:
631              
632             expose_methods => [qw/uri_for_css/],
633              
634             ...
635              
636             sub uri_for_css {
637             my ($self, $c, $filename) = @_;
638              
639             # additional complexity like checking file exists here
640              
641             return $c->uri_for('/static/css/' . $filename);
642             }
643              
644             Then in the template:
645              
646             [% uri_for_css('home.css') %]
647              
648             =head2 content_type
649              
650             This lets you override the default content type for the response. If you do
651             not set this and if you do not set the content type in your controllers, the
652             default is C<text/html; charset=utf-8>.
653              
654             Use this if you are creating alternative view responses, such as text or JSON
655             and want a global setting.
656              
657             Any content type set in your controllers before calling this view are respected
658             and have priority.
659              
660             =head2 C<CATALYST_VAR>
661              
662             Allows you to change the name of the Catalyst context object. If set, it will also
663             remove the base and name aliases, so you will have access them through <context>.
664              
665             For example, if CATALYST_VAR has been set to "Catalyst", a template might
666             contain:
667              
668             The base is [% Catalyst.req.base %]
669             The name is [% Catalyst.config.name %]
670              
671             =head2 C<TIMER>
672              
673             If you have configured Catalyst for debug output, and turned on the TIMER setting,
674             C<Catalyst::View::TT> will enable profiling of template processing
675             (using L<Template::Timer>). This will embed HTML comments in the
676             output from your templates, such as:
677              
678             <!-- TIMER START: process mainmenu/mainmenu.ttml -->
679             <!-- TIMER START: include mainmenu/cssindex.tt -->
680             <!-- TIMER START: process mainmenu/cssindex.tt -->
681             <!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) -->
682             <!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) -->
683              
684             ....
685              
686             <!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) -->
687              
688              
689             =head2 C<TEMPLATE_EXTENSION>
690              
691             a suffix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>.
692              
693             For example:
694              
695             package MyApp::Controller::Test;
696             sub test : Local { .. }
697              
698             Would by default look for a template in <root>/test/test. If you set TEMPLATE_EXTENSION to '.tt', it will look for
699             <root>/test/test.tt.
700              
701             =head2 C<PROVIDERS>
702              
703             Allows you to specify the template providers that TT will use.
704              
705             MyApp->config(
706             name => 'MyApp',
707             root => MyApp->path_to('root'),
708             'View::Web' => {
709             PROVIDERS => [
710             {
711             name => 'DBI',
712             args => {
713             DBI_DSN => 'dbi:DB2:books',
714             DBI_USER=> 'foo'
715             }
716             }, {
717             name => '_file_',
718             args => {}
719             }
720             ]
721             },
722             );
723              
724             The 'name' key should correspond to the class name of the provider you
725             want to use. The _file_ name is a special case that represents the default
726             TT file-based provider. By default the name is will be prefixed with
727             'Template::Provider::'. You can fully qualify the name by using a unary
728             plus:
729              
730             name => '+MyApp::Provider::Foo'
731              
732             You can also specify the 'copy_config' key as an arrayref, to copy those keys
733             from the general config, into the config for the provider:
734              
735             DEFAULT_ENCODING => 'utf-8',
736             PROVIDERS => [
737             {
738             name => 'Encoding',
739             copy_config => [qw(DEFAULT_ENCODING INCLUDE_PATH)]
740             }
741             ]
742              
743             This can prove useful when you want to use the additional_template_paths hack
744             in your own provider, or if you need to use Template::Provider::Encoding
745              
746             =head2 C<CLASS>
747              
748             Allows you to specify a custom class to use as the template class instead of
749             L<Template>.
750              
751             package MyApp::View::Web;
752             use Moose;
753             extends 'Catalyst::View::TT';
754              
755             use Template::AutoFilter;
756              
757             __PACKAGE__->config({
758             CLASS => 'Template::AutoFilter',
759             });
760              
761             This is useful if you want to use your own subclasses of L<Template>, so you
762             can, for example, prevent XSS by automatically filtering all output through
763             C<| html>.
764              
765             =head2 HELPERS
766              
767             The L<Catalyst::Helper::View::TT> and
768             L<Catalyst::Helper::View::TTSite> helper modules are provided to create
769             your view module. There are invoked by the F<myapp_create.pl> script:
770              
771             $ script/myapp_create.pl view Web TT
772              
773             $ script/myapp_create.pl view Web TTSite
774              
775             The L<Catalyst::Helper::View::TT> module creates a basic TT view
776             module. The L<Catalyst::Helper::View::TTSite> module goes a little
777             further. It also creates a default set of templates to get you
778             started. It also configures the view module to locate the templates
779             automatically.
780              
781             =head1 NOTES
782              
783             If you are using the L<CGI> module inside your templates, you will
784             experience that the Catalyst server appears to hang while rendering
785             the web page. This is due to the debug mode of L<CGI> (which is
786             waiting for input in the terminal window). Turning off the
787             debug mode using the "-no_debug" option solves the
788             problem, eg.:
789              
790             [% USE CGI('-no_debug') %]
791              
792             =head1 SEE ALSO
793              
794             L<Catalyst>, L<Catalyst::Helper::View::TT>,
795             L<Catalyst::Helper::View::TTSite>, L<Template::Manual>
796              
797             =head1 AUTHORS
798              
799             Sebastian Riedel, C<sri@cpan.org>
800              
801             Marcus Ramberg, C<mramberg@cpan.org>
802              
803             Jesse Sheidlower, C<jester@panix.com>
804              
805             Andy Wardley, C<abw@cpan.org>
806              
807             Luke Saunders, C<luke.saunders@gmail.com>
808              
809             =head1 COPYRIGHT
810              
811             This program is free software. You can redistribute it and/or modify it
812             under the same terms as Perl itself.
813              
814             =cut