diff options
author | mkanat%bugzilla.org <> | 2009-11-23 08:00:01 +0100 |
---|---|---|
committer | mkanat%bugzilla.org <> | 2009-11-23 08:00:01 +0100 |
commit | 9fb2bb66cfe8d106603a59c78ad742bebdbbaf09 (patch) | |
tree | 41a096d8f8e81cb0d8cde2765162a68dd61c68f8 | |
parent | c0117171874e3228abc125b12c25dbd436ebe7f7 (diff) | |
download | bugzilla-9fb2bb66cfe8d106603a59c78ad742bebdbbaf09.tar.gz bugzilla-9fb2bb66cfe8d106603a59c78ad742bebdbbaf09.tar.xz |
Bug 516404: Compile template hook code only once per request, and cache the compile templates so that they aren't looked up on disk every time the hook is called
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> (module owner) a=mkanat
-rw-r--r-- | Bugzilla/Template/Plugin/Hook.pm | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/Bugzilla/Template/Plugin/Hook.pm b/Bugzilla/Template/Plugin/Hook.pm index e74363461..fb59a495b 100644 --- a/Bugzilla/Template/Plugin/Hook.pm +++ b/Bugzilla/Template/Plugin/Hook.pm @@ -31,8 +31,8 @@ use Bugzilla::Install::Util qw(include_languages template_base_directories template_lang_directories); use Bugzilla::Util; use Bugzilla::Error; -use File::Spec; +use File::Spec; sub new { my ($class, $context) = @_; @@ -57,33 +57,48 @@ sub process { my $template_name = $1; my $type = $2; - # Munge the filename to create the extension hook filename + # Hooks are named like this: my $extension_template = "$path/$template_name-$hook_name.$type.tmpl"; - my $template_sets = _template_hook_include_path(); + # Get the hooks out of the cache if they exist. Otherwise, read them + # from the disk. + my $cache = Bugzilla->request_cache->{template_plugin_hook_cache} ||= {}; + $cache->{$extension_template} ||= $self->_get_hooks($extension_template); + + # process() accepts an arrayref of templates, so we just pass the whole + # arrayref. + return $context->process($cache->{$extension_template}); +} + +sub _get_hooks { + my ($self, $extension_template) = @_; + my $template_sets = _template_hook_include_path(); my @hooks; foreach my $dir_set (@$template_sets) { foreach my $lang_dir (@$dir_set) { my $file = File::Spec->catdir($lang_dir, $extension_template); if (-e $file) { - # TT won't take a template file not in its include path, - # so we open a filehandle and give it to process() - # instead of the file name. - open (my $fh, '<', $file) or die "$file: $!"; - push(@hooks, $fh); + # TT won't accept a file that isn't in its include path. + # So we open a file handle, compile it to a template, and + # then pass the compiled template to process(). + # + # This doesn't cache the hook template on disk + # (which is nearly impossible for us to do, with TT's + # architecture), but we do cache this compiled template + # per-request (in process() above) so that it doesn't have + # to be recompiled over and over within one request. + open(my $fh, '<', $file) or die "$file: $!"; + my $template = $self->_context->template($fh); + close($fh); + push(@hooks, $template); # Don't run the hook for more than one language. last; } } } - my $output; - foreach my $hook_fh (@hooks) { - $output .= $context->process($hook_fh); - close($hook_fh); - } - return $output; + return \@hooks; } sub _template_hook_include_path { |