| 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 |