Filename | /usr/lib/perl5/Template/Context.pm |
Statements | Executed 2760 statements in 11.6ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
214 | 15 | 4 | 3.19ms | 5.57ms | filter | Template::Context::
10 | 2 | 2 | 2.09ms | 642ms | template | Template::Context::
9 | 2 | 2 | 1.63ms | 322ms | process (recurses: max depth 1, inclusive time 290ms) | Template::Context::
8 | 7 | 1 | 142µs | 290ms | include | Template::Context::
1 | 1 | 1 | 119µs | 15.1ms | _init | Template::Context::
9 | 1 | 1 | 57µs | 57µs | leave | Template::Context::
9 | 1 | 1 | 55µs | 55µs | visit | Template::Context::
9 | 8 | 8 | 39µs | 39µs | stash | Template::Context::
9 | 1 | 1 | 28µs | 28µs | CORE:subst (opcode) | Template::Context::
1 | 1 | 1 | 26µs | 205µs | localise | Template::Context::
1 | 1 | 1 | 25µs | 31µs | BEGIN@23 | Template::Context::
1 | 1 | 1 | 21µs | 86µs | BEGIN@31 | Template::Context::
1 | 1 | 1 | 19µs | 24µs | delocalise | Template::Context::
1 | 1 | 1 | 19µs | 19µs | BEGIN@30 | Template::Context::
1 | 1 | 1 | 18µs | 56µs | BEGIN@29 | Template::Context::
1 | 1 | 1 | 15µs | 38µs | BEGIN@24 | Template::Context::
1 | 1 | 1 | 14µs | 14µs | DESTROY | Template::Context::
1 | 1 | 1 | 14µs | 77µs | BEGIN@33 | Template::Context::
1 | 1 | 1 | 13µs | 102µs | BEGIN@25 | Template::Context::
1 | 1 | 1 | 12µs | 12µs | reset | Template::Context::
1 | 1 | 1 | 11µs | 11µs | BEGIN@27 | Template::Context::
1 | 1 | 1 | 11µs | 74µs | BEGIN@35 | Template::Context::
1 | 1 | 1 | 10µs | 43µs | BEGIN@34 | Template::Context::
1 | 1 | 1 | 7µs | 7µs | BEGIN@28 | 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 | insert | Template::Context::
0 | 0 | 0 | 0s | 0s | plugin | 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 | 3 | 33µs | 2 | 38µs | # spent 31µs (25+7) within Template::Context::BEGIN@23 which was called:
# once (25µs+7µs) by Template::Config::load at line 23 # spent 31µs making 1 call to Template::Context::BEGIN@23
# spent 7µs making 1 call to strict::import |
24 | 3 | 33µs | 2 | 61µs | # spent 38µs (15+23) within Template::Context::BEGIN@24 which was called:
# once (15µs+23µs) by Template::Config::load at line 24 # spent 38µs making 1 call to Template::Context::BEGIN@24
# spent 23µs making 1 call to warnings::import |
25 | 3 | 38µs | 2 | 191µs | # spent 102µs (13+89) within Template::Context::BEGIN@25 which was called:
# once (13µs+89µs) by Template::Config::load at line 25 # spent 102µs making 1 call to Template::Context::BEGIN@25
# spent 89µs making 1 call to base::import |
26 | |||||
27 | 3 | 29µs | 1 | 11µs | # spent 11µs within Template::Context::BEGIN@27 which was called:
# once (11µs+0s) by Template::Config::load at line 27 # spent 11µs making 1 call to Template::Context::BEGIN@27 |
28 | 3 | 28µs | 1 | 7µs | # spent 7µs within Template::Context::BEGIN@28 which was called:
# once (7µs+0s) by Template::Config::load at line 28 # spent 7µs making 1 call to Template::Context::BEGIN@28 |
29 | 3 | 46µs | 2 | 93µs | # spent 56µs (18+38) within Template::Context::BEGIN@29 which was called:
# once (18µs+38µs) by Template::Config::load at line 29 # spent 56µs making 1 call to Template::Context::BEGIN@29
# spent 38µs making 1 call to Exporter::import |
30 | 3 | 53µs | 1 | 19µs | # spent 19µs within Template::Context::BEGIN@30 which was called:
# once (19µs+0s) by Template::Config::load at line 30 # spent 19µs making 1 call to Template::Context::BEGIN@30 |
31 | 3 | 106µs | 2 | 150µs | # spent 86µs (21+64) within Template::Context::BEGIN@31 which was called:
# once (21µs+64µs) by Template::Config::load at line 31 # spent 86µs making 1 call to Template::Context::BEGIN@31
# spent 64µs making 1 call to Exporter::import |
32 | |||||
33 | 3 | 37µs | 2 | 140µs | # spent 77µs (14+63) within Template::Context::BEGIN@33 which was called:
# once (14µs+63µs) by Template::Config::load at line 33 # spent 77µs making 1 call to Template::Context::BEGIN@33
# spent 63µs making 1 call to constant::import |
34 | 3 | 30µs | 2 | 77µs | # spent 43µs (10+34) within Template::Context::BEGIN@34 which was called:
# once (10µs+34µs) by Template::Config::load at line 34 # spent 43µs making 1 call to Template::Context::BEGIN@34
# spent 34µs making 1 call to constant::import |
35 | 3 | 3.53ms | 2 | 138µs | # spent 74µs (11+64) within Template::Context::BEGIN@35 which was called:
# once (11µs+64µs) by Template::Config::load at line 35 # spent 74µs making 1 call to Template::Context::BEGIN@35
# spent 64µs making 1 call to constant::import |
36 | |||||
37 | 1 | 700ns | our $VERSION = 2.98; | ||
38 | 1 | 800ns | our $DEBUG = 0 unless defined $DEBUG; | ||
39 | 1 | 900ns | our $DEBUG_FORMAT = "\n## \$file line \$line : [% \$text %] ##\n"; | ||
40 | 1 | 300ns | our $VIEW_CLASS = 'Template::View'; | ||
41 | 1 | 200ns | 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 642ms (2.09+640) within Template::Context::template which was called 10 times, avg 64.2ms/call:
# 9 times (476µs+264ms) by Template::Context::process at line 309, avg 29.4ms/call
# once (1.61ms+376ms) by Template::Service::process at line 68 of Template/Service.pm | ||||
78 | 95 | 265µs | my ($self, $name) = @_; | ||
79 | my ($prefix, $blocks, $defblocks, $provider, $template, $error); | ||||
80 | my ($shortname, $blockname, $providers); | ||||
81 | |||||
82 | $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 | 60µs | return $name # spent 57µs making 10 calls to Scalar::Util::blessed, avg 6µs/call
# spent 3µs making 1 call to UNIVERSAL::isa | ||
88 | if (blessed($name) && $name->isa(DOCUMENT)) | ||||
89 | || ref($name) eq 'CODE'; | ||||
90 | |||||
91 | $shortname = $name; | ||||
92 | |||||
93 | 45 | 101µs | unless (ref $name) { | ||
94 | |||||
95 | $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 | 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 | foreach $blocks (@{ $self->{ BLKSTACK } }) { | ||||
105 | 8 | 22µ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 | 9 | 1.58ms | if ($^O eq 'MSWin32') { | ||
112 | # let C:/foo through | ||||
113 | $prefix = $1 if $shortname =~ s/^(\w{2,})://o; | ||||
114 | } | ||||
115 | else { | ||||
116 | 9 | 28µs | $prefix = $1 if $shortname =~ s/^(\w+)://; # spent 28µs making 9 calls to Template::Context::CORE:subst, avg 3µs/call | ||
117 | } | ||||
118 | |||||
119 | 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 | 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 | $blockname = ''; | ||||
135 | while ($shortname) { | ||||
136 | $self->debug("asking providers for [$shortname] [$blockname]") | ||||
137 | 18 | 24µs | if $self->{ DEBUG }; | ||
138 | |||||
139 | foreach my $provider (@$providers) { | ||||
140 | 18 | 128µs | 9 | 639ms | ($template, $error) = $provider->fetch($shortname, $prefix); # spent 639ms making 9 calls to Template::Provider::fetch, avg 71.1ms/call |
141 | 9 | 51µ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 | 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 | sub plugin { | ||||
184 | my ($self, $name, $args) = @_; | ||||
185 | my ($provider, $plugin, $error); | ||||
186 | |||||
187 | $self->debug("plugin($name, ", defined $args ? @$args : '[ ]', ')') | ||||
188 | if $self->{ DEBUG }; | ||||
189 | |||||
190 | # request the named plugin from each of the LOAD_PLUGINS providers in turn | ||||
191 | foreach my $provider (@{ $self->{ LOAD_PLUGINS } }) { | ||||
192 | ($plugin, $error) = $provider->fetch($name, $args, $self); | ||||
193 | 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 | # spent 5.57ms (3.19+2.37) within Template::Context::filter which was called 214 times, avg 26µs/call:
# 101 times (1.23ms+855µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/opac-facets.inc:32] at line 13 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/opac-facets.inc, avg 21µs/call
# 60 times (1.02ms+800µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/page-numbers.inc:31] at line 7 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/page-numbers.inc, avg 30µs/call
# 25 times (606µs+408µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 505 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt, avg 41µs/call
# 5 times (77µs+70µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 5 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt, avg 29µs/call
# 4 times (61µs+42µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc:111] at line 72 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc, avg 26µs/call
# 4 times (46µs+35µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 385 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt, avg 20µs/call
# 4 times (34µs+29µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc:111] at line 91 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc, avg 16µs/call
# 3 times (45µs+31µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/opac-facets.inc:32] at line 8 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/opac-facets.inc, avg 25µs/call
# 2 times (14µs+12µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc:111] at line 98 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc, avg 13µs/call
# once (21µs+17µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc:111] at line 41 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc
# once (7µs+28µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 248 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (7µs+16µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 255 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (6µs+14µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 262 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (10µs+8µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 241 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (9µs+7µs) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 101 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt | ||||
213 | 1712 | 2.01ms | 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 | 428 | 858µs | 214 | 2.37ms | ($filter, $error) = $provider->fetch($name, $args, $self); # spent 2.37ms making 214 calls to Template::Filters::fetch, avg 11µs/call |
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 322ms (1.63+321) within Template::Context::process which was called 9 times, avg 35.8ms/call:
# 8 times (1.39ms+-1.39ms) by Template::Context::include at line 409, avg 0s/call
# once (247µs+322ms) by Template::Service::process at line 94 of Template/Service.pm | ||||
294 | 126 | 454µs | my ($self, $template, $params, $localize) = @_; | ||
295 | my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) }; | ||||
296 | my (@compiled, $name, $compiled); | ||||
297 | my ($stash, $component, $tblocks, $error, $tmpout); | ||||
298 | my $output = ''; | ||||
299 | |||||
300 | $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 | if $self->{ DEBUG }; | ||||
306 | |||||
307 | # fetch compiled template for each name specified | ||||
308 | foreach $name (@$template) { | ||||
309 | 9 | 63µs | 9 | 264ms | push(@compiled, $self->template($name)); # spent 264ms making 9 calls to Template::Context::template, avg 29.4ms/call |
310 | } | ||||
311 | |||||
312 | 2 | 10µs | 8 | 1.59ms | if ($localize) { # spent 1.59ms making 8 calls to Template::Stash::clone, avg 199µ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 | 7µs | $self->{ STASH }->update($params); # spent 7µs making 1 call to Template::Stash::update | ||
318 | $stash = $self->{ STASH }; | ||||
319 | } | ||||
320 | |||||
321 | 27 | 136µs | eval { | ||
322 | # save current component | ||||
323 | 9 | 184µs | 10 | 148µs | eval { $component = $stash->get('component') }; # spent 141µs making 9 calls to Template::Stash::XS::get, avg 16µs/call
# spent 7µs making 1 call to Template::Stash::undefined |
324 | |||||
325 | foreach $name (@$template) { | ||||
326 | 81 | 742µs | $compiled = shift @compiled; | ||
327 | my $element = ref $compiled eq 'CODE' | ||||
328 | ? { (name => (ref $name ? '' : $name), modtime => time()) } | ||||
329 | : $compiled; | ||||
330 | |||||
331 | 24 | 75µs | 17 | 126µs | if (blessed($component) && $component->isa(DOCUMENT)) { # spent 103µs making 9 calls to Scalar::Util::blessed, avg 11µs/call
# spent 24µs making 8 calls to UNIVERSAL::isa, avg 3µs/call |
332 | $element->{ caller } = $component->{ name }; | ||||
333 | $element->{ callers } = $component->{ callers } || []; | ||||
334 | push(@{$element->{ callers }}, $element->{ caller }); | ||||
335 | } | ||||
336 | |||||
337 | 9 | 62µs | $stash->set('component', $element); # spent 62µs making 9 calls to Template::Stash::XS::set, avg 7µs/call | ||
338 | |||||
339 | 3 | 7µs | unless ($localize) { # spent 4µs making 1 call to Template::Document::blocks
# spent 1µs making 1 call to Scalar::Util::blessed
# spent 1µs 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 | 9 | 322ms | if (ref $compiled eq 'CODE') { # spent 344ms making 9 calls to Template::Document::process, avg 38.3ms/call, recursion: max depth 1, sum of overlapping time 22.3ms | ||
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 | if ($trim) { | ||||
359 | for ($tmpout) { | ||||
360 | s/^\s+//; | ||||
361 | s/\s+$//; | ||||
362 | } | ||||
363 | } | ||||
364 | $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 | 17 | 111µs | pop(@{$element->{ callers }}) # spent 90µs making 9 calls to Scalar::Util::blessed, avg 10µs/call
# spent 21µs making 8 calls to UNIVERSAL::isa, avg 3µs/call | ||
374 | if (blessed($component) && $component->isa(DOCUMENT)); | ||||
375 | } | ||||
376 | 9 | 65µs | $stash->set('component', $component); # spent 65µs making 9 calls to Template::Stash::XS::set, avg 7µs/call | ||
377 | }; | ||||
378 | $error = $@; | ||||
379 | |||||
380 | 8 | 47µs | if ($localize) { # spent 47µs making 8 calls to Template::Stash::declone, avg 6µs/call | ||
381 | # ensure stash is delocalised before dying | ||||
382 | $self->{ STASH } = $self->{ STASH }->declone(); | ||||
383 | } | ||||
384 | |||||
385 | $self->throw(ref $error | ||||
386 | ? $error : (Template::Constants::ERROR_FILE, $error)) | ||||
387 | if $error; | ||||
388 | |||||
389 | 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 290ms (142µs+290) within Template::Context::include which was called 8 times, avg 36.3ms/call:
# 2 times (66µs+53.0ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 1 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt, avg 26.5ms/call
# once (11µs+89.7ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 313 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (16µs+55.9ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 525 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (8µs+35.5ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 532 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (9µs+25.3ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 389 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (16µs+25.0ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 317 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt
# once (16µs+5.53ms) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 518 of /usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt | ||||
408 | 16 | 119µs | my ($self, $template, $params) = @_; | ||
409 | 1 | 446µs | 16 | 39µs | return $self->process($template, $params, 'localize me!'); # spent 39µs making 8 calls to Template::Stash::XS::DESTROY, avg 5µs/call
# spent 290ms making 8 calls to Template::Context::process, avg 36.2ms/call, recursion: max depth 1, sum of overlapping time 290ms |
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 205µs (26+179) within Template::Context::localise which was called:
# once (26µs+179µs) by Template::Service::process at line 78 of Template/Service.pm | ||||
566 | 2 | 23µs | my $self = shift; | ||
567 | 1 | 179µs | $self->{ STASH } = $self->{ STASH }->clone(@_); # spent 179µs making 1 call to Template::Stash::clone | ||
568 | } | ||||
569 | |||||
570 | # spent 24µs (19+5) within Template::Context::delocalise which was called:
# once (19µs+5µs) by Template::Service::process at line 124 of Template/Service.pm | ||||
571 | 2 | 15µs | my $self = shift; | ||
572 | 1 | 5µs | $self->{ STASH } = $self->{ STASH }->declone(); # spent 5µ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 55µs within Template::Context::visit which was called 9 times, avg 6µs/call:
# 9 times (55µs+0s) by Template::Document::process at line 146 of Template/Document.pm, avg 6µs/call | ||||
588 | 18 | 62µs | my ($self, $document, $blocks) = @_; | ||
589 | 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 57µs within Template::Context::leave which was called 9 times, avg 6µs/call:
# 9 times (57µs+0s) by Template::Document::process at line 155 of Template/Document.pm, avg 6µs/call | ||||
604 | 18 | 64µs | my $self = shift; | ||
605 | 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 | sub define_view { | ||||
651 | my ($self, $name, $params) = @_; | ||||
652 | my $base; | ||||
653 | |||||
654 | if (defined $params->{ base }) { | ||||
655 | my $base = $self->{ STASH }->get($params->{ base }); | ||||
656 | |||||
657 | return $self->throw( | ||||
658 | &Template::Constants::ERROR_VIEW, | ||||
659 | "view base is not defined: $params->{ base }" | ||||
660 | ) unless $base; | ||||
661 | |||||
662 | return $self->throw( | ||||
663 | &Template::Constants::ERROR_VIEW, | ||||
664 | "view base is not a $VIEW_CLASS object: $params->{ base } => $base" | ||||
665 | ) unless blessed($base) && $base->isa($VIEW_CLASS); | ||||
666 | |||||
667 | $params->{ base } = $base; | ||||
668 | } | ||||
669 | my $view = $self->view($params); | ||||
670 | $view->seal(); | ||||
671 | $self->{ STASH }->set($name, $view); | ||||
672 | } | ||||
673 | |||||
674 | sub define_views { | ||||
675 | my ($self, $views) = @_; | ||||
676 | |||||
677 | # a list reference is better because the order is deterministic (and so | ||||
678 | # allows an earlier VIEW to be the base for a later VIEW), but we'll | ||||
679 | # accept a hash reference and assume that the user knows the order of | ||||
680 | # processing is undefined | ||||
681 | $views = [ %$views ] | ||||
682 | if ref $views eq 'HASH'; | ||||
683 | |||||
684 | # make of copy so we don't destroy the original list reference | ||||
685 | my @items = @$views; | ||||
686 | my ($name, $view); | ||||
687 | |||||
688 | while (@items) { | ||||
689 | $self->define_view(splice(@items, 0, 2)); | ||||
690 | } | ||||
691 | } | ||||
692 | |||||
693 | |||||
694 | #------------------------------------------------------------------------ | ||||
695 | # reset() | ||||
696 | # | ||||
697 | # Reset the state of the internal BLOCKS hash to clear any BLOCK | ||||
698 | # definitions imported via the PROCESS directive. Any original | ||||
699 | # BLOCKS definitions passed to the constructor will be restored. | ||||
700 | #------------------------------------------------------------------------ | ||||
701 | |||||
702 | # spent 12µs within Template::Context::reset which was called:
# once (12µs+0s) by Template::Service::process at line 64 of Template/Service.pm | ||||
703 | 3 | 15µs | my ($self, $blocks) = @_; | ||
704 | $self->{ BLKSTACK } = [ ]; | ||||
705 | $self->{ BLOCKS } = { %{ $self->{ INIT_BLOCKS } } }; | ||||
706 | } | ||||
707 | |||||
708 | |||||
709 | #------------------------------------------------------------------------ | ||||
710 | # stash() | ||||
711 | # | ||||
712 | # Simple accessor methods to return the STASH values. This is likely | ||||
713 | # to be called quite often so we provide a direct method rather than | ||||
714 | # relying on the slower AUTOLOAD. | ||||
715 | #------------------------------------------------------------------------ | ||||
716 | |||||
717 | # spent 39µs within Template::Context::stash which was called 9 times, avg 4µs/call:
# 2 times (8µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/page-numbers.inc:31] at line 3 of (eval 1127)[Template/Document.pm:78], avg 4µs/call
# once (9µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/doc-head-open.inc:14] at line 3 of (eval 1124)[Template/Document.pm:78]
# once (4µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/doc-head-close.inc:121] at line 3 of (eval 1125)[Template/Document.pm:78]
# once (4µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/opac-facets.inc:32] at line 3 of (eval 1129)[Template/Document.pm:78]
# once (4µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/opac-bottom.inc:74] at line 3 of (eval 1130)[Template/Document.pm:78]
# once (4µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/resort_form.inc:48] at line 3 of (eval 1128)[Template/Document.pm:78]
# once (4µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/includes/masthead.inc:111] at line 3 of (eval 1126)[Template/Document.pm:78]
# once (3µs+0s) by Template::Document::__ANON__[/usr/share/koha/opac/htdocs/opac-tmpl/prog/en-NZ/modules/opac-results.tt:541] at line 3 of (eval 1123)[Template/Document.pm:78] | ||||
718 | 9 | 69µs | return $_[0]->{ STASH }; | ||
719 | } | ||||
720 | |||||
721 | |||||
722 | #------------------------------------------------------------------------ | ||||
723 | # define_vmethod($type, $name, \&sub) | ||||
724 | # | ||||
725 | # Passes $type, $name, and &sub on to stash->define_vmethod(). | ||||
726 | #------------------------------------------------------------------------ | ||||
727 | sub define_vmethod { | ||||
728 | my $self = shift; | ||||
729 | $self->stash->define_vmethod(@_); | ||||
730 | } | ||||
731 | |||||
732 | |||||
733 | #------------------------------------------------------------------------ | ||||
734 | # debugging($command, @args, \%params) | ||||
735 | # | ||||
736 | # Method for controlling the debugging status of the context. The first | ||||
737 | # argument can be 'on' or 'off' to enable/disable debugging, 'format' | ||||
738 | # to define the format of the debug message, or 'msg' to generate a | ||||
739 | # debugging message reporting the file, line, message text, etc., | ||||
740 | # according to the current debug format. | ||||
741 | #------------------------------------------------------------------------ | ||||
742 | |||||
743 | sub debugging { | ||||
744 | my $self = shift; | ||||
745 | my $hash = ref $_[-1] eq 'HASH' ? pop : { }; | ||||
746 | my @args = @_; | ||||
747 | |||||
748 | # print "*** debug(@args)\n"; | ||||
749 | if (@args) { | ||||
750 | if ($args[0] =~ /^on|1$/i) { | ||||
751 | $self->{ DEBUG_DIRS } = 1; | ||||
752 | shift(@args); | ||||
753 | } | ||||
754 | elsif ($args[0] =~ /^off|0$/i) { | ||||
755 | $self->{ DEBUG_DIRS } = 0; | ||||
756 | shift(@args); | ||||
757 | } | ||||
758 | } | ||||
759 | |||||
760 | if (@args) { | ||||
761 | if ($args[0] =~ /^msg$/i) { | ||||
762 | return unless $self->{ DEBUG_DIRS }; | ||||
763 | my $format = $self->{ DEBUG_FORMAT }; | ||||
764 | $format = $DEBUG_FORMAT unless defined $format; | ||||
765 | $format =~ s/\$(\w+)/$hash->{ $1 }/ge; | ||||
766 | return $format; | ||||
767 | } | ||||
768 | elsif ($args[0] =~ /^format$/i) { | ||||
769 | $self->{ DEBUG_FORMAT } = $args[1]; | ||||
770 | } | ||||
771 | # else ignore | ||||
772 | } | ||||
773 | |||||
774 | return ''; | ||||
775 | } | ||||
776 | |||||
777 | |||||
778 | #------------------------------------------------------------------------ | ||||
779 | # AUTOLOAD | ||||
780 | # | ||||
781 | # Provides pseudo-methods for read-only access to various internal | ||||
782 | # members. For example, templates(), plugins(), filters(), | ||||
783 | # eval_perl(), load_perl(), etc. These aren't called very often, or | ||||
784 | # may never be called at all. | ||||
785 | #------------------------------------------------------------------------ | ||||
786 | |||||
787 | sub AUTOLOAD { | ||||
788 | my $self = shift; | ||||
789 | my $method = $AUTOLOAD; | ||||
790 | my $result; | ||||
791 | |||||
792 | $method =~ s/.*:://; | ||||
793 | return if $method eq 'DESTROY'; | ||||
794 | |||||
795 | warn "no such context method/member: $method\n" | ||||
796 | unless defined ($result = $self->{ uc $method }); | ||||
797 | |||||
798 | return $result; | ||||
799 | } | ||||
800 | |||||
801 | |||||
802 | #------------------------------------------------------------------------ | ||||
803 | # DESTROY | ||||
804 | # | ||||
805 | # Stash may contain references back to the Context via macro closures, | ||||
806 | # etc. This breaks the circular references. | ||||
807 | #------------------------------------------------------------------------ | ||||
808 | |||||
809 | # spent 14µs within Template::Context::DESTROY which was called:
# once (14µs+0s) by main::NULL at line 0 of /usr/share/koha/opac/cgi-bin/opac/opac-search.pl | ||||
810 | 2 | 14µs | my $self = shift; | ||
811 | undef $self->{ STASH }; | ||||
812 | } | ||||
813 | |||||
- - | |||||
816 | #======================================================================== | ||||
817 | # -- PRIVATE METHODS -- | ||||
818 | #======================================================================== | ||||
819 | |||||
820 | #------------------------------------------------------------------------ | ||||
821 | # _init(\%config) | ||||
822 | # | ||||
823 | # Initialisation method called by Template::Base::new() | ||||
824 | #------------------------------------------------------------------------ | ||||
825 | |||||
826 | # spent 15.1ms (119µs+14.9) within Template::Context::_init which was called:
# once (119µs+14.9ms) by Template::Base::new at line 65 of Template/Base.pm | ||||
827 | 21 | 52µs | my ($self, $config) = @_; | ||
828 | my ($name, $item, $method, $block, $blocks); | ||||
829 | my @itemlut = ( | ||||
830 | LOAD_TEMPLATES => 'provider', | ||||
831 | LOAD_PLUGINS => 'plugins', | ||||
832 | LOAD_FILTERS => 'filters' | ||||
833 | ); | ||||
834 | |||||
835 | # LOAD_TEMPLATE, LOAD_PLUGINS, LOAD_FILTERS - lists of providers | ||||
836 | while (($name, $method) = splice(@itemlut, 0, 2)) { | ||||
837 | 6 | 34µs | 3 | 6.05ms | $item = $config->{ $name } # spent 4.17ms making 1 call to Template::Config::filters
# spent 1.77ms making 1 call to Template::Config::plugins
# spent 108µs making 1 call to Template::Config::provider |
838 | || Template::Config->$method($config) | ||||
839 | || return $self->error($Template::Config::ERROR); | ||||
840 | $self->{ $name } = ref $item eq 'ARRAY' ? $item : [ $item ]; | ||||
841 | } | ||||
842 | |||||
843 | my $providers = $self->{ LOAD_TEMPLATES }; | ||||
844 | my $prefix_map = $self->{ PREFIX_MAP } = $config->{ PREFIX_MAP } || { }; | ||||
845 | while (my ($key, $val) = each %$prefix_map) { | ||||
846 | $prefix_map->{ $key } = [ ref $val ? $val : | ||||
847 | map { $providers->[$_] } split(/\D+/, $val) ] | ||||
848 | unless ref $val eq 'ARRAY'; | ||||
849 | } | ||||
850 | |||||
851 | # STASH | ||||
852 | 4 | 31µs | $self->{ STASH } = $config->{ STASH } || do { | ||
853 | my $predefs = $config->{ VARIABLES } | ||||
854 | || $config->{ PRE_DEFINE } | ||||
855 | || { }; | ||||
856 | |||||
857 | # hack to get stash to know about debug mode | ||||
858 | $predefs->{ _DEBUG } = ( ($config->{ DEBUG } || 0) | ||||
859 | & &Template::Constants::DEBUG_UNDEF ) ? 1 : 0 | ||||
860 | 1 | 6µs | unless defined $predefs->{ _DEBUG }; # spent 6µs making 1 call to Template::Constants::DEBUG_UNDEF | ||
861 | $predefs->{ _STRICT } = $config->{ STRICT }; | ||||
862 | |||||
863 | 1 | 8.88ms | Template::Config->stash($predefs) # spent 8.88ms making 1 call to Template::Config::stash | ||
864 | || return $self->error($Template::Config::ERROR); | ||||
865 | }; | ||||
866 | |||||
867 | # compile any template BLOCKS specified as text | ||||
868 | $blocks = $config->{ BLOCKS } || { }; | ||||
869 | $self->{ INIT_BLOCKS } = $self->{ BLOCKS } = { | ||||
870 | map { | ||||
871 | $block = $blocks->{ $_ }; | ||||
872 | $block = $self->template(\$block) | ||||
873 | || return undef | ||||
874 | unless ref $block; | ||||
875 | ($_ => $block); | ||||
876 | } | ||||
877 | keys %$blocks | ||||
878 | }; | ||||
879 | |||||
880 | # define any VIEWS | ||||
881 | $self->define_views( $config->{ VIEWS } ) | ||||
882 | if $config->{ VIEWS }; | ||||
883 | |||||
884 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||
885 | # RECURSION - flag indicating is recursion into templates is supported | ||||
886 | # EVAL_PERL - flag indicating if PERL blocks should be processed | ||||
887 | # TRIM - flag to remove leading and trailing whitespace from output | ||||
888 | # BLKSTACK - list of hashes of BLOCKs defined in current template(s) | ||||
889 | # CONFIG - original configuration hash | ||||
890 | # EXPOSE_BLOCKS - make blocks visible as pseudo-files | ||||
891 | # DEBUG_FORMAT - format for generating template runtime debugging messages | ||||
892 | # DEBUG - format for generating template runtime debugging messages | ||||
893 | |||||
894 | $self->{ RECURSION } = $config->{ RECURSION } || 0; | ||||
895 | $self->{ EVAL_PERL } = $config->{ EVAL_PERL } || 0; | ||||
896 | $self->{ TRIM } = $config->{ TRIM } || 0; | ||||
897 | $self->{ BLKSTACK } = [ ]; | ||||
898 | $self->{ CONFIG } = $config; | ||||
899 | $self->{ EXPOSE_BLOCKS } = defined $config->{ EXPOSE_BLOCKS } | ||||
900 | ? $config->{ EXPOSE_BLOCKS } | ||||
901 | : 0; | ||||
902 | |||||
903 | $self->{ DEBUG_FORMAT } = $config->{ DEBUG_FORMAT }; | ||||
904 | $self->{ DEBUG_DIRS } = ($config->{ DEBUG } || 0) | ||||
905 | & Template::Constants::DEBUG_DIRS; | ||||
906 | $self->{ DEBUG } = defined $config->{ DEBUG } | ||||
907 | ? $config->{ DEBUG } & ( Template::Constants::DEBUG_CONTEXT | ||||
908 | | Template::Constants::DEBUG_FLAGS ) | ||||
909 | : $DEBUG; | ||||
910 | |||||
911 | return $self; | ||||
912 | } | ||||
913 | |||||
914 | |||||
915 | #------------------------------------------------------------------------ | ||||
916 | # _dump() | ||||
917 | # | ||||
918 | # Debug method which returns a string representing the internal state | ||||
919 | # of the context object. | ||||
920 | #------------------------------------------------------------------------ | ||||
921 | |||||
922 | sub _dump { | ||||
923 | my $self = shift; | ||||
924 | my $output = "[Template::Context] {\n"; | ||||
925 | my $format = " %-16s => %s\n"; | ||||
926 | my $key; | ||||
927 | |||||
928 | foreach $key (qw( RECURSION EVAL_PERL TRIM )) { | ||||
929 | $output .= sprintf($format, $key, $self->{ $key }); | ||||
930 | } | ||||
931 | foreach my $pname (qw( LOAD_TEMPLATES LOAD_PLUGINS LOAD_FILTERS )) { | ||||
932 | my $provtext = "[\n"; | ||||
933 | foreach my $prov (@{ $self->{ $pname } }) { | ||||
934 | $provtext .= $prov->_dump(); | ||||
935 | # $provtext .= ",\n"; | ||||
936 | } | ||||
937 | $provtext =~ s/\n/\n /g; | ||||
938 | $provtext =~ s/\s+$//; | ||||
939 | $provtext .= ",\n ]"; | ||||
940 | $output .= sprintf($format, $pname, $provtext); | ||||
941 | } | ||||
942 | $output .= sprintf($format, STASH => $self->{ STASH }->_dump()); | ||||
943 | $output .= '}'; | ||||
944 | return $output; | ||||
945 | } | ||||
946 | |||||
947 | |||||
948 | 1 | 5µs | 1; | ||
949 | |||||
950 | __END__ | ||||
# spent 28µs within Template::Context::CORE:subst which was called 9 times, avg 3µs/call:
# 9 times (28µs+0s) by Template::Context::template at line 116, avg 3µs/call |