line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojolicious::Renderer; |
2
|
50
|
|
|
1518
|
|
853
|
use Mojo::Base -base; |
|
50
|
|
|
|
|
213
|
|
|
50
|
|
|
|
|
410
|
|
3
|
|
|
|
|
|
|
|
4
|
50
|
|
|
983
|
|
412
|
use Carp qw(croak); |
|
50
|
|
|
|
|
163
|
|
|
50
|
|
|
|
|
2533
|
|
5
|
50
|
|
|
983
|
|
22761
|
use Mojo::Cache; |
|
50
|
|
|
|
|
213
|
|
|
50
|
|
|
|
|
435
|
|
6
|
50
|
|
|
481
|
|
420
|
use Mojo::DynamicMethods; |
|
50
|
|
|
|
|
210
|
|
|
50
|
|
|
|
|
356
|
|
7
|
50
|
|
|
481
|
|
379
|
use Mojo::File qw(curfile path); |
|
50
|
|
|
|
|
166
|
|
|
50
|
|
|
|
|
2697
|
|
8
|
50
|
|
|
481
|
|
364
|
use Mojo::JSON qw(encode_json); |
|
50
|
|
|
|
|
141
|
|
|
50
|
|
|
|
|
2206
|
|
9
|
50
|
|
|
481
|
|
348
|
use Mojo::Loader qw(data_section); |
|
50
|
|
|
|
|
187
|
|
|
50
|
|
|
|
|
2545
|
|
10
|
50
|
|
|
481
|
|
379
|
use Mojo::Util qw(decamelize deprecated encode gzip md5_sum monkey_patch); |
|
50
|
|
|
|
|
157
|
|
|
50
|
|
|
|
|
160439
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
has cache => sub { Mojo::Cache->new }; |
13
|
|
|
|
|
|
|
has classes => sub { ['main'] }; |
14
|
|
|
|
|
|
|
has compress => 1; |
15
|
|
|
|
|
|
|
has default_format => 'html'; |
16
|
|
|
|
|
|
|
has 'default_handler'; |
17
|
|
|
|
|
|
|
has encoding => 'UTF-8'; |
18
|
|
|
|
|
|
|
has [qw(handlers helpers)] => sub { {} }; |
19
|
|
|
|
|
|
|
has min_compress_size => 860; |
20
|
|
|
|
|
|
|
has paths => sub { [] }; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# Bundled templates |
23
|
|
|
|
|
|
|
my $TEMPLATES = curfile->sibling('resources', 'templates'); |
24
|
|
|
|
|
|
|
|
25
|
38
|
|
|
38
|
|
15354
|
sub DESTROY { Mojo::Util::_teardown($_) for @{shift->{namespaces}} } |
|
38
|
|
|
|
|
288
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub accepts { |
28
|
112
|
|
|
112
|
1
|
230
|
my ($self, $c) = (shift, shift); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# DEPRECATED! |
31
|
112
|
|
|
|
|
298
|
my $req = $c->req; |
32
|
112
|
|
|
|
|
437
|
my $param = $req->param('format'); |
33
|
112
|
50
|
|
|
|
288
|
deprecated 'The ?format=* parameter is deprecated in favor of ?_format=* for content negotiation' if defined $param; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# List representations |
36
|
112
|
|
100
|
|
|
438
|
my $fmt = $param // $req->param('_format') || $c->stash->{format}; |
37
|
112
|
100
|
|
|
|
391
|
my @exts = $fmt ? ($fmt) : (); |
38
|
112
|
|
|
|
|
195
|
push @exts, @{$c->app->types->detect($req->headers->accept)}; |
|
112
|
|
|
|
|
318
|
|
39
|
112
|
100
|
|
|
|
610
|
return \@exts unless @_; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Find best representation |
42
|
29
|
|
100
|
|
|
70
|
for my $ext (@exts) { $ext eq $_ and return $ext for @_ } |
|
13
|
|
|
|
|
89
|
|
43
|
22
|
100
|
|
|
|
135
|
return @exts ? undef : shift; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
231
|
50
|
|
231
|
1
|
906
|
sub add_handler { $_[0]->handlers->{$_[1]} = $_[2] and return $_[0] } |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub add_helper { |
49
|
8787
|
|
|
8787
|
1
|
17240
|
my ($self, $name, $cb) = @_; |
50
|
|
|
|
|
|
|
|
51
|
8787
|
|
|
|
|
17854
|
$self->helpers->{$name} = $cb; |
52
|
8787
|
|
|
|
|
16392
|
delete $self->{proxy}; |
53
|
8787
|
100
|
|
|
|
28724
|
$cb = $self->get_helper($name) if $name =~ s/\..*$//; |
54
|
8787
|
|
|
|
|
23145
|
Mojo::DynamicMethods::register $_, $self, $name, $cb for qw(Mojolicious Mojolicious::Controller); |
55
|
|
|
|
|
|
|
|
56
|
8787
|
|
|
|
|
30232
|
return $self; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub get_data_template { |
60
|
332
|
|
|
332
|
1
|
922
|
my ($self, $options) = @_; |
61
|
332
|
50
|
|
|
|
918
|
return undef unless my $template = $self->template_name($options); |
62
|
332
|
|
|
|
|
2321
|
return data_section $self->{index}{$template}, $template; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub get_helper { |
66
|
24223
|
|
|
24223
|
1
|
53397
|
my ($self, $name) = @_; |
67
|
|
|
|
|
|
|
|
68
|
24223
|
100
|
100
|
|
|
81116
|
if (my $h = $self->{proxy}{$name} || $self->helpers->{$name}) { return $h } |
|
21897
|
|
|
|
|
46694
|
|
69
|
|
|
|
|
|
|
|
70
|
2326
|
|
|
|
|
3956
|
my $found; |
71
|
2326
|
|
|
|
|
13254
|
my $class = 'Mojolicious::Renderer::Helpers::' . md5_sum "$name:$self"; |
72
|
2326
|
100
|
|
|
|
24144
|
my $re = length $name ? qr/^(\Q$name\E\.([^.]+))/ : qr/^(([^.]+))/; |
73
|
2326
|
|
|
|
|
4594
|
for my $key (keys %{$self->helpers}) { |
|
2326
|
|
|
|
|
8786
|
|
74
|
100863
|
100
|
|
|
|
293308
|
$key =~ $re ? ($found, my $method) = (1, $2) : next; |
75
|
17501
|
|
|
|
|
38205
|
my $sub = $self->get_helper($1); |
76
|
17501
|
|
|
5824
|
|
70880
|
monkey_patch $class, $method => sub { ${shift()}->$sub(@_) }; |
|
5824
|
|
|
5478
|
|
8597
|
|
|
5824
|
|
|
5478
|
|
18329
|
|
|
|
|
|
6067
|
|
|
|
|
|
|
|
5980
|
|
|
|
|
|
|
|
6490
|
|
|
|
|
|
|
|
7025
|
|
|
|
|
|
|
|
7502
|
|
|
|
|
|
|
|
7415
|
|
|
|
|
|
|
|
7854
|
|
|
|
|
|
|
|
8318
|
|
|
|
|
|
|
|
8741
|
|
|
|
|
|
|
|
9243
|
|
|
|
|
|
|
|
9674
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10536
|
|
|
|
|
|
|
|
10967
|
|
|
|
|
|
|
|
10967
|
|
|
|
|
|
|
|
10967
|
|
|
|
|
|
|
|
11398
|
|
|
|
|
|
|
|
11829
|
|
|
|
|
|
|
|
11398
|
|
|
|
|
|
|
|
12969
|
|
|
|
|
|
|
|
11452
|
|
|
|
|
|
|
|
10863
|
|
|
|
|
|
|
|
10440
|
|
|
|
|
|
|
|
10527
|
|
|
|
|
|
|
|
9930
|
|
|
|
|
|
|
|
10009
|
|
|
|
|
|
|
|
10042
|
|
|
|
|
|
|
|
10088
|
|
|
|
|
|
|
|
9570
|
|
|
|
|
|
|
|
9578
|
|
|
|
|
|
|
|
9611
|
|
|
|
|
|
|
|
9603
|
|
|
|
|
|
|
|
9728
|
|
|
|
|
|
|
|
9570
|
|
|
|
|
|
|
|
11572
|
|
|
|
|
|
|
|
10096
|
|
|
|
|
|
|
|
9930
|
|
|
|
|
|
|
|
10494
|
|
|
|
|
|
|
|
9938
|
|
|
|
|
|
|
|
9561
|
|
|
|
|
|
|
|
9507
|
|
|
|
|
|
|
|
9992
|
|
|
|
|
|
|
|
9076
|
|
|
|
|
|
|
|
9076
|
|
|
|
|
|
|
|
9180
|
|
|
|
|
|
|
|
9603
|
|
|
|
|
|
|
|
9674
|
|
|
|
|
|
|
|
9674
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10590
|
|
|
|
|
|
|
|
10432
|
|
|
|
|
|
|
|
10494
|
|
|
|
|
|
|
|
10369
|
|
|
|
|
|
|
|
10800
|
|
|
|
|
|
|
|
10904
|
|
|
|
|
|
|
|
11327
|
|
|
|
|
|
|
|
10967
|
|
|
|
|
|
|
|
10967
|
|
|
|
|
|
|
|
10590
|
|
|
|
|
|
|
|
10001
|
|
|
|
|
|
|
|
9578
|
|
|
|
|
|
|
|
9611
|
|
|
|
|
|
|
|
10034
|
|
|
|
|
|
|
|
10590
|
|
|
|
|
|
|
|
10432
|
|
|
|
|
|
|
|
10871
|
|
|
|
|
|
|
|
10904
|
|
|
|
|
|
|
|
10896
|
|
|
|
|
|
|
|
10536
|
|
|
|
|
|
|
|
10536
|
|
|
|
|
|
|
|
10536
|
|
|
|
|
|
|
|
11021
|
|
|
|
|
|
|
|
10432
|
|
|
|
|
|
|
|
10440
|
|
|
|
|
|
|
|
10473
|
|
|
|
|
|
|
|
10519
|
|
|
|
|
|
|
|
10432
|
|
|
|
|
|
|
|
10440
|
|
|
|
|
|
|
|
10527
|
|
|
|
|
|
|
|
9930
|
|
|
|
|
|
|
|
10009
|
|
|
|
|
|
|
|
10096
|
|
|
|
|
|
|
|
9068
|
|
|
|
|
|
|
|
9147
|
|
|
|
|
|
|
|
9611
|
|
|
|
|
|
|
|
10034
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10536
|
|
|
|
|
|
|
|
12530
|
|
|
|
|
|
|
|
12555
|
|
|
|
|
|
|
|
12986
|
|
|
|
|
|
|
|
13392
|
|
|
|
|
|
|
|
11829
|
|
|
|
|
|
|
|
11883
|
|
|
|
|
|
|
|
11725
|
|
|
|
|
|
|
|
11787
|
|
|
|
|
|
|
|
10369
|
|
|
|
|
|
|
|
10369
|
|
|
|
|
|
|
|
10473
|
|
|
|
|
|
|
|
10034
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
10105
|
|
|
|
|
|
|
|
2021
|
|
|
|
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
2326
|
50
|
|
|
|
9461
|
$found ? push @{$self->{namespaces}}, $class : return undef; |
|
2326
|
|
|
|
|
6498
|
|
80
|
2326
|
|
|
10196
|
|
11980
|
return $self->{proxy}{$name} = sub { bless \(my $dummy = shift), $class }; |
|
5569
|
|
|
|
|
27334
|
|
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub render { |
84
|
958
|
|
|
5050
|
1
|
2125
|
my ($self, $c) = @_; |
85
|
|
|
|
|
|
|
|
86
|
958
|
|
|
|
|
2235
|
my $stash = $c->stash; |
87
|
|
|
|
|
|
|
my $options = { |
88
|
|
|
|
|
|
|
encoding => $self->encoding, |
89
|
|
|
|
|
|
|
handler => $stash->{handler}, |
90
|
|
|
|
|
|
|
template => delete $stash->{template}, |
91
|
|
|
|
|
|
|
variant => $stash->{variant} |
92
|
958
|
|
|
|
|
3414
|
}; |
93
|
958
|
|
|
|
|
2733
|
my $inline = $options->{inline} = delete $stash->{inline}; |
94
|
958
|
100
|
66
|
|
|
2604
|
$options->{handler} //= $self->default_handler if defined $inline; |
95
|
958
|
|
66
|
|
|
3776
|
$options->{format} = $stash->{format} || $self->default_format; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# Data |
98
|
958
|
100
|
|
|
|
2991
|
return delete $stash->{data}, $options->{format} if defined $stash->{data}; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# Text |
101
|
889
|
100
|
|
|
|
2918
|
return _maybe($options->{encoding}, delete $stash->{text}), $options->{format} if defined $stash->{text}; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# JSON |
104
|
583
|
100
|
|
|
|
1697
|
return encode_json(delete $stash->{json}), 'json' if exists $stash->{json}; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# Template or templateless handler |
107
|
532
|
|
100
|
|
|
2478
|
$options->{template} //= $self->template_for($c); |
108
|
532
|
100
|
|
|
|
1940
|
return () unless $self->_render_template($c, \my $output, $options); |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Inheritance |
111
|
331
|
|
100
|
|
|
2069
|
my $content = $stash->{'mojo.content'} //= {}; |
112
|
331
|
100
|
100
|
|
|
2014
|
local $content->{content} = $output =~ /\S/ ? $output : undef if $stash->{extends} || $stash->{layout}; |
|
|
100
|
|
|
|
|
|
113
|
331
|
|
100
|
|
|
1101
|
while ((my $next = _next($stash)) && !defined $inline) { |
114
|
44
|
|
|
|
|
164
|
@$options{qw(handler template)} = ($stash->{handler}, $next); |
115
|
44
|
|
66
|
|
|
193
|
$options->{format} = $stash->{format} || $self->default_format; |
116
|
44
|
50
|
|
|
|
163
|
if ($self->_render_template($c, \my $tmp, $options)) { $output = $tmp } |
|
44
|
|
|
|
|
92
|
|
117
|
44
|
100
|
66
|
|
|
327
|
$content->{content} //= $output if $output =~ /\S/; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
331
|
100
|
|
|
|
1163
|
return $output if $stash->{'mojo.string'}; |
121
|
306
|
|
|
|
|
1036
|
return _maybe($options->{encoding}, $output), $options->{format}; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub respond { |
125
|
732
|
|
|
4322
|
1
|
3312
|
my ($self, $c, $output, $format, $status) = @_; |
126
|
|
|
|
|
|
|
|
127
|
732
|
50
|
|
|
|
2119
|
croak 'A response has already been rendered' if $c->stash->{'mojo.respond'}++; |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Gzip compression |
130
|
732
|
|
|
|
|
2586
|
my $res = $c->res; |
131
|
732
|
100
|
66
|
|
|
2690
|
if ($self->compress && length($output) >= $self->min_compress_size) { |
132
|
48
|
|
|
|
|
253
|
my $headers = $res->headers; |
133
|
48
|
|
|
|
|
4417
|
$headers->append(Vary => 'Accept-Encoding'); |
134
|
48
|
|
100
|
|
|
271
|
my $gzip = ($c->req->headers->accept_encoding // '') =~ /gzip/i; |
135
|
48
|
100
|
66
|
|
|
388
|
if ($gzip && !$headers->content_encoding) { |
136
|
45
|
|
|
|
|
175
|
$headers->content_encoding('gzip'); |
137
|
45
|
|
|
|
|
275
|
$output = gzip $output; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
732
|
|
|
|
|
4096
|
$res->body($output); |
142
|
732
|
|
|
|
|
2216
|
$c->app->types->content_type($c, {ext => $format}); |
143
|
732
|
|
|
|
|
3274
|
return !!$c->rendered($status); |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub template_for { |
147
|
207
|
|
|
3726
|
1
|
595
|
my ($self, $c) = @_; |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# Normal default template |
150
|
207
|
|
|
|
|
687
|
my $stash = $c->stash; |
151
|
207
|
|
|
|
|
766
|
my ($controller, $action) = @$stash{qw(controller action)}; |
152
|
207
|
100
|
100
|
|
|
775
|
return join '/', split(/-/, decamelize $controller), $action if $controller && $action; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Try the route name if we don't have controller and action |
155
|
203
|
100
|
|
|
|
613
|
return undef unless my $route = $c->match->endpoint; |
156
|
200
|
|
|
|
|
990
|
return $route->name; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub template_handler { |
160
|
454
|
|
|
3902
|
1
|
1089
|
my ($self, $options) = @_; |
161
|
454
|
100
|
|
|
|
1304
|
return undef unless my $file = $self->template_name($options); |
162
|
453
|
100
|
|
|
|
2117
|
return $self->default_handler unless my $handlers = $self->{templates}{$file}; |
163
|
273
|
|
|
|
|
1267
|
return $handlers->[0]; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub template_name { |
167
|
2005
|
|
|
5453
|
1
|
3750
|
my ($self, $options) = @_; |
168
|
|
|
|
|
|
|
|
169
|
2005
|
100
|
|
|
|
4999
|
return undef unless defined(my $template = $options->{template}); |
170
|
2004
|
50
|
|
|
|
4262
|
return undef unless my $format = $options->{format}; |
171
|
2004
|
|
|
|
|
3826
|
$template .= ".$format"; |
172
|
|
|
|
|
|
|
|
173
|
2004
|
100
|
|
|
|
4449
|
$self->warmup unless $self->{templates}; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# Variants |
176
|
2004
|
|
|
|
|
3297
|
my $handler = $options->{handler}; |
177
|
2004
|
100
|
|
|
|
4184
|
if (defined(my $variant = $options->{variant})) { |
178
|
21
|
|
|
|
|
49
|
$variant = "$template+$variant"; |
179
|
21
|
|
100
|
|
|
94
|
my $handlers = $self->{templates}{$variant} // []; |
180
|
21
|
100
|
100
|
|
|
119
|
$template = $variant if @$handlers && !defined $handler || grep { $_ eq $handler } @$handlers; |
|
10
|
|
100
|
|
|
44
|
|
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
2004
|
100
|
|
|
|
9670
|
return defined $handler ? "$template.$handler" : $template; |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub template_path { |
187
|
383
|
|
|
3831
|
1
|
860
|
my ($self, $options) = @_; |
188
|
383
|
50
|
|
|
|
903
|
return undef unless my $name = $self->template_name($options); |
189
|
383
|
|
|
|
|
1720
|
my @parts = split /\//, $name; |
190
|
383
|
|
100
|
|
|
866
|
-r and return $_ for map { path($_, @parts)->to_string } @{$self->paths}, $TEMPLATES; |
|
770
|
|
|
|
|
2269
|
|
|
383
|
|
|
|
|
1106
|
|
191
|
332
|
|
|
|
|
3310
|
return undef; |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub warmup { |
195
|
55
|
|
|
3072
|
1
|
176
|
my $self = shift; |
196
|
|
|
|
|
|
|
|
197
|
55
|
|
|
|
|
452
|
my ($index, $templates) = @$self{qw(index templates)} = ({}, {}); |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
# Handlers for templates |
200
|
55
|
|
|
|
|
141
|
for my $path (@{$self->paths}, $TEMPLATES) { |
|
55
|
|
|
|
|
256
|
|
201
|
763
|
|
|
|
|
5939
|
s/\.(\w+)$// and push @{$templates->{$_}}, $1 |
202
|
111
|
|
33
|
3349
|
|
529
|
for path($path)->list_tree->map(sub { join '/', @{$_->to_rel($path)} })->each; |
|
763
|
|
|
|
|
1129
|
|
|
763
|
|
|
|
|
1707
|
|
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Handlers and classes for DATA templates |
206
|
55
|
|
|
|
|
181
|
for my $class (reverse @{$self->classes}) { |
|
55
|
|
|
|
|
299
|
|
207
|
81
|
|
|
|
|
193
|
$index->{$_} = $class for my @keys = sort keys %{data_section $class}; |
|
81
|
|
|
|
|
303
|
|
208
|
81
|
|
66
|
|
|
768
|
s/\.(\w+)$// and unshift @{$templates->{$_}}, $1 for reverse @keys; |
|
202
|
|
|
|
|
1487
|
|
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
612
|
100
|
|
2336
|
|
2615
|
sub _maybe { $_[0] ? encode @_ : $_[1] } |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
sub _next { |
215
|
375
|
|
|
1668
|
|
685
|
my $stash = shift; |
216
|
375
|
100
|
|
|
|
1089
|
return delete $stash->{extends} if $stash->{extends}; |
217
|
362
|
100
|
|
|
|
1805
|
return undef unless my $layout = delete $stash->{layout}; |
218
|
33
|
|
|
|
|
210
|
return join '/', 'layouts', $layout; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub _render_template { |
222
|
576
|
|
|
1007
|
|
1402
|
my ($self, $c, $output, $options) = @_; |
223
|
|
|
|
|
|
|
|
224
|
576
|
|
100
|
|
|
2265
|
my $handler = $options->{handler} ||= $self->template_handler($options); |
225
|
576
|
100
|
|
|
|
1441
|
return undef unless $handler; |
226
|
|
|
|
|
|
|
$c->helpers->log->error(qq{No handler for "$handler" found}) and return undef |
227
|
575
|
50
|
0
|
|
|
1729
|
unless my $renderer = $self->handlers->{$handler}; |
228
|
|
|
|
|
|
|
|
229
|
575
|
|
|
|
|
2558
|
$renderer->($self, $c, $output, $options); |
230
|
555
|
100
|
|
|
|
3528
|
return 1 if defined $$output; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
1; |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=encoding utf8 |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head1 NAME |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Mojolicious::Renderer - Generate dynamic content |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=head1 SYNOPSIS |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
use Mojolicious::Renderer; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
my $renderer = Mojolicious::Renderer->new; |
246
|
|
|
|
|
|
|
push @{$renderer->classes}, 'MyApp::Controller::Foo'; |
247
|
|
|
|
|
|
|
push @{$renderer->paths}, '/home/sri/templates'; |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=head1 DESCRIPTION |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
L is the standard L renderer. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
See L for more. |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
L implements the following attributes. |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=head2 cache |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
my $cache = $renderer->cache; |
262
|
|
|
|
|
|
|
$renderer = $renderer->cache(Mojo::Cache->new); |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
Renderer cache, defaults to a L object. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 classes |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
my $classes = $renderer->classes; |
269
|
|
|
|
|
|
|
$renderer = $renderer->classes(['main']); |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
Classes to use for finding templates in C sections with L, first one has the highest precedence, |
272
|
|
|
|
|
|
|
defaults to C. Only files with exactly two extensions will be used, like C. Note that for |
273
|
|
|
|
|
|
|
templates to be detected, these classes need to have already been loaded and added before L"warmup"> is called, which |
274
|
|
|
|
|
|
|
usually happens automatically during application startup. |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# Add another class with templates in DATA section |
277
|
|
|
|
|
|
|
push @{$renderer->classes}, 'Mojolicious::Plugin::Fun'; |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# Add another class with templates in DATA section and higher precedence |
280
|
|
|
|
|
|
|
unshift @{$renderer->classes}, 'Mojolicious::Plugin::MoreFun'; |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 compress |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
my $bool = $renderer->compress; |
285
|
|
|
|
|
|
|
$renderer = $renderer->compress($bool); |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
Try to negotiate compression for dynamically generated response content and C compress it automatically, defaults |
288
|
|
|
|
|
|
|
to true. |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=head2 default_format |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
my $default = $renderer->default_format; |
293
|
|
|
|
|
|
|
$renderer = $renderer->default_format('html'); |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
The default format to render if C is not set in the stash, defaults to C. Note that changing the default |
296
|
|
|
|
|
|
|
away from C is not recommended, as it has the potential to break, for example, plugins with bundled templates. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=head2 default_handler |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
my $default = $renderer->default_handler; |
301
|
|
|
|
|
|
|
$renderer = $renderer->default_handler('ep'); |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
The default template handler to use for rendering in cases where auto-detection doesn't work, like for C |
304
|
|
|
|
|
|
|
templates. |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=head2 encoding |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
my $encoding = $renderer->encoding; |
309
|
|
|
|
|
|
|
$renderer = $renderer->encoding('koi8-r'); |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
Will encode generated content if set, defaults to C. Note that many renderers such as |
312
|
|
|
|
|
|
|
L also use this value to determine if template files should be decoded before |
313
|
|
|
|
|
|
|
processing. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=head2 handlers |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
my $handlers = $renderer->handlers; |
318
|
|
|
|
|
|
|
$renderer = $renderer->handlers({epl => sub {...}}); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
Registered handlers. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=head2 helpers |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
my $helpers = $renderer->helpers; |
325
|
|
|
|
|
|
|
$renderer = $renderer->helpers({url_for => sub {...}}); |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
Registered helpers. |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=head2 min_compress_size |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
my $size = $renderer->min_compress_size; |
332
|
|
|
|
|
|
|
$renderer = $renderer->min_compress_size(1024); |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
Minimum output size in bytes required for compression to be used if enabled, defaults to C<860>. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=head2 paths |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
my $paths = $renderer->paths; |
339
|
|
|
|
|
|
|
$renderer = $renderer->paths(['/home/sri/templates']); |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
Directories to look for templates in, first one has the highest precedence. |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
# Add another "templates" directory |
344
|
|
|
|
|
|
|
push @{$renderer->paths}, '/home/sri/templates'; |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
# Add another "templates" directory with higher precedence |
347
|
|
|
|
|
|
|
unshift @{$renderer->paths}, '/home/sri/themes/blue/templates'; |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=head1 METHODS |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
L inherits all methods from L and implements the following new ones. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=head2 accepts |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
my $all = $renderer->accepts(Mojolicious::Controller->new); |
356
|
|
|
|
|
|
|
my $best = $renderer->accepts(Mojolicious::Controller->new, 'html', 'json'); |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
Select best possible representation for L object from C C/C parameter, |
359
|
|
|
|
|
|
|
C stash value, or C request header, defaults to returning the first extension if no preference could be |
360
|
|
|
|
|
|
|
detected. |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
=head2 add_handler |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
$renderer = $renderer->add_handler(epl => sub {...}); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
Register a handler. |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
$renderer->add_handler(foo => sub ($renderer, $c, $output, $options) { |
369
|
|
|
|
|
|
|
... |
370
|
|
|
|
|
|
|
$$output = 'Hello World!'; |
371
|
|
|
|
|
|
|
}); |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head2 add_helper |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
$renderer = $renderer->add_helper(url_for => sub {...}); |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
Register a helper. |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
$renderer->add_helper(foo => sub ($c, @args) { |
380
|
|
|
|
|
|
|
... |
381
|
|
|
|
|
|
|
}); |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=head2 get_data_template |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
my $template = $renderer->get_data_template({ |
386
|
|
|
|
|
|
|
template => 'foo/bar', |
387
|
|
|
|
|
|
|
format => 'html', |
388
|
|
|
|
|
|
|
handler => 'epl' |
389
|
|
|
|
|
|
|
}); |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Return a C section template from L"classes"> for an options hash reference with C, C, |
392
|
|
|
|
|
|
|
C and C values, or C if no template could be found, usually used by handlers. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=head2 get_helper |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
my $helper = $renderer->get_helper('url_for'); |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
Get a helper by full name, generate a helper dynamically for a prefix, or return C if no helper or prefix could |
399
|
|
|
|
|
|
|
be found. Generated helpers return a proxy object containing the current controller object and on which nested helpers |
400
|
|
|
|
|
|
|
can be called. |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=head2 render |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
my ($output, $format) = $renderer->render(Mojolicious::Controller->new); |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
Render output through one of the renderers. See L for a more user-friendly interface. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=head2 respond |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
my $bool = $renderer->respond(Mojolicious::Controller->new, $output, $format); |
411
|
|
|
|
|
|
|
my $bool = $renderer->respond( |
412
|
|
|
|
|
|
|
Mojolicious::Controller->new, $output, $format, $status); |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
Finalize dynamically generated response content and L"compress"> it if possible. |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head2 template_for |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
my $name = $renderer->template_for(Mojolicious::Controller->new); |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
Return default template name for L object, or C if no name could be generated. |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=head2 template_handler |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
my $handler = $renderer->template_handler({ |
425
|
|
|
|
|
|
|
template => 'foo/bar', |
426
|
|
|
|
|
|
|
format => 'html' |
427
|
|
|
|
|
|
|
}); |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
Return handler for an options hash reference with C, C and C values, or C if no |
430
|
|
|
|
|
|
|
handler could be found. |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
=head2 template_name |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
my $template = $renderer->template_name({ |
435
|
|
|
|
|
|
|
template => 'foo/bar', |
436
|
|
|
|
|
|
|
format => 'html', |
437
|
|
|
|
|
|
|
handler => 'epl' |
438
|
|
|
|
|
|
|
}); |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Return a template name for an options hash reference with C, C, C and C values, or |
441
|
|
|
|
|
|
|
C if no template could be found, usually used by handlers. |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head2 template_path |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
my $path = $renderer->template_path({ |
446
|
|
|
|
|
|
|
template => 'foo/bar', |
447
|
|
|
|
|
|
|
format => 'html', |
448
|
|
|
|
|
|
|
handler => 'epl' |
449
|
|
|
|
|
|
|
}); |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
Return the full template path for an options hash reference with C, C, C and C |
452
|
|
|
|
|
|
|
values, or C if the file does not exist in L"paths">, usually used by handlers. |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=head2 warmup |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
$renderer->warmup; |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
Prepare templates from L"classes"> for future use. |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=head1 SEE ALSO |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
L, L, L. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=cut |