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