line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Catalyst::View::TT; |
2
|
|
|
|
|
|
|
|
3
|
12
|
|
|
12
|
|
19829697
|
use strict; |
|
12
|
|
|
|
|
47
|
|
|
12
|
|
|
|
|
384
|
|
4
|
12
|
|
|
12
|
|
71
|
use warnings; |
|
12
|
|
|
|
|
23
|
|
|
12
|
|
|
|
|
464
|
|
5
|
|
|
|
|
|
|
|
6
|
12
|
|
|
12
|
|
68
|
use base qw/Catalyst::View/; |
|
12
|
|
|
|
|
40
|
|
|
12
|
|
|
|
|
6102
|
|
7
|
12
|
|
|
12
|
|
1439858
|
use Data::Dump 'dump'; |
|
12
|
|
|
|
|
17215
|
|
|
12
|
|
|
|
|
802
|
|
8
|
12
|
|
|
12
|
|
6818
|
use Template; |
|
12
|
|
|
|
|
236371
|
|
|
12
|
|
|
|
|
429
|
|
9
|
12
|
|
|
12
|
|
5542
|
use Template::Timer; |
|
12
|
|
|
|
|
78831
|
|
|
12
|
|
|
|
|
343
|
|
10
|
12
|
|
|
12
|
|
92
|
use MRO::Compat; |
|
12
|
|
|
|
|
30
|
|
|
12
|
|
|
|
|
319
|
|
11
|
12
|
|
|
12
|
|
71
|
use Scalar::Util qw/blessed weaken/; |
|
12
|
|
|
|
|
28
|
|
|
12
|
|
|
|
|
19118
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $VERSION = '0.45'; |
14
|
|
|
|
|
|
|
$VERSION =~ tr/_//d; |
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
|
|
257
|
my ( $paths, $dlim ) = shift; |
86
|
92
|
100
|
|
|
|
278
|
return () if ( !$paths ); |
87
|
21
|
50
|
|
|
|
145
|
return @{$paths} if ( ref $paths eq 'ARRAY' ); |
|
0
|
|
|
|
|
0
|
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# tweak delim to ignore C:/ |
90
|
21
|
50
|
|
|
|
72
|
unless ( defined $dlim ) { |
91
|
21
|
50
|
|
|
|
116
|
$dlim = ( $^O eq 'MSWin32' ) ? ':(?!\\/)' : ':'; |
92
|
|
|
|
|
|
|
} |
93
|
21
|
|
|
|
|
211
|
return split( /$dlim/, $paths ); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub new { |
97
|
112
|
|
|
112
|
1
|
2471452
|
my ( $class, $c, $arguments ) = @_; |
98
|
|
|
|
|
|
|
my $config = { |
99
|
|
|
|
|
|
|
EVAL_PERL => 0, |
100
|
|
|
|
|
|
|
TEMPLATE_EXTENSION => '', |
101
|
|
|
|
|
|
|
CLASS => 'Template', |
102
|
112
|
|
|
|
|
416
|
%{ $class->config }, |
103
|
112
|
|
|
|
|
239
|
%{$arguments}, |
|
112
|
|
|
|
|
41829
|
|
104
|
|
|
|
|
|
|
}; |
105
|
112
|
100
|
|
|
|
451
|
if ( ! (ref $config->{INCLUDE_PATH} eq 'ARRAY') ) { |
106
|
92
|
|
|
|
|
311
|
my $delim = $config->{DELIMITER}; |
107
|
|
|
|
|
|
|
my @include_path |
108
|
92
|
|
|
|
|
303
|
= _coerce_paths( $config->{INCLUDE_PATH}, $delim ); |
109
|
92
|
100
|
|
|
|
551
|
if ( !@include_path ) { |
110
|
71
|
|
|
|
|
275
|
my $root = $c->config->{root}; |
111
|
71
|
|
|
|
|
5660
|
my $base = Path::Class::dir( $root, 'base' ); |
112
|
71
|
|
|
|
|
4233
|
@include_path = ( "$root", "$base" ); |
113
|
|
|
|
|
|
|
} |
114
|
92
|
|
|
|
|
3092
|
$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
|
|
|
|
300
|
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
|
|
|
437
|
if ( $c->debug && $config->{DUMP_CONFIG} ) { |
133
|
0
|
|
|
|
|
0
|
$c->log->debug( "TT Config: ", dump($config) ); |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
112
|
|
|
|
|
1126
|
my $self = $class->next::method( |
137
|
|
|
|
|
|
|
$c, { %$config }, |
138
|
|
|
|
|
|
|
); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Set base include paths. Local'd in render if needed |
141
|
112
|
|
|
|
|
193402
|
$self->include_path($config->{INCLUDE_PATH}); |
142
|
|
|
|
|
|
|
|
143
|
112
|
|
|
|
|
41053
|
$self->expose_methods($config->{expose_methods}); |
144
|
112
|
|
|
|
|
34426
|
$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
|
|
|
|
|
14378
|
my $copy = $self; |
152
|
112
|
|
|
|
|
404
|
Scalar::Util::weaken($copy); |
153
|
112
|
|
|
17
|
|
650
|
$config->{INCLUDE_PATH} = [ sub { $copy->paths } ]; |
|
17
|
|
|
|
|
4899
|
|
154
|
|
|
|
|
|
|
|
155
|
112
|
100
|
|
|
|
346
|
if ( $config->{PROVIDERS} ) { |
156
|
10
|
|
|
|
|
35
|
my @providers = (); |
157
|
10
|
50
|
|
|
|
59
|
if ( ref($config->{PROVIDERS}) eq 'ARRAY') { |
158
|
10
|
|
|
|
|
20
|
foreach my $p (@{$config->{PROVIDERS}}) { |
|
10
|
|
|
|
|
52
|
|
159
|
10
|
|
|
|
|
29
|
my $pname = $p->{name}; |
160
|
10
|
|
|
|
|
24
|
my $prov = 'Template::Provider'; |
161
|
10
|
50
|
|
|
|
44
|
if($pname eq '_file_') |
162
|
|
|
|
|
|
|
{ |
163
|
0
|
|
|
|
|
0
|
$p->{args} = { %$config }; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
else |
166
|
|
|
|
|
|
|
{ |
167
|
10
|
50
|
|
|
|
80
|
if($pname =~ s/^\+//) { |
168
|
10
|
|
|
|
|
33
|
$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
|
|
|
67
|
$p->{args} ||= {}; |
177
|
10
|
50
|
|
|
|
53
|
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
|
|
|
|
|
30
|
local $@; |
184
|
10
|
|
|
|
|
1013
|
eval "require $prov"; |
185
|
10
|
50
|
|
|
|
3250
|
if(!$@) { |
186
|
10
|
|
|
|
|
142
|
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
|
|
|
|
|
864
|
delete $config->{PROVIDERS}; |
195
|
10
|
50
|
|
|
|
49
|
if(@providers) { |
196
|
10
|
|
|
|
|
30
|
$config->{LOAD_TEMPLATES} = \@providers; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
$self->{template} = |
201
|
112
|
|
33
|
|
|
639
|
$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
|
|
|
|
|
250604
|
return $self; |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub process { |
213
|
18
|
|
|
18
|
1
|
1119609
|
my ( $self, $c ) = @_; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
my $template = $c->stash->{template} |
216
|
18
|
|
66
|
|
|
86
|
|| $c->action . $self->config->{TEMPLATE_EXTENSION}; |
217
|
|
|
|
|
|
|
|
218
|
18
|
50
|
|
|
|
2146
|
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
|
|
|
|
|
42
|
my $output = eval { $self->render($c, $template) }; |
|
18
|
|
|
|
|
123
|
|
225
|
18
|
50
|
|
|
|
82
|
if (my $err = $@) { |
226
|
0
|
|
|
|
|
0
|
return $self->_rendering_error($c, $template . ': ' . $err); |
227
|
|
|
|
|
|
|
} |
228
|
18
|
50
|
33
|
|
|
130
|
if (blessed($output) && $output->isa('Template::Exception')) { |
229
|
0
|
|
|
|
|
0
|
$self->_rendering_error($c, $output); |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
18
|
50
|
|
|
|
522
|
unless ( $c->response->content_type ) { |
233
|
18
|
|
100
|
|
|
5343
|
my $default = $self->content_type || 'text/html; charset=UTF-8'; |
234
|
18
|
|
|
|
|
3063
|
$c->response->content_type($default); |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
18
|
|
|
|
|
3796
|
$c->response->body($output); |
238
|
|
|
|
|
|
|
|
239
|
18
|
|
|
|
|
676
|
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
|
177086
|
my ($self, $c, $template, $args) = @_; |
252
|
|
|
|
|
|
|
|
253
|
22
|
50
|
66
|
|
|
136
|
$c->log->debug(qq/Rendering template "$template"/) if $c && $c->debug; |
254
|
|
|
|
|
|
|
|
255
|
22
|
|
|
|
|
157
|
my $output; |
256
|
|
|
|
|
|
|
my $vars = { |
257
|
22
|
100
|
|
|
|
108
|
(ref $args eq 'HASH' ? %$args : %{ $c->stash() }), |
|
19
|
|
|
|
|
97
|
|
258
|
|
|
|
|
|
|
$self->template_vars($c) |
259
|
|
|
|
|
|
|
}; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
local $self->{include_path} = |
262
|
2
|
|
|
|
|
7
|
[ @{ $vars->{additional_template_paths} }, @{ $self->{include_path} } ] |
|
2
|
|
|
|
|
11
|
|
263
|
22
|
100
|
|
|
|
121
|
if ref $vars->{additional_template_paths}; |
264
|
|
|
|
|
|
|
|
265
|
22
|
100
|
|
|
|
159
|
unless ( $self->template->process( $template, $vars, \$output ) ) { |
266
|
1
|
50
|
|
|
|
522
|
if (exists $self->{render_die}) { |
267
|
1
|
50
|
|
|
|
7
|
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
|
|
|
|
|
286935
|
return $output; |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub template_vars { |
277
|
22
|
|
|
22
|
1
|
1379
|
my ( $self, $c ) = @_; |
278
|
|
|
|
|
|
|
|
279
|
22
|
100
|
|
|
|
76
|
return () unless $c; |
280
|
21
|
|
|
|
|
80
|
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
|
|
|
|
1724
|
); |
289
|
|
|
|
|
|
|
|
290
|
21
|
100
|
|
|
|
3135
|
if ($self->expose_methods) { |
291
|
2
|
|
|
|
|
314
|
my $meta = $self->meta; |
292
|
2
|
|
|
|
|
34
|
foreach my $method_name (@{$self->expose_methods}) { |
|
2
|
|
|
|
|
5
|
|
293
|
2
|
|
|
|
|
196
|
my $method = $meta->find_method_by_name( $method_name ); |
294
|
2
|
50
|
|
|
|
321
|
unless ($method) { |
295
|
0
|
|
|
|
|
0
|
Catalyst::Exception->throw( "$method_name not found in TT view" ); |
296
|
|
|
|
|
|
|
} |
297
|
2
|
|
|
|
|
18
|
my $method_body = $method->body; |
298
|
2
|
|
|
|
|
4
|
my $weak_ctx = $c; |
299
|
2
|
|
|
|
|
6
|
weaken $weak_ctx; |
300
|
|
|
|
|
|
|
my $sub = sub { |
301
|
2
|
|
|
2
|
|
29108
|
$self->$method_body($weak_ctx, @_); |
302
|
2
|
|
|
|
|
12
|
}; |
303
|
2
|
|
|
|
|
8
|
$vars{$method_name} = $sub; |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
} |
306
|
21
|
|
|
|
|
2923
|
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
|
|
|
|
|
|
|
=head1 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 |
557
|
|
|
|
|
|
|
L<render|/render($c, $template, \%args)> to |
558
|
|
|
|
|
|
|
perform actual rendering. Output is stored in C<< $c->response->body >>. |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
It is possible to forward to the process method of a TT view from inside |
561
|
|
|
|
|
|
|
Catalyst like this: |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
$c->forward('View::Web'); |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
N.B. This is usually done automatically by L<Catalyst::Action::RenderView>. |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=head2 render($c, $template, \%args) |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Renders the given template and returns output. Throws a L<Template::Exception> |
570
|
|
|
|
|
|
|
object upon error. |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
The template variables are set to C<%$args> if C<$args> is a hashref, or |
573
|
|
|
|
|
|
|
C<< $c->stash >> otherwise. In either case the variables are augmented with |
574
|
|
|
|
|
|
|
C<base> set to C<< $c->req->base >>, C<c> to C<$c>, and C<name> to |
575
|
|
|
|
|
|
|
C<< $c->config->{name} >>. Alternately, the C<CATALYST_VAR> configuration item |
576
|
|
|
|
|
|
|
can be defined to specify the name of a template variable through which the |
577
|
|
|
|
|
|
|
context reference (C<$c>) can be accessed. In this case, the C<c>, C<base>, and |
578
|
|
|
|
|
|
|
C<name> variables are omitted. |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
C<$template> can be anything that Template::process understands how to |
581
|
|
|
|
|
|
|
process, including the name of a template file or a reference to a test string. |
582
|
|
|
|
|
|
|
See L<Template::process|Template/process> for a full list of supported formats. |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
To use the render method outside of your Catalyst app, just pass a undef context. |
585
|
|
|
|
|
|
|
This can be useful for tests, for instance. |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
It is possible to forward to the render method of a TT view from inside Catalyst |
588
|
|
|
|
|
|
|
to render page fragments like this: |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
my $fragment = $c->forward("View::Web", "render", $template_name, $c->stash->{fragment_data}); |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
=head3 Backwards compatibility note |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
The render method used to just return the Template::Exception object, rather |
595
|
|
|
|
|
|
|
than just throwing it. This is now deprecated and instead the render method |
596
|
|
|
|
|
|
|
will throw an exception for new applications. |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
This behaviour can be activated (and is activated in the default skeleton |
599
|
|
|
|
|
|
|
configuration) by using C<< render_die => 1 >>. If you rely on the legacy |
600
|
|
|
|
|
|
|
behaviour then a warning will be issued. |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
To silence this warning, set C<< render_die => 0 >>, but it is recommended |
603
|
|
|
|
|
|
|
you adjust your code so that it works with C<< render_die => 1 >>. |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
In a future release, C<< render_die => 1 >> will become the default if |
606
|
|
|
|
|
|
|
unspecified. |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=head2 template_vars |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
Returns a list of keys/values to be used as the catalyst variables in the |
611
|
|
|
|
|
|
|
template. |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
=head2 config |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
This method allows your view subclass to pass additional settings to |
616
|
|
|
|
|
|
|
the TT configuration hash, or to set the options as below: |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=head2 paths |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
The list of paths TT will look for templates in. |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
=head2 expose_methods |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
The list of methods in your View class which should be made available to the templates. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
For example: |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
expose_methods => [qw/uri_for_css/], |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
... |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
sub uri_for_css { |
633
|
|
|
|
|
|
|
my ($self, $c, $filename) = @_; |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
# additional complexity like checking file exists here |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
return $c->uri_for('/static/css/' . $filename); |
638
|
|
|
|
|
|
|
} |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
Then in the template: |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
[% uri_for_css('home.css') %] |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=head2 content_type |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
This lets you override the default content type for the response. If you do |
647
|
|
|
|
|
|
|
not set this and if you do not set the content type in your controllers, the |
648
|
|
|
|
|
|
|
default is C<text/html; charset=utf-8>. |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
Use this if you are creating alternative view responses, such as text or JSON |
651
|
|
|
|
|
|
|
and want a global setting. |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
Any content type set in your controllers before calling this view are respected |
654
|
|
|
|
|
|
|
and have priority. |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=head2 C<CATALYST_VAR> |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
Allows you to change the name of the Catalyst context object. If set, it will also |
659
|
|
|
|
|
|
|
remove the base and name aliases, so you will have access them through <context>. |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
For example, if CATALYST_VAR has been set to "Catalyst", a template might |
662
|
|
|
|
|
|
|
contain: |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
The base is [% Catalyst.req.base %] |
665
|
|
|
|
|
|
|
The name is [% Catalyst.config.name %] |
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
=head2 C<TIMER> |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
If you have configured Catalyst for debug output, and turned on the TIMER setting, |
670
|
|
|
|
|
|
|
C<Catalyst::View::TT> will enable profiling of template processing |
671
|
|
|
|
|
|
|
(using L<Template::Timer>). This will embed HTML comments in the |
672
|
|
|
|
|
|
|
output from your templates, such as: |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
<!-- TIMER START: process mainmenu/mainmenu.ttml --> |
675
|
|
|
|
|
|
|
<!-- TIMER START: include mainmenu/cssindex.tt --> |
676
|
|
|
|
|
|
|
<!-- TIMER START: process mainmenu/cssindex.tt --> |
677
|
|
|
|
|
|
|
<!-- TIMER END: process mainmenu/cssindex.tt (0.017279 seconds) --> |
678
|
|
|
|
|
|
|
<!-- TIMER END: include mainmenu/cssindex.tt (0.017401 seconds) --> |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
.... |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
<!-- TIMER END: process mainmenu/footer.tt (0.003016 seconds) --> |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
=head2 C<TEMPLATE_EXTENSION> |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
a suffix to add when looking for templates bases on the C<match> method in L<Catalyst::Request>. |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
For example: |
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
package MyApp::Controller::Test; |
692
|
|
|
|
|
|
|
sub test : Local { .. } |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Would by default look for a template in <root>/test/test. If you set TEMPLATE_EXTENSION to '.tt', it will look for |
695
|
|
|
|
|
|
|
<root>/test/test.tt. |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=head2 C<PROVIDERS> |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
Allows you to specify the template providers that TT will use. |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
MyApp->config( |
702
|
|
|
|
|
|
|
name => 'MyApp', |
703
|
|
|
|
|
|
|
root => MyApp->path_to('root'), |
704
|
|
|
|
|
|
|
'View::Web' => { |
705
|
|
|
|
|
|
|
PROVIDERS => [ |
706
|
|
|
|
|
|
|
{ |
707
|
|
|
|
|
|
|
name => 'DBI', |
708
|
|
|
|
|
|
|
args => { |
709
|
|
|
|
|
|
|
DBI_DSN => 'dbi:DB2:books', |
710
|
|
|
|
|
|
|
DBI_USER=> 'foo' |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
}, { |
713
|
|
|
|
|
|
|
name => '_file_', |
714
|
|
|
|
|
|
|
args => {} |
715
|
|
|
|
|
|
|
} |
716
|
|
|
|
|
|
|
] |
717
|
|
|
|
|
|
|
}, |
718
|
|
|
|
|
|
|
); |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
The 'name' key should correspond to the class name of the provider you |
721
|
|
|
|
|
|
|
want to use. The _file_ name is a special case that represents the default |
722
|
|
|
|
|
|
|
TT file-based provider. By default the name is will be prefixed with |
723
|
|
|
|
|
|
|
'Template::Provider::'. You can fully qualify the name by using a unary |
724
|
|
|
|
|
|
|
plus: |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
name => '+MyApp::Provider::Foo' |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
You can also specify the 'copy_config' key as an arrayref, to copy those keys |
729
|
|
|
|
|
|
|
from the general config, into the config for the provider: |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
DEFAULT_ENCODING => 'utf-8', |
732
|
|
|
|
|
|
|
PROVIDERS => [ |
733
|
|
|
|
|
|
|
{ |
734
|
|
|
|
|
|
|
name => 'Encoding', |
735
|
|
|
|
|
|
|
copy_config => [qw(DEFAULT_ENCODING INCLUDE_PATH)] |
736
|
|
|
|
|
|
|
} |
737
|
|
|
|
|
|
|
] |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
This can prove useful when you want to use the additional_template_paths hack |
740
|
|
|
|
|
|
|
in your own provider, or if you need to use Template::Provider::Encoding |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=head2 C<CLASS> |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
Allows you to specify a custom class to use as the template class instead of |
745
|
|
|
|
|
|
|
L<Template>. |
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
package MyApp::View::Web; |
748
|
|
|
|
|
|
|
use Moose; |
749
|
|
|
|
|
|
|
extends 'Catalyst::View::TT'; |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
use Template::AutoFilter; |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
__PACKAGE__->config({ |
754
|
|
|
|
|
|
|
CLASS => 'Template::AutoFilter', |
755
|
|
|
|
|
|
|
}); |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
This is useful if you want to use your own subclasses of L<Template>, so you |
758
|
|
|
|
|
|
|
can, for example, prevent XSS by automatically filtering all output through |
759
|
|
|
|
|
|
|
C<| html>. |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
=head2 HELPERS |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
The L<Catalyst::Helper::View::TT> and |
764
|
|
|
|
|
|
|
L<Catalyst::Helper::View::TTSite> helper modules are provided to create |
765
|
|
|
|
|
|
|
your view module. There are invoked by the F<myapp_create.pl> script: |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
$ script/myapp_create.pl view Web TT |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
$ script/myapp_create.pl view Web TTSite |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
The L<Catalyst::Helper::View::TT> module creates a basic TT view |
772
|
|
|
|
|
|
|
module. The L<Catalyst::Helper::View::TTSite> module goes a little |
773
|
|
|
|
|
|
|
further. It also creates a default set of templates to get you |
774
|
|
|
|
|
|
|
started. It also configures the view module to locate the templates |
775
|
|
|
|
|
|
|
automatically. |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
=head1 NOTES |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
If you are using the L<CGI> module inside your templates, you will |
780
|
|
|
|
|
|
|
experience that the Catalyst server appears to hang while rendering |
781
|
|
|
|
|
|
|
the web page. This is due to the debug mode of L<CGI> (which is |
782
|
|
|
|
|
|
|
waiting for input in the terminal window). Turning off the |
783
|
|
|
|
|
|
|
debug mode using the "-no_debug" option solves the |
784
|
|
|
|
|
|
|
problem, eg.: |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
[% USE CGI('-no_debug') %] |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=head1 SEE ALSO |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
L<Catalyst>, L<Catalyst::Helper::View::TT>, |
791
|
|
|
|
|
|
|
L<Catalyst::Helper::View::TTSite>, L<Template::Manual> |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
=head1 AUTHORS |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
Sebastian Riedel, C<sri@cpan.org> |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
Marcus Ramberg, C<mramberg@cpan.org> |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
Jesse Sheidlower, C<jester@panix.com> |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
Andy Wardley, C<abw@cpan.org> |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
Luke Saunders, C<luke.saunders@gmail.com> |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=head1 COPYRIGHT |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
This program is free software. You can redistribute it and/or modify it |
808
|
|
|
|
|
|
|
under the same terms as Perl itself. |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
=cut |