Filename | /usr/lib/x86_64-linux-gnu/perl5/5.20/Template/Context.pm |
Statements | Executed 694 statements in 5.87ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
10 | 2 | 2 | 872µs | 109ms | process (recurses: max depth 2, inclusive time 123ms) | Template::Context::
11 | 2 | 2 | 299µs | 136ms | template | Template::Context::
1 | 1 | 1 | 69µs | 12.9ms | _init | Template::Context::
7 | 7 | 5 | 64µs | 7.44ms | plugin | Template::Context::
9 | 9 | 3 | 55µs | 101ms | include (recurses: max depth 1, inclusive time 21.3ms) | Template::Context::
10 | 1 | 1 | 35µs | 35µs | visit | Template::Context::
10 | 1 | 1 | 21µs | 21µs | CORE:subst (opcode) | Template::Context::
10 | 1 | 1 | 20µs | 20µs | leave | Template::Context::
10 | 10 | 10 | 18µs | 18µs | stash | Template::Context::
1 | 1 | 1 | 18µs | 125µs | localise | Template::Context::
1 | 1 | 1 | 18µs | 29µs | BEGIN@23 | Template::Context::
1 | 1 | 1 | 12µs | 63µs | BEGIN@25 | Template::Context::
1 | 1 | 1 | 11µs | 25µs | BEGIN@34 | Template::Context::
1 | 1 | 1 | 11µs | 32µs | BEGIN@29 | Template::Context::
1 | 1 | 1 | 11µs | 40µs | BEGIN@33 | Template::Context::
1 | 1 | 1 | 10µs | 19µs | BEGIN@24 | Template::Context::
1 | 1 | 1 | 9µs | 28µs | BEGIN@31 | Template::Context::
1 | 1 | 1 | 8µs | 8µs | BEGIN@27 | Template::Context::
1 | 1 | 1 | 7µs | 7µs | BEGIN@30 | Template::Context::
1 | 1 | 1 | 7µs | 22µs | BEGIN@35 | Template::Context::
1 | 1 | 1 | 7µs | 7µs | reset | Template::Context::
1 | 1 | 1 | 6µs | 7µs | delocalise | Template::Context::
1 | 1 | 1 | 5µs | 5µs | BEGIN@28 | Template::Context::
1 | 1 | 1 | 5µs | 5µs | DESTROY | Template::Context::
0 | 0 | 0 | 0s | 0s | AUTOLOAD | Template::Context::
0 | 0 | 0 | 0s | 0s | _dump | Template::Context::
0 | 0 | 0 | 0s | 0s | catch | Template::Context::
0 | 0 | 0 | 0s | 0s | debugging | Template::Context::
0 | 0 | 0 | 0s | 0s | define_block | Template::Context::
0 | 0 | 0 | 0s | 0s | define_filter | Template::Context::
0 | 0 | 0 | 0s | 0s | define_view | Template::Context::
0 | 0 | 0 | 0s | 0s | define_views | Template::Context::
0 | 0 | 0 | 0s | 0s | define_vmethod | Template::Context::
0 | 0 | 0 | 0s | 0s | filter | Template::Context::
0 | 0 | 0 | 0s | 0s | insert | Template::Context::
0 | 0 | 0 | 0s | 0s | throw | Template::Context::
0 | 0 | 0 | 0s | 0s | view | Template::Context::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | #============================================================= -*-Perl-*- | ||||
2 | # | ||||
3 | # Template::Context | ||||
4 | # | ||||
5 | # DESCRIPTION | ||||
6 | # Module defining a context in which a template document is processed. | ||||
7 | # This is the runtime processing interface through which templates | ||||
8 | # can access the functionality of the Template Toolkit. | ||||
9 | # | ||||
10 | # AUTHOR | ||||
11 | # Andy Wardley <abw@wardley.org> | ||||
12 | # | ||||
13 | # COPYRIGHT | ||||
14 | # Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. | ||||
15 | # | ||||
16 | # This module is free software; you can redistribute it and/or | ||||
17 | # modify it under the same terms as Perl itself. | ||||
18 | # | ||||
19 | #============================================================================ | ||||
20 | |||||
21 | package Template::Context; | ||||
22 | |||||
23 | 2 | 45µs | 2 | 41µs | # spent 29µs (18+12) within Template::Context::BEGIN@23 which was called:
# once (18µs+12µs) by Template::Config::load at line 23 # spent 29µs making 1 call to Template::Context::BEGIN@23
# spent 12µs making 1 call to strict::import |
24 | 2 | 40µs | 2 | 28µs | # spent 19µs (10+9) within Template::Context::BEGIN@24 which was called:
# once (10µs+9µs) by Template::Config::load at line 24 # spent 19µs making 1 call to Template::Context::BEGIN@24
# spent 9µs making 1 call to warnings::import |
25 | 2 | 87µs | 2 | 115µs | # spent 63µs (12+51) within Template::Context::BEGIN@25 which was called:
# once (12µs+51µs) by Template::Config::load at line 25 # spent 63µs making 1 call to Template::Context::BEGIN@25
# spent 51µs making 1 call to base::import |
26 | |||||
27 | 2 | 25µs | 1 | 8µs | # spent 8µs within Template::Context::BEGIN@27 which was called:
# once (8µs+0s) by Template::Config::load at line 27 # spent 8µs making 1 call to Template::Context::BEGIN@27 |
28 | 2 | 21µs | 1 | 5µs | # spent 5µs within Template::Context::BEGIN@28 which was called:
# once (5µs+0s) by Template::Config::load at line 28 # spent 5µs making 1 call to Template::Context::BEGIN@28 |
29 | 2 | 55µs | 2 | 52µs | # spent 32µs (11+20) within Template::Context::BEGIN@29 which was called:
# once (11µs+20µs) by Template::Config::load at line 29 # spent 32µs making 1 call to Template::Context::BEGIN@29
# spent 20µs making 1 call to Exporter::import |
30 | 2 | 25µs | 1 | 7µs | # spent 7µs within Template::Context::BEGIN@30 which was called:
# once (7µs+0s) by Template::Config::load at line 30 # spent 7µs making 1 call to Template::Context::BEGIN@30 |
31 | 2 | 51µs | 2 | 46µs | # spent 28µs (9+18) within Template::Context::BEGIN@31 which was called:
# once (9µs+18µs) by Template::Config::load at line 31 # spent 28µs making 1 call to Template::Context::BEGIN@31
# spent 18µs making 1 call to Exporter::import |
32 | |||||
33 | 2 | 61µs | 2 | 69µs | # spent 40µs (11+29) within Template::Context::BEGIN@33 which was called:
# once (11µs+29µs) by Template::Config::load at line 33 # spent 40µs making 1 call to Template::Context::BEGIN@33
# spent 29µs making 1 call to constant::import |
34 | 2 | 46µs | 2 | 39µs | # spent 25µs (11+14) within Template::Context::BEGIN@34 which was called:
# once (11µs+14µs) by Template::Config::load at line 34 # spent 25µs making 1 call to Template::Context::BEGIN@34
# spent 14µs making 1 call to constant::import |
35 | 2 | 3.63ms | 2 | 36µs | # spent 22µs (7+14) within Template::Context::BEGIN@35 which was called:
# once (7µs+14µs) by Template::Config::load at line 35 # spent 22µs making 1 call to Template::Context::BEGIN@35
# spent 14µs making 1 call to constant::import |
36 | |||||
37 | 1 | 700ns | our $VERSION = 2.98; | ||
38 | 1 | 1µs | our $DEBUG = 0 unless defined $DEBUG; | ||
39 | 1 | 300ns | our $DEBUG_FORMAT = "\n## \$file line \$line : [% \$text %] ##\n"; | ||
40 | 1 | 400ns | our $VIEW_CLASS = 'Template::View'; | ||
41 | 1 | 0s | our $AUTOLOAD; | ||
42 | |||||
43 | #======================================================================== | ||||
44 | # ----- PUBLIC METHODS ----- | ||||
45 | #======================================================================== | ||||
46 | |||||
47 | #------------------------------------------------------------------------ | ||||
48 | # template($name) | ||||
49 | # | ||||
50 | # General purpose method to fetch a template and return it in compiled | ||||
51 | # form. In the usual case, the $name parameter will be a simple string | ||||
52 | # containing the name of a template (e.g. 'header'). It may also be | ||||
53 | # a reference to Template::Document object (or sub-class) or a Perl | ||||
54 | # sub-routine. These are considered to be compiled templates and are | ||||
55 | # returned intact. Finally, it may be a reference to any other kind | ||||
56 | # of valid input source accepted by Template::Provider (e.g. scalar | ||||
57 | # ref, glob, IO handle, etc). | ||||
58 | # | ||||
59 | # Templates may be cached at one of 3 different levels. The internal | ||||
60 | # BLOCKS member is a local cache which holds references to all | ||||
61 | # template blocks used or imported via PROCESS since the context's | ||||
62 | # reset() method was last called. This is checked first and if the | ||||
63 | # template is not found, the method then walks down the BLOCKSTACK | ||||
64 | # list. This contains references to the block definition tables in | ||||
65 | # any enclosing Template::Documents that we're visiting (e.g. we've | ||||
66 | # been called via an INCLUDE and we want to access a BLOCK defined in | ||||
67 | # the template that INCLUDE'd us). If nothing is defined, then we | ||||
68 | # iterate through the LOAD_TEMPLATES providers list as a 'chain of | ||||
69 | # responsibility' (see Design Patterns) asking each object to fetch() | ||||
70 | # the template if it can. | ||||
71 | # | ||||
72 | # Returns the compiled template. On error, undef is returned and | ||||
73 | # the internal ERROR value (read via error()) is set to contain an | ||||
74 | # error message of the form "$name: $error". | ||||
75 | #------------------------------------------------------------------------ | ||||
76 | |||||
77 | # spent 136ms (299µs+135) within Template::Context::template which was called 11 times, avg 12.3ms/call:
# 10 times (266µs+81.4ms) by Template::Context::process at line 309, avg 8.17ms/call
# once (33µs+53.9ms) by Template::Service::process at line 68 of Template/Service.pm | ||||
78 | 11 | 5µs | my ($self, $name) = @_; | ||
79 | 11 | 3µs | my ($prefix, $blocks, $defblocks, $provider, $template, $error); | ||
80 | my ($shortname, $blockname, $providers); | ||||
81 | |||||
82 | 11 | 5µs | $self->debug("template($name)") if $self->{ DEBUG }; | ||
83 | |||||
84 | # references to Template::Document (or sub-class) objects objects, or | ||||
85 | # CODE references are assumed to be pre-compiled templates and are | ||||
86 | # returned intact | ||||
87 | 11 | 64µs | 12 | 14µs | return $name # spent 13µs making 11 calls to Scalar::Util::blessed, avg 1µs/call
# spent 2µs making 1 call to UNIVERSAL::isa |
88 | if (blessed($name) && $name->isa(DOCUMENT)) | ||||
89 | || ref($name) eq 'CODE'; | ||||
90 | |||||
91 | 10 | 4µs | $shortname = $name; | ||
92 | |||||
93 | 10 | 4µs | unless (ref $name) { | ||
94 | |||||
95 | 10 | 5µs | $self->debug("looking for block [$name]") if $self->{ DEBUG }; | ||
96 | |||||
97 | # we first look in the BLOCKS hash for a BLOCK that may have | ||||
98 | # been imported from a template (via PROCESS) | ||||
99 | return $template | ||||
100 | 10 | 9µs | if ($template = $self->{ BLOCKS }->{ $name }); | ||
101 | |||||
102 | # then we iterate through the BLKSTACK list to see if any of the | ||||
103 | # Template::Documents we're visiting define this BLOCK | ||||
104 | 10 | 13µs | foreach $blocks (@{ $self->{ BLKSTACK } }) { | ||
105 | 13 | 16µs | return $template | ||
106 | if $blocks && ($template = $blocks->{ $name }); | ||||
107 | } | ||||
108 | |||||
109 | # now it's time to ask the providers, so we look to see if any | ||||
110 | # prefix is specified to indicate the desired provider set. | ||||
111 | 10 | 21µs | if ($^O eq 'MSWin32') { | ||
112 | # let C:/foo through | ||||
113 | $prefix = $1 if $shortname =~ s/^(\w{2,})://o; | ||||
114 | } | ||||
115 | else { | ||||
116 | 10 | 57µs | 10 | 21µs | $prefix = $1 if $shortname =~ s/^(\w+)://; # spent 21µs making 10 calls to Template::Context::CORE:subst, avg 2µs/call |
117 | } | ||||
118 | |||||
119 | 10 | 4µs | if (defined $prefix) { | ||
120 | $providers = $self->{ PREFIX_MAP }->{ $prefix } | ||||
121 | || return $self->throw( Template::Constants::ERROR_FILE, | ||||
122 | "no providers for template prefix '$prefix'"); | ||||
123 | } | ||||
124 | } | ||||
125 | $providers = $self->{ PREFIX_MAP }->{ default } | ||||
126 | || $self->{ LOAD_TEMPLATES } | ||||
127 | 10 | 20µs | unless $providers; | ||
128 | |||||
129 | |||||
130 | # Finally we try the regular template providers which will | ||||
131 | # handle references to files, text, etc., as well as templates | ||||
132 | # reference by name. If | ||||
133 | |||||
134 | 10 | 4µs | $blockname = ''; | ||
135 | 10 | 5µs | while ($shortname) { | ||
136 | $self->debug("asking providers for [$shortname] [$blockname]") | ||||
137 | 10 | 5µs | if $self->{ DEBUG }; | ||
138 | |||||
139 | 10 | 8µs | foreach my $provider (@$providers) { | ||
140 | 10 | 37µs | 10 | 135ms | ($template, $error) = $provider->fetch($shortname, $prefix); # spent 135ms making 10 calls to Template::Provider::fetch, avg 13.5ms/call |
141 | 10 | 12µs | if ($error) { | ||
142 | if ($error == Template::Constants::STATUS_ERROR) { | ||||
143 | # $template contains exception object | ||||
144 | if (blessed($template) && $template->isa(EXCEPTION) | ||||
145 | && $template->type eq Template::Constants::ERROR_FILE) { | ||||
146 | $self->throw($template); | ||||
147 | } | ||||
148 | else { | ||||
149 | $self->throw( Template::Constants::ERROR_FILE, $template ); | ||||
150 | } | ||||
151 | } | ||||
152 | # DECLINE is ok, carry on | ||||
153 | } | ||||
154 | elsif (length $blockname) { | ||||
155 | return $template | ||||
156 | if $template = $template->blocks->{ $blockname }; | ||||
157 | } | ||||
158 | else { | ||||
159 | 10 | 44µs | return $template; | ||
160 | } | ||||
161 | } | ||||
162 | |||||
163 | last if ref $shortname || ! $self->{ EXPOSE_BLOCKS }; | ||||
164 | $shortname =~ s{/([^/]+)$}{} || last; | ||||
165 | $blockname = length $blockname ? "$1/$blockname" : $1; | ||||
166 | } | ||||
167 | |||||
168 | $self->throw(Template::Constants::ERROR_FILE, "$name: not found"); | ||||
169 | } | ||||
170 | |||||
171 | |||||
172 | #------------------------------------------------------------------------ | ||||
173 | # plugin($name, \@args) | ||||
174 | # | ||||
175 | # Calls on each of the LOAD_PLUGINS providers in turn to fetch() (i.e. load | ||||
176 | # and instantiate) a plugin of the specified name. Additional parameters | ||||
177 | # passed are propagated to the new() constructor for the plugin. | ||||
178 | # Returns a reference to a new plugin object or other reference. On | ||||
179 | # error, undef is returned and the appropriate error message is set for | ||||
180 | # subsequent retrieval via error(). | ||||
181 | #------------------------------------------------------------------------ | ||||
182 | |||||
183 | # spent 7.44ms (64µs+7.37) within Template::Context::plugin which was called 7 times, avg 1.06ms/call:
# once (7µs+2.18ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 4 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
# once (12µs+2.15ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 2 of koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
# once (11µs+1.71ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc:120] at line 2 of koha-tmpl/intranet-tmpl/prog/en/includes/header.inc
# once (5µs+1.27ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 3 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
# once (9µs+22µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search-box.inc:62] at line 2 of koha-tmpl/intranet-tmpl/prog/en/includes/patron-search-box.inc
# once (10µs+20µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-open.inc:36] at line 5 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-open.inc
# once (9µs+20µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 2 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc | ||||
184 | 7 | 4µs | my ($self, $name, $args) = @_; | ||
185 | 7 | 1µs | my ($provider, $plugin, $error); | ||
186 | |||||
187 | $self->debug("plugin($name, ", defined $args ? @$args : '[ ]', ')') | ||||
188 | 7 | 4µs | if $self->{ DEBUG }; | ||
189 | |||||
190 | # request the named plugin from each of the LOAD_PLUGINS providers in turn | ||||
191 | 7 | 9µs | foreach my $provider (@{ $self->{ LOAD_PLUGINS } }) { | ||
192 | 7 | 21µs | 7 | 7.37ms | ($plugin, $error) = $provider->fetch($name, $args, $self); # spent 7.37ms making 7 calls to Template::Plugins::fetch, avg 1.05ms/call |
193 | 7 | 37µs | return $plugin unless $error; | ||
194 | if ($error == Template::Constants::STATUS_ERROR) { | ||||
195 | $self->throw($plugin) if ref $plugin; | ||||
196 | $self->throw(Template::Constants::ERROR_PLUGIN, $plugin); | ||||
197 | } | ||||
198 | } | ||||
199 | |||||
200 | $self->throw(Template::Constants::ERROR_PLUGIN, "$name: plugin not found"); | ||||
201 | } | ||||
202 | |||||
203 | |||||
204 | #------------------------------------------------------------------------ | ||||
205 | # filter($name, \@args, $alias) | ||||
206 | # | ||||
207 | # Similar to plugin() above, but querying the LOAD_FILTERS providers to | ||||
208 | # return filter instances. An alias may be provided which is used to | ||||
209 | # save the returned filter in a local cache. | ||||
210 | #------------------------------------------------------------------------ | ||||
211 | |||||
212 | sub filter { | ||||
213 | my ($self, $name, $args, $alias) = @_; | ||||
214 | my ($provider, $filter, $error); | ||||
215 | |||||
216 | $self->debug("filter($name, ", | ||||
217 | defined $args ? @$args : '[ ]', | ||||
218 | defined $alias ? $alias : '<no alias>', ')') | ||||
219 | if $self->{ DEBUG }; | ||||
220 | |||||
221 | # use any cached version of the filter if no params provided | ||||
222 | return $filter | ||||
223 | if ! $args && ! ref $name | ||||
224 | && ($filter = $self->{ FILTER_CACHE }->{ $name }); | ||||
225 | |||||
226 | # request the named filter from each of the FILTERS providers in turn | ||||
227 | foreach my $provider (@{ $self->{ LOAD_FILTERS } }) { | ||||
228 | ($filter, $error) = $provider->fetch($name, $args, $self); | ||||
229 | last unless $error; | ||||
230 | if ($error == Template::Constants::STATUS_ERROR) { | ||||
231 | $self->throw($filter) if ref $filter; | ||||
232 | $self->throw(Template::Constants::ERROR_FILTER, $filter); | ||||
233 | } | ||||
234 | # return $self->error($filter) | ||||
235 | # if $error == &Template::Constants::STATUS_ERROR; | ||||
236 | } | ||||
237 | |||||
238 | return $self->error("$name: filter not found") | ||||
239 | unless $filter; | ||||
240 | |||||
241 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||
242 | # commented out by abw on 19 Nov 2001 to fix problem with xmlstyle | ||||
243 | # plugin which may re-define a filter by calling define_filter() | ||||
244 | # multiple times. With the automatic aliasing/caching below, any | ||||
245 | # new filter definition isn't seen. Don't think this will cause | ||||
246 | # any problems as filters explicitly supplied with aliases will | ||||
247 | # still work as expected. | ||||
248 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||
249 | # alias defaults to name if undefined | ||||
250 | # $alias = $name | ||||
251 | # unless defined($alias) or ref($name) or $args; | ||||
252 | |||||
253 | # cache FILTER if alias is valid | ||||
254 | $self->{ FILTER_CACHE }->{ $alias } = $filter | ||||
255 | if $alias; | ||||
256 | |||||
257 | return $filter; | ||||
258 | } | ||||
259 | |||||
260 | |||||
261 | #------------------------------------------------------------------------ | ||||
262 | # view(\%config) | ||||
263 | # | ||||
264 | # Create a new Template::View bound to this context. | ||||
265 | #------------------------------------------------------------------------ | ||||
266 | |||||
267 | sub view { | ||||
268 | my $self = shift; | ||||
269 | require Template::View; | ||||
270 | return $VIEW_CLASS->new($self, @_) | ||||
271 | || $self->throw(&Template::Constants::ERROR_VIEW, | ||||
272 | $VIEW_CLASS->error); | ||||
273 | } | ||||
274 | |||||
275 | |||||
276 | #------------------------------------------------------------------------ | ||||
277 | # process($template, \%params) [% PROCESS template var=val ... %] | ||||
278 | # process($template, \%params, $local) [% INCLUDE template var=val ... %] | ||||
279 | # | ||||
280 | # Processes the template named or referenced by the first parameter. | ||||
281 | # The optional second parameter may reference a hash array of variable | ||||
282 | # definitions. These are set before the template is processed by | ||||
283 | # calling update() on the stash. Note that, unless the third parameter | ||||
284 | # is true, the context is not localised and these, and any other | ||||
285 | # variables set in the template will retain their new values after this | ||||
286 | # method returns. The third parameter is in place so that this method | ||||
287 | # can handle INCLUDE calls: the stash will be localized. | ||||
288 | # | ||||
289 | # Returns the output of processing the template. Errors are thrown | ||||
290 | # as Template::Exception objects via die(). | ||||
291 | #------------------------------------------------------------------------ | ||||
292 | |||||
293 | # spent 109ms (872µs+108) within Template::Context::process which was called 10 times, avg 10.9ms/call:
# 9 times (803µs+-803µs) by Template::Context::include at line 409, avg 0s/call
# once (69µs+108ms) by Template::Service::process at line 94 of Template/Service.pm | ||||
294 | 10 | 6µs | my ($self, $template, $params, $localize) = @_; | ||
295 | 10 | 15µs | my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) }; | ||
296 | 10 | 3µs | my (@compiled, $name, $compiled); | ||
297 | my ($stash, $component, $tblocks, $error, $tmpout); | ||||
298 | 10 | 3µs | my $output = ''; | ||
299 | |||||
300 | 10 | 14µs | $template = [ $template ] unless ref $template eq 'ARRAY'; | ||
301 | |||||
302 | $self->debug("process([ ", join(', '), @$template, ' ], ', | ||||
303 | defined $params ? $params : '<no params>', ', ', | ||||
304 | $localize ? '<localized>' : '<unlocalized>', ')') | ||||
305 | 10 | 7µs | if $self->{ DEBUG }; | ||
306 | |||||
307 | # fetch compiled template for each name specified | ||||
308 | 10 | 10µs | foreach $name (@$template) { | ||
309 | 10 | 40µs | 10 | 81.7ms | push(@compiled, $self->template($name)); # spent 81.7ms making 10 calls to Template::Context::template, avg 8.17ms/call |
310 | } | ||||
311 | |||||
312 | 10 | 59µs | 9 | 1.01ms | if ($localize) { # spent 1.01ms making 9 calls to Template::Stash::clone, avg 113µs/call |
313 | # localise the variable stash with any parameters passed | ||||
314 | $stash = $self->{ STASH } = $self->{ STASH }->clone($params); | ||||
315 | } else { | ||||
316 | # update stash with any new parameters passed | ||||
317 | 1 | 6µs | 1 | 5µs | $self->{ STASH }->update($params); # spent 5µs making 1 call to Template::Stash::update |
318 | 1 | 600ns | $stash = $self->{ STASH }; | ||
319 | } | ||||
320 | |||||
321 | 10 | 6µs | eval { | ||
322 | # save current component | ||||
323 | 20 | 139µs | 11 | 103µs | eval { $component = $stash->get('component') }; # spent 100µs making 10 calls to Template::Stash::XS::get, avg 10µs/call
# spent 3µs making 1 call to Template::Stash::undefined |
324 | |||||
325 | 10 | 9µs | foreach $name (@$template) { | ||
326 | 10 | 7µs | $compiled = shift @compiled; | ||
327 | 10 | 11µs | my $element = ref $compiled eq 'CODE' | ||
328 | ? { (name => (ref $name ? '' : $name), modtime => time()) } | ||||
329 | : $compiled; | ||||
330 | |||||
331 | 10 | 126µs | 19 | 49µs | if (blessed($component) && $component->isa(DOCUMENT)) { # spent 26µs making 10 calls to Scalar::Util::blessed, avg 3µs/call
# spent 23µs making 9 calls to UNIVERSAL::isa, avg 3µs/call |
332 | 9 | 14µs | $element->{ caller } = $component->{ name }; | ||
333 | 9 | 15µs | $element->{ callers } = $component->{ callers } || []; | ||
334 | 9 | 10µs | push(@{$element->{ callers }}, $element->{ caller }); | ||
335 | } | ||||
336 | |||||
337 | 10 | 73µs | 10 | 38µs | $stash->set('component', $element); # spent 38µs making 10 calls to Template::Stash::XS::set, avg 4µs/call |
338 | |||||
339 | 10 | 13µs | 3 | 4µs | unless ($localize) { # spent 2µs making 1 call to Template::Document::blocks
# spent 700ns making 1 call to Scalar::Util::blessed
# spent 600ns making 1 call to UNIVERSAL::isa |
340 | # merge any local blocks defined in the Template::Document | ||||
341 | # into our local BLOCKS cache | ||||
342 | @$blocks{ keys %$tblocks } = values %$tblocks | ||||
343 | if (blessed($compiled) && $compiled->isa(DOCUMENT)) | ||||
344 | && ($tblocks = $compiled->blocks); | ||||
345 | } | ||||
346 | |||||
347 | 10 | 40µs | 10 | 108ms | if (ref $compiled eq 'CODE') { # spent 147ms making 10 calls to Template::Document::process, avg 14.7ms/call, recursion: max depth 2, sum of overlapping time 39.0ms |
348 | $tmpout = &$compiled($self); | ||||
349 | } | ||||
350 | elsif (ref $compiled) { | ||||
351 | $tmpout = $compiled->process($self); | ||||
352 | } | ||||
353 | else { | ||||
354 | $self->throw('file', | ||||
355 | "invalid template reference: $compiled"); | ||||
356 | } | ||||
357 | |||||
358 | 10 | 3µs | if ($trim) { | ||
359 | for ($tmpout) { | ||||
360 | s/^\s+//; | ||||
361 | s/\s+$//; | ||||
362 | } | ||||
363 | } | ||||
364 | 10 | 24µs | $output .= $tmpout; | ||
365 | |||||
366 | # pop last item from callers. | ||||
367 | # NOTE - this will not be called if template throws an | ||||
368 | # error. The whole issue of caller and callers should be | ||||
369 | # revisited to try and avoid putting this info directly into | ||||
370 | # the component data structure. Perhaps use a local element | ||||
371 | # instead? | ||||
372 | |||||
373 | 10 | 86µs | 19 | 24µs | pop(@{$element->{ callers }}) # spent 17µs making 10 calls to Scalar::Util::blessed, avg 2µs/call
# spent 8µs making 9 calls to UNIVERSAL::isa, avg 867ns/call |
374 | if (blessed($component) && $component->isa(DOCUMENT)); | ||||
375 | } | ||||
376 | 10 | 54µs | 10 | 30µs | $stash->set('component', $component); # spent 30µs making 10 calls to Template::Stash::XS::set, avg 3µs/call |
377 | }; | ||||
378 | 10 | 4µs | $error = $@; | ||
379 | |||||
380 | 10 | 31µs | 9 | 22µs | if ($localize) { # spent 22µs making 9 calls to Template::Stash::declone, avg 2µs/call |
381 | # ensure stash is delocalised before dying | ||||
382 | $self->{ STASH } = $self->{ STASH }->declone(); | ||||
383 | } | ||||
384 | |||||
385 | 10 | 2µs | $self->throw(ref $error | ||
386 | ? $error : (Template::Constants::ERROR_FILE, $error)) | ||||
387 | if $error; | ||||
388 | |||||
389 | 10 | 36µs | return $output; | ||
390 | } | ||||
391 | |||||
392 | |||||
393 | #------------------------------------------------------------------------ | ||||
394 | # include($template, \%params) [% INCLUDE template var = val, ... %] | ||||
395 | # | ||||
396 | # Similar to process() above but processing the template in a local | ||||
397 | # context. Any variables passed by reference to a hash as the second | ||||
398 | # parameter will be set before the template is processed and then | ||||
399 | # revert to their original values before the method returns. Similarly, | ||||
400 | # any changes made to non-global variables within the template will | ||||
401 | # persist only until the template is processed. | ||||
402 | # | ||||
403 | # Returns the output of processing the template. Errors are thrown | ||||
404 | # as Template::Exception objects via die(). | ||||
405 | #------------------------------------------------------------------------ | ||||
406 | |||||
407 | # spent 101ms (55µs+101) within Template::Context::include which was called 9 times, avg 11.3ms/call:
# once (5µs+34.9ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 5 of koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
# once (6µs+22.5ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 194 of koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
# once (5µs+17.9ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 11 of koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
# once (5µs+15.4ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 10 of koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
# once (8µs+10.6ms) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 2 of koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt
# once (6µs+-6µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/home-search.inc:48] at line 5 of koha-tmpl/intranet-tmpl/prog/en/includes/home-search.inc
# once (4µs+-4µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 30 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
# once (7µs+-7µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 90 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc
# once (8µs+-8µs) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 11 of koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc | ||||
408 | 9 | 6µs | my ($self, $template, $params) = @_; | ||
409 | 9 | 263µs | 18 | 15µs | return $self->process($template, $params, 'localize me!'); # spent 15µs making 9 calls to Template::Stash::XS::DESTROY, avg 2µs/call
# spent 123ms making 9 calls to Template::Context::process, avg 13.6ms/call, recursion: max depth 2, sum of overlapping time 123ms |
410 | } | ||||
411 | |||||
412 | #------------------------------------------------------------------------ | ||||
413 | # insert($file) | ||||
414 | # | ||||
415 | # Insert the contents of a file without parsing. | ||||
416 | #------------------------------------------------------------------------ | ||||
417 | |||||
418 | sub insert { | ||||
419 | my ($self, $file) = @_; | ||||
420 | my ($prefix, $providers, $text, $error); | ||||
421 | my $output = ''; | ||||
422 | |||||
423 | my $files = ref $file eq 'ARRAY' ? $file : [ $file ]; | ||||
424 | |||||
425 | $self->debug("insert([ ", join(', '), @$files, " ])") | ||||
426 | if $self->{ DEBUG }; | ||||
427 | |||||
428 | |||||
429 | FILE: foreach $file (@$files) { | ||||
430 | my $name = $file; | ||||
431 | |||||
432 | if ($^O eq 'MSWin32') { | ||||
433 | # let C:/foo through | ||||
434 | $prefix = $1 if $name =~ s/^(\w{2,})://o; | ||||
435 | } | ||||
436 | else { | ||||
437 | $prefix = $1 if $name =~ s/^(\w+)://; | ||||
438 | } | ||||
439 | |||||
440 | if (defined $prefix) { | ||||
441 | $providers = $self->{ PREFIX_MAP }->{ $prefix } | ||||
442 | || return $self->throw(Template::Constants::ERROR_FILE, | ||||
443 | "no providers for file prefix '$prefix'"); | ||||
444 | } | ||||
445 | else { | ||||
446 | $providers = $self->{ PREFIX_MAP }->{ default } | ||||
447 | || $self->{ LOAD_TEMPLATES }; | ||||
448 | } | ||||
449 | |||||
450 | foreach my $provider (@$providers) { | ||||
451 | ($text, $error) = $provider->load($name, $prefix); | ||||
452 | next FILE unless $error; | ||||
453 | if ($error == Template::Constants::STATUS_ERROR) { | ||||
454 | $self->throw($text) if ref $text; | ||||
455 | $self->throw(Template::Constants::ERROR_FILE, $text); | ||||
456 | } | ||||
457 | } | ||||
458 | $self->throw(Template::Constants::ERROR_FILE, "$file: not found"); | ||||
459 | } | ||||
460 | continue { | ||||
461 | $output .= $text; | ||||
462 | } | ||||
463 | return $output; | ||||
464 | } | ||||
465 | |||||
466 | |||||
467 | #------------------------------------------------------------------------ | ||||
468 | # throw($type, $info, \$output) [% THROW errtype "Error info" %] | ||||
469 | # | ||||
470 | # Throws a Template::Exception object by calling die(). This method | ||||
471 | # may be passed a reference to an existing Template::Exception object; | ||||
472 | # a single value containing an error message which is used to | ||||
473 | # instantiate a Template::Exception of type 'undef'; or a pair of | ||||
474 | # values representing the exception type and info from which a | ||||
475 | # Template::Exception object is instantiated. e.g. | ||||
476 | # | ||||
477 | # $context->throw($exception); | ||||
478 | # $context->throw("I'm sorry Dave, I can't do that"); | ||||
479 | # $context->throw('denied', "I'm sorry Dave, I can't do that"); | ||||
480 | # | ||||
481 | # An optional third parameter can be supplied in the last case which | ||||
482 | # is a reference to the current output buffer containing the results | ||||
483 | # of processing the template up to the point at which the exception | ||||
484 | # was thrown. The RETURN and STOP directives, for example, use this | ||||
485 | # to propagate output back to the user, but it can safely be ignored | ||||
486 | # in most cases. | ||||
487 | # | ||||
488 | # This method rides on a one-way ticket to die() oblivion. It does not | ||||
489 | # return in any real sense of the word, but should get caught by a | ||||
490 | # surrounding eval { } block (e.g. a BLOCK or TRY) and handled | ||||
491 | # accordingly, or returned to the caller as an uncaught exception. | ||||
492 | #------------------------------------------------------------------------ | ||||
493 | |||||
494 | sub throw { | ||||
495 | my ($self, $error, $info, $output) = @_; | ||||
496 | local $" = ', '; | ||||
497 | |||||
498 | # die! die! die! | ||||
499 | if (blessed($error) && $error->isa(EXCEPTION)) { | ||||
500 | die $error; | ||||
501 | } | ||||
502 | elsif (blessed($error) && $error->isa(BADGER_EXCEPTION)) { | ||||
503 | # convert a Badger::Exception to a Template::Exception so that | ||||
504 | # things continue to work during the transition to Badger | ||||
505 | die EXCEPTION->new($error->type, $error->info); | ||||
506 | } | ||||
507 | elsif (defined $info) { | ||||
508 | die (EXCEPTION->new($error, $info, $output)); | ||||
509 | } | ||||
510 | else { | ||||
511 | $error ||= ''; | ||||
512 | die (EXCEPTION->new('undef', $error, $output)); | ||||
513 | } | ||||
514 | |||||
515 | # not reached | ||||
516 | } | ||||
517 | |||||
518 | |||||
519 | #------------------------------------------------------------------------ | ||||
520 | # catch($error, \$output) | ||||
521 | # | ||||
522 | # Called by various directives after catching an error thrown via die() | ||||
523 | # from within an eval { } block. The first parameter contains the errror | ||||
524 | # which may be a sanitized reference to a Template::Exception object | ||||
525 | # (such as that raised by the throw() method above, a plugin object, | ||||
526 | # and so on) or an error message thrown via die from somewhere in user | ||||
527 | # code. The latter are coerced into 'undef' Template::Exception objects. | ||||
528 | # Like throw() above, a reference to a scalar may be passed as an | ||||
529 | # additional parameter to represent the current output buffer | ||||
530 | # localised within the eval block. As exceptions are thrown upwards | ||||
531 | # and outwards from nested blocks, the catch() method reconstructs the | ||||
532 | # correct output buffer from these fragments, storing it in the | ||||
533 | # exception object for passing further onwards and upwards. | ||||
534 | # | ||||
535 | # Returns a reference to a Template::Exception object.. | ||||
536 | #------------------------------------------------------------------------ | ||||
537 | |||||
538 | sub catch { | ||||
539 | my ($self, $error, $output) = @_; | ||||
540 | |||||
541 | if ( blessed($error) | ||||
542 | && ( $error->isa(EXCEPTION) || $error->isa(BADGER_EXCEPTION) ) ) { | ||||
543 | $error->text($output) if $output; | ||||
544 | return $error; | ||||
545 | } | ||||
546 | else { | ||||
547 | return EXCEPTION->new('undef', $error, $output); | ||||
548 | } | ||||
549 | } | ||||
550 | |||||
551 | |||||
552 | #------------------------------------------------------------------------ | ||||
553 | # localise(\%params) | ||||
554 | # delocalise() | ||||
555 | # | ||||
556 | # The localise() method creates a local copy of the current stash, | ||||
557 | # allowing the existing state of variables to be saved and later | ||||
558 | # restored via delocalise(). | ||||
559 | # | ||||
560 | # A reference to a hash array may be passed containing local variable | ||||
561 | # definitions which should be added to the cloned namespace. These | ||||
562 | # values persist until delocalisation. | ||||
563 | #------------------------------------------------------------------------ | ||||
564 | |||||
565 | # spent 125µs (18+107) within Template::Context::localise which was called:
# once (18µs+107µs) by Template::Service::process at line 78 of Template/Service.pm | ||||
566 | 1 | 300ns | my $self = shift; | ||
567 | 1 | 16µs | 1 | 107µs | $self->{ STASH } = $self->{ STASH }->clone(@_); # spent 107µs making 1 call to Template::Stash::clone |
568 | } | ||||
569 | |||||
570 | # spent 7µs (6+1) within Template::Context::delocalise which was called:
# once (6µs+1µs) by Template::Service::process at line 124 of Template/Service.pm | ||||
571 | 1 | 400ns | my $self = shift; | ||
572 | 1 | 5µs | 1 | 1µs | $self->{ STASH } = $self->{ STASH }->declone(); # spent 1µs making 1 call to Template::Stash::declone |
573 | } | ||||
574 | |||||
575 | |||||
576 | #------------------------------------------------------------------------ | ||||
577 | # visit($document, $blocks) | ||||
578 | # | ||||
579 | # Each Template::Document calls the visit() method on the context | ||||
580 | # before processing itself. It passes a reference to the hash array | ||||
581 | # of named BLOCKs defined within the document, allowing them to be | ||||
582 | # added to the internal BLKSTACK list which is subsequently used by | ||||
583 | # template() to resolve templates. | ||||
584 | # from a provider. | ||||
585 | #------------------------------------------------------------------------ | ||||
586 | |||||
587 | # spent 35µs within Template::Context::visit which was called 10 times, avg 4µs/call:
# 10 times (35µs+0s) by Template::Document::process at line 158 of Template/Document.pm, avg 4µs/call | ||||
588 | 10 | 5µs | my ($self, $document, $blocks) = @_; | ||
589 | 10 | 37µs | unshift(@{ $self->{ BLKSTACK } }, $blocks) | ||
590 | } | ||||
591 | |||||
592 | |||||
593 | #------------------------------------------------------------------------ | ||||
594 | # leave() | ||||
595 | # | ||||
596 | # The leave() method is called when the document has finished | ||||
597 | # processing itself. This removes the entry from the BLKSTACK list | ||||
598 | # that was added visit() above. For persistence of BLOCK definitions, | ||||
599 | # the process() method (i.e. the PROCESS directive) does some extra | ||||
600 | # magic to copy BLOCKs into a shared hash. | ||||
601 | #------------------------------------------------------------------------ | ||||
602 | |||||
603 | # spent 20µs within Template::Context::leave which was called 10 times, avg 2µs/call:
# 10 times (20µs+0s) by Template::Document::process at line 167 of Template/Document.pm, avg 2µs/call | ||||
604 | 10 | 3µs | my $self = shift; | ||
605 | 10 | 29µs | shift(@{ $self->{ BLKSTACK } }); | ||
606 | } | ||||
607 | |||||
608 | |||||
609 | #------------------------------------------------------------------------ | ||||
610 | # define_block($name, $block) | ||||
611 | # | ||||
612 | # Adds a new BLOCK definition to the local BLOCKS cache. $block may | ||||
613 | # be specified as a reference to a sub-routine or Template::Document | ||||
614 | # object or as text which is compiled into a template. Returns a true | ||||
615 | # value (the $block reference or compiled block reference) if | ||||
616 | # successful or undef on failure. Call error() to retrieve the | ||||
617 | # relevent error message (i.e. compilation failure). | ||||
618 | #------------------------------------------------------------------------ | ||||
619 | |||||
620 | sub define_block { | ||||
621 | my ($self, $name, $block) = @_; | ||||
622 | $block = $self->template(\$block) | ||||
623 | || return undef | ||||
624 | unless ref $block; | ||||
625 | $self->{ BLOCKS }->{ $name } = $block; | ||||
626 | } | ||||
627 | |||||
628 | |||||
629 | #------------------------------------------------------------------------ | ||||
630 | # define_filter($name, $filter, $is_dynamic) | ||||
631 | # | ||||
632 | # Adds a new FILTER definition to the local FILTER_CACHE. | ||||
633 | #------------------------------------------------------------------------ | ||||
634 | |||||
635 | sub define_filter { | ||||
636 | my ($self, $name, $filter, $is_dynamic) = @_; | ||||
637 | my ($result, $error); | ||||
638 | $filter = [ $filter, 1 ] if $is_dynamic; | ||||
639 | |||||
640 | foreach my $provider (@{ $self->{ LOAD_FILTERS } }) { | ||||
641 | ($result, $error) = $provider->store($name, $filter); | ||||
642 | return 1 unless $error; | ||||
643 | $self->throw(&Template::Constants::ERROR_FILTER, $result) | ||||
644 | if $error == &Template::Constants::STATUS_ERROR; | ||||
645 | } | ||||
646 | $self->throw(&Template::Constants::ERROR_FILTER, | ||||
647 | "FILTER providers declined to store filter $name"); | ||||
648 | } | ||||
649 | |||||
650 | |||||
651 | #------------------------------------------------------------------------ | ||||
652 | # define_vmethod($type, $name, \&sub) | ||||
653 | # | ||||
654 | # Passes $type, $name, and &sub on to stash->define_vmethod(). | ||||
655 | #------------------------------------------------------------------------ | ||||
656 | |||||
657 | sub define_vmethod { | ||||
658 | my $self = shift; | ||||
659 | $self->stash->define_vmethod(@_); | ||||
660 | } | ||||
661 | |||||
662 | |||||
663 | #------------------------------------------------------------------------ | ||||
664 | # define_view($name, $params) | ||||
665 | # | ||||
666 | # Defines a new view. | ||||
667 | #------------------------------------------------------------------------ | ||||
668 | |||||
669 | sub define_view { | ||||
670 | my ($self, $name, $params) = @_; | ||||
671 | my $base; | ||||
672 | |||||
673 | if (defined $params->{ base }) { | ||||
674 | my $base = $self->{ STASH }->get($params->{ base }); | ||||
675 | |||||
676 | return $self->throw( | ||||
677 | &Template::Constants::ERROR_VIEW, | ||||
678 | "view base is not defined: $params->{ base }" | ||||
679 | ) unless $base; | ||||
680 | |||||
681 | return $self->throw( | ||||
682 | &Template::Constants::ERROR_VIEW, | ||||
683 | "view base is not a $VIEW_CLASS object: $params->{ base } => $base" | ||||
684 | ) unless blessed($base) && $base->isa($VIEW_CLASS); | ||||
685 | |||||
686 | $params->{ base } = $base; | ||||
687 | } | ||||
688 | my $view = $self->view($params); | ||||
689 | $view->seal(); | ||||
690 | $self->{ STASH }->set($name, $view); | ||||
691 | } | ||||
692 | |||||
693 | |||||
694 | #------------------------------------------------------------------------ | ||||
695 | # define_views($views) | ||||
696 | # | ||||
697 | # Defines multiple new views. | ||||
698 | #------------------------------------------------------------------------ | ||||
699 | |||||
700 | sub define_views { | ||||
701 | my ($self, $views) = @_; | ||||
702 | |||||
703 | # a list reference is better because the order is deterministic (and so | ||||
704 | # allows an earlier VIEW to be the base for a later VIEW), but we'll | ||||
705 | # accept a hash reference and assume that the user knows the order of | ||||
706 | # processing is undefined | ||||
707 | $views = [ %$views ] | ||||
708 | if ref $views eq 'HASH'; | ||||
709 | |||||
710 | # make of copy so we don't destroy the original list reference | ||||
711 | my @items = @$views; | ||||
712 | my ($name, $view); | ||||
713 | |||||
714 | while (@items) { | ||||
715 | $self->define_view(splice(@items, 0, 2)); | ||||
716 | } | ||||
717 | } | ||||
718 | |||||
719 | |||||
720 | #------------------------------------------------------------------------ | ||||
721 | # reset() | ||||
722 | # | ||||
723 | # Reset the state of the internal BLOCKS hash to clear any BLOCK | ||||
724 | # definitions imported via the PROCESS directive. Any original | ||||
725 | # BLOCKS definitions passed to the constructor will be restored. | ||||
726 | #------------------------------------------------------------------------ | ||||
727 | |||||
728 | # spent 7µs within Template::Context::reset which was called:
# once (7µs+0s) by Template::Service::process at line 64 of Template/Service.pm | ||||
729 | 1 | 400ns | my ($self, $blocks) = @_; | ||
730 | 1 | 2µs | $self->{ BLKSTACK } = [ ]; | ||
731 | 1 | 6µs | $self->{ BLOCKS } = { %{ $self->{ INIT_BLOCKS } } }; | ||
732 | } | ||||
733 | |||||
734 | |||||
735 | #------------------------------------------------------------------------ | ||||
736 | # stash() | ||||
737 | # | ||||
738 | # Simple accessor methods to return the STASH values. This is likely | ||||
739 | # to be called quite often so we provide a direct method rather than | ||||
740 | # relying on the slower AUTOLOAD. | ||||
741 | #------------------------------------------------------------------------ | ||||
742 | |||||
743 | # spent 18µs within Template::Context::stash which was called 10 times, avg 2µs/call:
# once (2µs+0s) by Template::Document::__ANON__[(eval 1136)[/usr/lib/x86_64-linux-gnu/perl5/5.20/Template/Document.pm:78]:16] at line 3 of (eval 1136)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/home-search.inc:48] at line 3 of (eval 1138)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search-box.inc:62] at line 3 of (eval 1139)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/header.inc:120] at line 3 of (eval 1137)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/intranet-bottom.inc:94] at line 3 of (eval 1140)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-open.inc:36] at line 3 of (eval 1132)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/doc-head-close.inc:99] at line 3 of (eval 1133)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/includes/intranetstylesheet.inc:28] at line 3 of (eval 1134)[Template/Document.pm:78]
# once (2µs+0s) by Template::Document::__ANON__[/home/vagrant/kohaclone/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt:203] at line 3 of (eval 1131)[Template/Document.pm:78]
# once (1µs+0s) by Template::Document::__ANON__[(eval 1135)[/usr/lib/x86_64-linux-gnu/perl5/5.20/Template/Document.pm:78]:16] at line 3 of (eval 1135)[Template/Document.pm:78] | ||||
744 | 10 | 48µs | return $_[0]->{ STASH }; | ||
745 | } | ||||
746 | |||||
747 | |||||
748 | #------------------------------------------------------------------------ | ||||
749 | # debugging($command, @args, \%params) | ||||
750 | # | ||||
751 | # Method for controlling the debugging status of the context. The first | ||||
752 | # argument can be 'on' or 'off' to enable/disable debugging, 'format' | ||||
753 | # to define the format of the debug message, or 'msg' to generate a | ||||
754 | # debugging message reporting the file, line, message text, etc., | ||||
755 | # according to the current debug format. | ||||
756 | #------------------------------------------------------------------------ | ||||
757 | |||||
758 | sub debugging { | ||||
759 | my $self = shift; | ||||
760 | my $hash = ref $_[-1] eq 'HASH' ? pop : { }; | ||||
761 | my @args = @_; | ||||
762 | |||||
763 | if (@args) { | ||||
764 | if ($args[0] =~ /^on|1$/i) { | ||||
765 | $self->{ DEBUG_DIRS } = 1; | ||||
766 | shift(@args); | ||||
767 | } | ||||
768 | elsif ($args[0] =~ /^off|0$/i) { | ||||
769 | $self->{ DEBUG_DIRS } = 0; | ||||
770 | shift(@args); | ||||
771 | } | ||||
772 | } | ||||
773 | |||||
774 | if (@args) { | ||||
775 | if ($args[0] =~ /^msg$/i) { | ||||
776 | return unless $self->{ DEBUG_DIRS }; | ||||
777 | my $format = $self->{ DEBUG_FORMAT }; | ||||
778 | $format = $DEBUG_FORMAT unless defined $format; | ||||
779 | $format =~ s/\$(\w+)/$hash->{ $1 }/ge; | ||||
780 | return $format; | ||||
781 | } | ||||
782 | elsif ($args[0] =~ /^format$/i) { | ||||
783 | $self->{ DEBUG_FORMAT } = $args[1]; | ||||
784 | } | ||||
785 | # else ignore | ||||
786 | } | ||||
787 | |||||
788 | return ''; | ||||
789 | } | ||||
790 | |||||
791 | |||||
792 | #------------------------------------------------------------------------ | ||||
793 | # AUTOLOAD | ||||
794 | # | ||||
795 | # Provides pseudo-methods for read-only access to various internal | ||||
796 | # members. For example, templates(), plugins(), filters(), | ||||
797 | # eval_perl(), load_perl(), etc. These aren't called very often, or | ||||
798 | # may never be called at all. | ||||
799 | #------------------------------------------------------------------------ | ||||
800 | |||||
801 | sub AUTOLOAD { | ||||
802 | my $self = shift; | ||||
803 | my $method = $AUTOLOAD; | ||||
804 | my $result; | ||||
805 | |||||
806 | $method =~ s/.*:://; | ||||
807 | return if $method eq 'DESTROY'; | ||||
808 | |||||
809 | warn "no such context method/member: $method\n" | ||||
810 | unless defined ($result = $self->{ uc $method }); | ||||
811 | |||||
812 | return $result; | ||||
813 | } | ||||
814 | |||||
815 | |||||
816 | #------------------------------------------------------------------------ | ||||
817 | # DESTROY | ||||
818 | # | ||||
819 | # Stash may contain references back to the Context via macro closures, | ||||
820 | # etc. This breaks the circular references. | ||||
821 | #------------------------------------------------------------------------ | ||||
822 | |||||
823 | # spent 5µs within Template::Context::DESTROY which was called:
# once (5µs+0s) by CGI::Compile::ROOT::home_vagrant_kohaclone_mainpage_2epl::__ANON__[/home/vagrant/kohaclone/mainpage.pl:107] at line 2 of mainpage.pl | ||||
824 | 1 | 700ns | my $self = shift; | ||
825 | 1 | 6µs | undef $self->{ STASH }; | ||
826 | } | ||||
827 | |||||
- - | |||||
830 | #======================================================================== | ||||
831 | # -- PRIVATE METHODS -- | ||||
832 | #======================================================================== | ||||
833 | |||||
834 | #------------------------------------------------------------------------ | ||||
835 | # _init(\%config) | ||||
836 | # | ||||
837 | # Initialisation method called by Template::Base::new() | ||||
838 | #------------------------------------------------------------------------ | ||||
839 | |||||
840 | # spent 12.9ms (69µs+12.8) within Template::Context::_init which was called:
# once (69µs+12.8ms) by Template::Base::new at line 65 of Template/Base.pm | ||||
841 | 1 | 600ns | my ($self, $config) = @_; | ||
842 | 1 | 100ns | my ($name, $item, $method, $block, $blocks); | ||
843 | 1 | 1µs | my @itemlut = ( | ||
844 | LOAD_TEMPLATES => 'provider', | ||||
845 | LOAD_PLUGINS => 'plugins', | ||||
846 | LOAD_FILTERS => 'filters' | ||||
847 | ); | ||||
848 | |||||
849 | # LOAD_TEMPLATE, LOAD_PLUGINS, LOAD_FILTERS - lists of providers | ||||
850 | 1 | 1µs | while (($name, $method) = splice(@itemlut, 0, 2)) { | ||
851 | 3 | 10µs | 3 | 5.34ms | $item = $config->{ $name } # spent 3.75ms making 1 call to Template::Config::filters
# spent 1.50ms making 1 call to Template::Config::plugins
# spent 81µs making 1 call to Template::Config::provider |
852 | || Template::Config->$method($config) | ||||
853 | || return $self->error($Template::Config::ERROR); | ||||
854 | 3 | 10µs | $self->{ $name } = ref $item eq 'ARRAY' ? $item : [ $item ]; | ||
855 | } | ||||
856 | |||||
857 | 1 | 800ns | my $providers = $self->{ LOAD_TEMPLATES }; | ||
858 | 1 | 2µs | my $prefix_map = $self->{ PREFIX_MAP } = $config->{ PREFIX_MAP } || { }; | ||
859 | 1 | 2µs | while (my ($key, $val) = each %$prefix_map) { | ||
860 | $prefix_map->{ $key } = [ ref $val ? $val : | ||||
861 | map { $providers->[$_] } split(/\D+/, $val) ] | ||||
862 | unless ref $val eq 'ARRAY'; | ||||
863 | } | ||||
864 | |||||
865 | # STASH | ||||
866 | 1 | 2µs | $self->{ STASH } = $config->{ STASH } || do { | ||
867 | my $predefs = $config->{ VARIABLES } | ||||
868 | || $config->{ PRE_DEFINE } | ||||
869 | 1 | 2µs | || { }; | ||
870 | |||||
871 | # hack to get stash to know about debug mode | ||||
872 | $predefs->{ _DEBUG } = ( ($config->{ DEBUG } || 0) | ||||
873 | & &Template::Constants::DEBUG_UNDEF ) ? 1 : 0 | ||||
874 | 1 | 6µs | 1 | 1µs | unless defined $predefs->{ _DEBUG }; # spent 1µs making 1 call to Template::Constants::DEBUG_UNDEF |
875 | 1 | 700ns | $predefs->{ _STRICT } = $config->{ STRICT }; | ||
876 | |||||
877 | 1 | 4µs | 1 | 7.50ms | Template::Config->stash($predefs) # spent 7.50ms making 1 call to Template::Config::stash |
878 | || return $self->error($Template::Config::ERROR); | ||||
879 | }; | ||||
880 | |||||
881 | # compile any template BLOCKS specified as text | ||||
882 | 1 | 1µs | $blocks = $config->{ BLOCKS } || { }; | ||
883 | $self->{ INIT_BLOCKS } = $self->{ BLOCKS } = { | ||||
884 | map { | ||||
885 | 1 | 4µs | $block = $blocks->{ $_ }; | ||
886 | $block = $self->template(\$block) | ||||
887 | || return undef | ||||
888 | unless ref $block; | ||||
889 | ($_ => $block); | ||||
890 | } | ||||
891 | keys %$blocks | ||||
892 | }; | ||||
893 | |||||
894 | # define any VIEWS | ||||
895 | $self->define_views( $config->{ VIEWS } ) | ||||
896 | 1 | 1µs | if $config->{ VIEWS }; | ||
897 | |||||
898 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||
899 | # RECURSION - flag indicating is recursion into templates is supported | ||||
900 | # EVAL_PERL - flag indicating if PERL blocks should be processed | ||||
901 | # TRIM - flag to remove leading and trailing whitespace from output | ||||
902 | # BLKSTACK - list of hashes of BLOCKs defined in current template(s) | ||||
903 | # CONFIG - original configuration hash | ||||
904 | # EXPOSE_BLOCKS - make blocks visible as pseudo-files | ||||
905 | # DEBUG_FORMAT - format for generating template runtime debugging messages | ||||
906 | # DEBUG - format for generating template runtime debugging messages | ||||
907 | |||||
908 | 1 | 1µs | $self->{ RECURSION } = $config->{ RECURSION } || 0; | ||
909 | 1 | 900ns | $self->{ EVAL_PERL } = $config->{ EVAL_PERL } || 0; | ||
910 | 1 | 700ns | $self->{ TRIM } = $config->{ TRIM } || 0; | ||
911 | 1 | 700ns | $self->{ BLKSTACK } = [ ]; | ||
912 | 1 | 500ns | $self->{ CONFIG } = $config; | ||
913 | $self->{ EXPOSE_BLOCKS } = defined $config->{ EXPOSE_BLOCKS } | ||||
914 | ? $config->{ EXPOSE_BLOCKS } | ||||
915 | 1 | 900ns | : 0; | ||
916 | |||||
917 | 1 | 1µs | $self->{ DEBUG_FORMAT } = $config->{ DEBUG_FORMAT }; | ||
918 | 1 | 2µs | $self->{ DEBUG_DIRS } = ($config->{ DEBUG } || 0) | ||
919 | & Template::Constants::DEBUG_DIRS; | ||||
920 | $self->{ DEBUG } = defined $config->{ DEBUG } | ||||
921 | 1 | 1µs | ? $config->{ DEBUG } & ( Template::Constants::DEBUG_CONTEXT | ||
922 | | Template::Constants::DEBUG_FLAGS ) | ||||
923 | : $DEBUG; | ||||
924 | |||||
925 | 1 | 5µs | return $self; | ||
926 | } | ||||
927 | |||||
928 | |||||
929 | #------------------------------------------------------------------------ | ||||
930 | # _dump() | ||||
931 | # | ||||
932 | # Debug method which returns a string representing the internal state | ||||
933 | # of the context object. | ||||
934 | #------------------------------------------------------------------------ | ||||
935 | |||||
936 | sub _dump { | ||||
937 | my $self = shift; | ||||
938 | my $output = "[Template::Context] {\n"; | ||||
939 | my $format = " %-16s => %s\n"; | ||||
940 | my $key; | ||||
941 | |||||
942 | foreach $key (qw( RECURSION EVAL_PERL TRIM )) { | ||||
943 | $output .= sprintf($format, $key, $self->{ $key }); | ||||
944 | } | ||||
945 | foreach my $pname (qw( LOAD_TEMPLATES LOAD_PLUGINS LOAD_FILTERS )) { | ||||
946 | my $provtext = "[\n"; | ||||
947 | foreach my $prov (@{ $self->{ $pname } }) { | ||||
948 | $provtext .= $prov->_dump(); | ||||
949 | # $provtext .= ",\n"; | ||||
950 | } | ||||
951 | $provtext =~ s/\n/\n /g; | ||||
952 | $provtext =~ s/\s+$//; | ||||
953 | $provtext .= ",\n ]"; | ||||
954 | $output .= sprintf($format, $pname, $provtext); | ||||
955 | } | ||||
956 | $output .= sprintf($format, STASH => $self->{ STASH }->_dump()); | ||||
957 | $output .= '}'; | ||||
958 | return $output; | ||||
959 | } | ||||
960 | |||||
961 | |||||
962 | 1 | 6µs | 1; | ||
963 | |||||
964 | __END__ | ||||
# spent 21µs within Template::Context::CORE:subst which was called 10 times, avg 2µs/call:
# 10 times (21µs+0s) by Template::Context::template at line 116, avg 2µs/call |