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 |