Filename | /usr/lib/perl5/Template/Context.pm |
Statements | Executed 2760 statements in 10.5ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
214 | 15 | 4 | 3.64ms | 6.44ms | filter | Template::Context::
9 | 2 | 2 | 1.64ms | 365ms | process (recurses: max depth 1, inclusive time 343ms) | Template::Context::
10 | 2 | 2 | 472µs | 776ms | template | Template::Context::
1 | 1 | 1 | 124µs | 18.3ms | _init | Template::Context::
9 | 1 | 1 | 115µs | 115µs | visit | Template::Context::
1 | 1 | 1 | 86µs | 92µs | delocalise | Template::Context::
8 | 7 | 1 | 79µs | 343ms | include | Template::Context::
1 | 1 | 1 | 66µs | 67µs | BEGIN@30 | Template::Context::
9 | 1 | 1 | 47µs | 47µs | leave | Template::Context::
1 | 1 | 1 | 39µs | 301µs | localise | Template::Context::
9 | 8 | 8 | 38µs | 38µs | stash | Template::Context::
1 | 1 | 1 | 27µs | 35µs | BEGIN@23 | Template::Context::
1 | 1 | 1 | 23µs | 169µs | BEGIN@33 | Template::Context::
9 | 1 | 1 | 22µs | 22µs | CORE:subst (opcode) | Template::Context::
1 | 1 | 1 | 21µs | 64µs | BEGIN@29 | Template::Context::
1 | 1 | 1 | 20µs | 24µs | BEGIN@27 | Template::Context::
1 | 1 | 1 | 20µs | 76µs | BEGIN@31 | Template::Context::
1 | 1 | 1 | 18µs | 60µs | BEGIN@34 | Template::Context::
1 | 1 | 1 | 16µs | 43µs | BEGIN@24 | Template::Context::
1 | 1 | 1 | 15µs | 17µs | BEGIN@28 | Template::Context::
1 | 1 | 1 | 15µs | 15µs | DESTROY | Template::Context::
1 | 1 | 1 | 14µs | 14µs | reset | Template::Context::
1 | 1 | 1 | 13µs | 99µs | BEGIN@25 | Template::Context::
1 | 1 | 1 | 9µs | 44µs | BEGIN@35 | 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 | 37µs | 2 | 42µs | # spent 35µs (27+8) within Template::Context::BEGIN@23 which was called:
# once (27µs+8µs) by Template::Config::load at line 23 # spent 35µs making 1 call to Template::Context::BEGIN@23
# spent 8µs making 1 call to strict::import |
24 | 3 | 37µs | 2 | 70µs | # spent 43µs (16+27) within Template::Context::BEGIN@24 which was called:
# once (16µs+27µs) by Template::Config::load at line 24 # spent 43µs making 1 call to Template::Context::BEGIN@24
# spent 27µs making 1 call to warnings::import |
25 | 3 | 45µs | 2 | 186µs | # spent 99µs (13+86) within Template::Context::BEGIN@25 which was called:
# once (13µs+86µs) by Template::Config::load at line 25 # spent 99µs making 1 call to Template::Context::BEGIN@25
# spent 86µs making 1 call to base::import |
26 | |||||
27 | 3 | 34µs | 2 | 28µs | # spent 24µs (20+4) within Template::Context::BEGIN@27 which was called:
# once (20µs+4µs) by Template::Config::load at line 27 # spent 24µs making 1 call to Template::Context::BEGIN@27
# spent 4µs making 1 call to UNIVERSAL::import |
28 | 3 | 29µs | 2 | 19µs | # spent 17µs (15+2) within Template::Context::BEGIN@28 which was called:
# once (15µs+2µs) by Template::Config::load at line 28 # spent 17µs making 1 call to Template::Context::BEGIN@28
# spent 2µs making 1 call to UNIVERSAL::import |
29 | 3 | 40µs | 2 | 106µs | # spent 64µs (21+43) within Template::Context::BEGIN@29 which was called:
# once (21µs+43µs) by Template::Config::load at line 29 # spent 64µs making 1 call to Template::Context::BEGIN@29
# spent 43µs making 1 call to Exporter::import |
30 | 3 | 43µs | 2 | 69µs | # spent 67µs (66+2) within Template::Context::BEGIN@30 which was called:
# once (66µs+2µs) by Template::Config::load at line 30 # spent 67µs making 1 call to Template::Context::BEGIN@30
# spent 2µs making 1 call to UNIVERSAL::import |
31 | 3 | 48µs | 2 | 132µs | # spent 76µs (20+56) within Template::Context::BEGIN@31 which was called:
# once (20µs+56µs) by Template::Config::load at line 31 # spent 76µs making 1 call to Template::Context::BEGIN@31
# spent 56µs making 1 call to Exporter::import |
32 | |||||
33 | 3 | 72µs | 2 | 315µs | # spent 169µs (23+146) within Template::Context::BEGIN@33 which was called:
# once (23µs+146µs) by Template::Config::load at line 33 # spent 169µs making 1 call to Template::Context::BEGIN@33
# spent 146µs making 1 call to constant::import |
34 | 3 | 38µs | 2 | 102µs | # spent 60µs (18+42) within Template::Context::BEGIN@34 which was called:
# once (18µs+42µs) by Template::Config::load at line 34 # spent 60µs making 1 call to Template::Context::BEGIN@34
# spent 42µs making 1 call to constant::import |
35 | 3 | 3.70ms | 2 | 80µs | # spent 44µs (9+35) within Template::Context::BEGIN@35 which was called:
# once (9µs+35µs) by Template::Config::load at line 35 # spent 44µs making 1 call to Template::Context::BEGIN@35
# spent 35µs making 1 call to constant::import |
36 | |||||
37 | 1 | 1µs | our $VERSION = 2.98; | ||
38 | 1 | 1µs | our $DEBUG = 0 unless defined $DEBUG; | ||
39 | 1 | 1µs | our $DEBUG_FORMAT = "\n## \$file line \$line : [% \$text %] ##\n"; | ||
40 | 1 | 500ns | 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 776ms (472µs+776) within Template::Context::template which was called 10 times, avg 77.6ms/call:
# 9 times (377µs+311ms) by Template::Context::process at line 309, avg 34.6ms/call
# once (95µs+464ms) by Template::Service::process at line 68 of Template/Service.pm | ||||
78 | 10 | 13µs | my ($self, $name) = @_; | ||
79 | 10 | 7µs | my ($prefix, $blocks, $defblocks, $provider, $template, $error); | ||
80 | 10 | 5µs | my ($shortname, $blockname, $providers); | ||
81 | |||||
82 | 10 | 9µ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 | 10 | 120µs | 11 | 53µs | return $name # spent 50µs making 10 calls to Scalar::Util::blessed, avg 5µ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 | 9 | 7µs | $shortname = $name; | ||
92 | |||||
93 | 9 | 9µs | unless (ref $name) { | ||
94 | |||||
95 | 9 | 9µ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 | 9 | 12µ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 | 9 | 17µs | foreach $blocks (@{ $self->{ BLKSTACK } }) { | ||
105 | 8 | 18µ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 | 33µs | if ($^O eq 'MSWin32') { | ||
112 | # let C:/foo through | ||||
113 | $prefix = $1 if $shortname =~ s/^(\w{2,})://o; | ||||
114 | } | ||||
115 | else { | ||||
116 | 9 | 59µs | 9 | 22µs | $prefix = $1 if $shortname =~ s/^(\w+)://; # spent 22µs making 9 calls to Template::Context::CORE:subst, avg 2µs/call |
117 | } | ||||
118 | |||||
119 | 9 | 5µ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 | 9 | 31µ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 | 9 | 7µs | $blockname = ''; | ||
135 | 9 | 7µs | while ($shortname) { | ||
136 | $self->debug("asking providers for [$shortname] [$blockname]") | ||||
137 | 9 | 8µs | if $self->{ DEBUG }; | ||
138 | |||||
139 | 9 | 9µs | foreach my $provider (@$providers) { | ||
140 | 9 | 55µs | 9 | 775ms | ($template, $error) = $provider->fetch($shortname, $prefix); # spent 775ms making 9 calls to Template::Provider::fetch, avg 86.2ms/call |
141 | 9 | 14µ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 | 9 | 65µ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 | 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 6.44ms (3.64+2.81) within Template::Context::filter which was called 214 times, avg 30µs/call:
# 101 times (2.04ms+1.58ms) 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 36µs/call
# 60 times (583µs+476µ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 18µs/call
# 25 times (482µs+320µ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 32µs/call
# 5 times (161µs+126µ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 57µs/call
# 4 times (40µs+31µ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 18µs/call
# 4 times (36µ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
# 4 times (35µs+27µ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 16µs/call
# 3 times (87µs+53µ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 47µs/call
# 2 times (24µs+19µ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 21µs/call
# once (85µs+9µ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 (11µs+45µ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 (13µs+32µ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
# 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 (8µs+27µ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 (8µs+18µ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 | ||||
213 | 214 | 251µs | my ($self, $name, $args, $alias) = @_; | ||
214 | 214 | 106µs | my ($provider, $filter, $error); | ||
215 | |||||
216 | $self->debug("filter($name, ", | ||||
217 | defined $args ? @$args : '[ ]', | ||||
218 | defined $alias ? $alias : '<no alias>', ')') | ||||
219 | 214 | 207µs | 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 | 214 | 407µs | && ($filter = $self->{ FILTER_CACHE }->{ $name }); | ||
225 | |||||
226 | # request the named filter from each of the FILTERS providers in turn | ||||
227 | 214 | 280µs | foreach my $provider (@{ $self->{ LOAD_FILTERS } }) { | ||
228 | 214 | 737µs | 214 | 2.81ms | ($filter, $error) = $provider->fetch($name, $args, $self); # spent 2.81ms making 214 calls to Template::Filters::fetch, avg 13µs/call |
229 | 214 | 287µs | 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 | 214 | 67µs | 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 | 214 | 53µs | $self->{ FILTER_CACHE }->{ $alias } = $filter | ||
255 | if $alias; | ||||
256 | |||||
257 | 214 | 817µs | 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 365ms (1.64+364) within Template::Context::process which was called 9 times, avg 40.6ms/call:
# 8 times (1.39ms+-1.39ms) by Template::Context::include at line 409, avg 0s/call
# once (246µs+365ms) by Template::Service::process at line 94 of Template/Service.pm | ||||
294 | 9 | 16µs | my ($self, $template, $params, $localize) = @_; | ||
295 | 9 | 27µs | my ($trim, $blocks) = @$self{ qw( TRIM BLOCKS ) }; | ||
296 | 9 | 8µs | my (@compiled, $name, $compiled); | ||
297 | 9 | 6µs | my ($stash, $component, $tblocks, $error, $tmpout); | ||
298 | 9 | 7µs | my $output = ''; | ||
299 | |||||
300 | 9 | 16µ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 | 9 | 8µs | if $self->{ DEBUG }; | ||
306 | |||||
307 | # fetch compiled template for each name specified | ||||
308 | 9 | 13µs | foreach $name (@$template) { | ||
309 | 9 | 51µs | 9 | 312ms | push(@compiled, $self->template($name)); # spent 312ms making 9 calls to Template::Context::template, avg 34.6ms/call |
310 | } | ||||
311 | |||||
312 | 9 | 109µs | 8 | 1.51ms | if ($localize) { # spent 1.51ms making 8 calls to Template::Stash::clone, avg 188µ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 | 10µs | 1 | 9µs | $self->{ STASH }->update($params); # spent 9µs making 1 call to Template::Stash::update |
318 | 1 | 2µs | $stash = $self->{ STASH }; | ||
319 | } | ||||
320 | |||||
321 | 9 | 13µs | eval { | ||
322 | # save current component | ||||
323 | 18 | 252µs | 10 | 173µs | eval { $component = $stash->get('component') }; # spent 163µs making 9 calls to Template::Stash::XS::get, avg 18µs/call
# spent 11µs making 1 call to Template::Stash::undefined |
324 | |||||
325 | 9 | 20µs | foreach $name (@$template) { | ||
326 | 9 | 10µs | $compiled = shift @compiled; | ||
327 | 9 | 20µs | my $element = ref $compiled eq 'CODE' | ||
328 | ? { (name => (ref $name ? '' : $name), modtime => time()) } | ||||
329 | : $compiled; | ||||
330 | |||||
331 | 9 | 231µs | 17 | 86µs | if (blessed($component) && $component->isa(DOCUMENT)) { # spent 66µs making 9 calls to Scalar::Util::blessed, avg 7µs/call
# spent 20µs making 8 calls to UNIVERSAL::isa, avg 3µs/call |
332 | 8 | 36µs | $element->{ caller } = $component->{ name }; | ||
333 | 8 | 24µs | $element->{ callers } = $component->{ callers } || []; | ||
334 | 8 | 19µs | push(@{$element->{ callers }}, $element->{ caller }); | ||
335 | } | ||||
336 | |||||
337 | 9 | 193µs | 9 | 81µs | $stash->set('component', $element); # spent 81µs making 9 calls to Template::Stash::XS::set, avg 9µs/call |
338 | |||||
339 | 9 | 32µs | 3 | 12µs | unless ($localize) { # spent 6µs making 1 call to Template::Document::blocks
# spent 4µs making 1 call to Scalar::Util::blessed
# spent 2µ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 | 122µs | 9 | 365ms | if (ref $compiled eq 'CODE') { # spent 393ms making 9 calls to Template::Document::process, avg 43.6ms/call, recursion: max depth 1, sum of overlapping time 27.8ms |
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 | 9 | 5µs | if ($trim) { | ||
359 | for ($tmpout) { | ||||
360 | s/^\s+//; | ||||
361 | s/\s+$//; | ||||
362 | } | ||||
363 | } | ||||
364 | 9 | 57µ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 | 9 | 144µs | 17 | 48µs | pop(@{$element->{ callers }}) # spent 33µs making 9 calls to Scalar::Util::blessed, avg 4µs/call
# spent 14µs making 8 calls to UNIVERSAL::isa, avg 2µs/call |
374 | if (blessed($component) && $component->isa(DOCUMENT)); | ||||
375 | } | ||||
376 | 9 | 102µs | 9 | 60µs | $stash->set('component', $component); # spent 60µs making 9 calls to Template::Stash::XS::set, avg 7µs/call |
377 | }; | ||||
378 | 9 | 6µs | $error = $@; | ||
379 | |||||
380 | 9 | 51µs | 8 | 36µs | if ($localize) { # spent 36µs making 8 calls to Template::Stash::declone, avg 5µs/call |
381 | # ensure stash is delocalised before dying | ||||
382 | $self->{ STASH } = $self->{ STASH }->declone(); | ||||
383 | } | ||||
384 | |||||
385 | 9 | 3µs | $self->throw(ref $error | ||
386 | ? $error : (Template::Constants::ERROR_FILE, $error)) | ||||
387 | if $error; | ||||
388 | |||||
389 | 9 | 156µ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 343ms (79µs+343) within Template::Context::include which was called 8 times, avg 42.9ms/call:
# 2 times (18µs+57.6ms) 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 28.8ms/call
# once (9µs+97.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 (11µs+80.2ms) 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 (15µs+63.9ms) 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+20.7ms) 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 (9µs+19.6ms) 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 (9µs+2.96ms) 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 | 8 | 14µs | my ($self, $template, $params) = @_; | ||
409 | 8 | 355µs | 16 | 27µs | return $self->process($template, $params, 'localize me!'); # spent 27µs making 8 calls to Template::Stash::XS::DESTROY, avg 3µs/call
# spent 343ms making 8 calls to Template::Context::process, avg 42.8ms/call, recursion: max depth 1, sum of overlapping time 343ms |
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 301µs (39+261) within Template::Context::localise which was called:
# once (39µs+261µs) by Template::Service::process at line 78 of Template/Service.pm | ||||
566 | 1 | 2µs | my $self = shift; | ||
567 | 1 | 33µs | 1 | 261µs | $self->{ STASH } = $self->{ STASH }->clone(@_); # spent 261µs making 1 call to Template::Stash::clone |
568 | } | ||||
569 | |||||
570 | # spent 92µs (86+6) within Template::Context::delocalise which was called:
# once (86µs+6µs) by Template::Service::process at line 124 of Template/Service.pm | ||||
571 | 1 | 2µs | my $self = shift; | ||
572 | 1 | 15µs | 1 | 6µs | $self->{ STASH } = $self->{ STASH }->declone(); # spent 6µ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 115µs within Template::Context::visit which was called 9 times, avg 13µs/call:
# 9 times (115µs+0s) by Template::Document::process at line 146 of Template/Document.pm, avg 13µs/call | ||||
588 | 9 | 11µs | my ($self, $document, $blocks) = @_; | ||
589 | 9 | 117µ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 47µs within Template::Context::leave which was called 9 times, avg 5µs/call:
# 9 times (47µs+0s) by Template::Document::process at line 155 of Template/Document.pm, avg 5µs/call | ||||
604 | 9 | 9µs | my $self = shift; | ||
605 | 9 | 54µ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 | 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 14µs within Template::Context::reset which was called:
# once (14µs+0s) by Template::Service::process at line 64 of Template/Service.pm | ||||
703 | 1 | 1µs | my ($self, $blocks) = @_; | ||
704 | 1 | 3µs | $self->{ BLKSTACK } = [ ]; | ||
705 | 1 | 15µs | $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 38µs within Template::Context::stash which was called 9 times, avg 4µs/call:
# 2 times (7µ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 1145)[Template/Document.pm:78], avg 3µs/call
# once (6µ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 1148)[Template/Document.pm:78]
# once (6µ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 1141)[Template/Document.pm:78]
# once (6µ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 1147)[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 1143)[Template/Document.pm:78]
# once (3µ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 1146)[Template/Document.pm:78]
# once (3µ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 1144)[Template/Document.pm:78]
# once (2µ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 1142)[Template/Document.pm:78] | ||||
718 | 9 | 77µ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 15µs within Template::Context::DESTROY which was called:
# once (15µs+0s) by main::NULL at line 0 of /usr/share/koha/opac/cgi-bin/opac/opac-search.pl | ||||
810 | 1 | 3µs | my $self = shift; | ||
811 | 1 | 14µs | 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 18.3ms (124µs+18.1) within Template::Context::_init which was called:
# once (124µs+18.1ms) by Template::Base::new at line 65 of Template/Base.pm | ||||
827 | 1 | 1µs | my ($self, $config) = @_; | ||
828 | 1 | 400ns | my ($name, $item, $method, $block, $blocks); | ||
829 | 1 | 2µs | 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 | 1 | 3µs | while (($name, $method) = splice(@itemlut, 0, 2)) { | ||
837 | 3 | 16µs | 3 | 6.13ms | $item = $config->{ $name } # spent 4.14ms making 1 call to Template::Config::filters
# spent 1.87ms making 1 call to Template::Config::plugins
# spent 124µs making 1 call to Template::Config::provider |
838 | || Template::Config->$method($config) | ||||
839 | || return $self->error($Template::Config::ERROR); | ||||
840 | 3 | 15µs | $self->{ $name } = ref $item eq 'ARRAY' ? $item : [ $item ]; | ||
841 | } | ||||
842 | |||||
843 | 1 | 900ns | my $providers = $self->{ LOAD_TEMPLATES }; | ||
844 | 1 | 2µs | my $prefix_map = $self->{ PREFIX_MAP } = $config->{ PREFIX_MAP } || { }; | ||
845 | 1 | 3µs | 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 | 1 | 5µs | $self->{ STASH } = $config->{ STASH } || do { | ||
853 | my $predefs = $config->{ VARIABLES } | ||||
854 | || $config->{ PRE_DEFINE } | ||||
855 | 1 | 2µs | || { }; | ||
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 | 12µs | 1 | 3µs | unless defined $predefs->{ _DEBUG }; # spent 3µs making 1 call to Template::Constants::DEBUG_UNDEF |
861 | 1 | 2µs | $predefs->{ _STRICT } = $config->{ STRICT }; | ||
862 | |||||
863 | 1 | 7µs | 1 | 12.0ms | Template::Config->stash($predefs) # spent 12.0ms 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 | 1 | 4µs | $blocks = $config->{ BLOCKS } || { }; | ||
869 | $self->{ INIT_BLOCKS } = $self->{ BLOCKS } = { | ||||
870 | map { | ||||
871 | 1 | 10µs | $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 | 1 | 2µs | 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 | 1 | 4µs | $self->{ RECURSION } = $config->{ RECURSION } || 0; | ||
895 | 1 | 2µs | $self->{ EVAL_PERL } = $config->{ EVAL_PERL } || 0; | ||
896 | 1 | 2µs | $self->{ TRIM } = $config->{ TRIM } || 0; | ||
897 | 1 | 2µs | $self->{ BLKSTACK } = [ ]; | ||
898 | 1 | 1µs | $self->{ CONFIG } = $config; | ||
899 | $self->{ EXPOSE_BLOCKS } = defined $config->{ EXPOSE_BLOCKS } | ||||
900 | ? $config->{ EXPOSE_BLOCKS } | ||||
901 | 1 | 2µs | : 0; | ||
902 | |||||
903 | 1 | 2µs | $self->{ DEBUG_FORMAT } = $config->{ DEBUG_FORMAT }; | ||
904 | 1 | 3µs | $self->{ DEBUG_DIRS } = ($config->{ DEBUG } || 0) | ||
905 | & Template::Constants::DEBUG_DIRS; | ||||
906 | $self->{ DEBUG } = defined $config->{ DEBUG } | ||||
907 | 1 | 2µs | ? $config->{ DEBUG } & ( Template::Constants::DEBUG_CONTEXT | ||
908 | | Template::Constants::DEBUG_FLAGS ) | ||||
909 | : $DEBUG; | ||||
910 | |||||
911 | 1 | 11µs | 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 | 7µs | 1; | ||
949 | |||||
950 | __END__ | ||||
# spent 22µs within Template::Context::CORE:subst which was called 9 times, avg 2µs/call:
# 9 times (22µs+0s) by Template::Context::template at line 116, avg 2µs/call |