# -*- Mode: perl; indent-tabs-mode: nil -*- # # The contents of this file are subject to the Mozilla Public # License Version 1.1 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of # the License at http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or # implied. See the License for the specific language governing # rights and limitations under the License. # # The Original Code is the Bugzilla Bug Tracking System. # # The Initial Developer of the Original Code is Netscape Communications # Corporation. Portions created by Netscape are # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> # Zach Lipton <zach@zachlipton.com> # Elliotte Martin <everythingsolved.com> # package Bugzilla::Template::Plugin::Hook; use strict; use Bugzilla::Constants; use Bugzilla::Install::Util qw(include_languages); use Bugzilla::Template; use Bugzilla::Util; use Bugzilla::Error; use File::Spec; use base qw(Template::Plugin); sub load { my ($class, $context) = @_; return $class; } sub new { my ($class, $context) = @_; return bless { _CONTEXT => $context }, $class; } sub process { my ($self, $hook_name, $template) = @_; $template ||= $self->{_CONTEXT}->stash->{component}->{name}; my @hooks; # sanity check: if (!$template =~ /[\w\.\/\-_\\]+/) { ThrowCodeError('template_invalid', { name => $template}); } # also get extension hook files that live in extensions/: # parse out the parts of the template name my ($vol, $subpath, $filename) = File::Spec->splitpath($template); $subpath = $subpath || ''; $filename =~ m/(.*)\.(.*)\.tmpl/; my $templatename = $1; my $type = $2; # munge the filename to create the extension hook filename: my $extensiontemplate = $subpath.'/'.$templatename.'-'.$hook_name.'.'.$type.'.tmpl'; my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*"); my @usedlanguages = include_languages({use_languages => Bugzilla->languages}); foreach my $extension (@extensions) { next if -e "$extension/disabled"; foreach my $language (@usedlanguages) { my $file = $extension.'/template/'.$language.'/'.$extensiontemplate; if (-e $file) { # tt is stubborn and won't take a template file not in its # include path, so we open a filehandle and give it to process() # so the hook gets invoked: open (my $fh, $file); push(@hooks, $fh); } } } my $paths = $self->{_CONTEXT}->{LOAD_TEMPLATES}->[0]->paths; # we keep this too since you can still put hook templates in # template/en/custom/hook foreach my $path (@$paths) { my @files = glob("$path/hook/$template/$hook_name/*.tmpl"); # Have to remove the templates path (INCLUDE_PATH) from the # file path since the template processor auto-adds it back. @files = map($_ =~ /^$path\/(.*)$/ ? $1 : {}, @files); # Add found files to the list of hooks, but removing duplicates, # which can happen when there are identical hooks or duplicate # directories in the INCLUDE_PATH (the latter probably being a TT bug). foreach my $file (@files) { push(@hooks, $file) unless grep($file eq $_, @hooks); } } my $output; foreach my $hook (@hooks) { $output .= $self->{_CONTEXT}->process($hook); } return $output; } 1; __END__ =head1 NAME Bugzilla::Template::Plugin::Hook =head1 DESCRIPTION Template Toolkit plugin to process hooks added into templates by extensions. =head1 METHODS =over =item B<process> =over =item B<Description> Processes hooks added into templates by extensions. =item B<Params> =over =item C<hook_name> The unique name of the template hook. =item C<template> (optional) The path of the calling template. This is used as a work around to a bug which causes the path to the hook to be incorrect when the hook is called from inside a block. Example: If the hook C<lastrow> is added to the template F<show-multiple.html.tmpl> and it is desired to force the correct template path, the template hook would be: [% Hook.process("lastrow", "bug/show-multiple.html.tmpl") %] =back =item B<Returns> Output from processing template extension. =back =back =head1 SEE ALSO L<Template::Plugin> L<http://www.bugzilla.org/docs/tip/html/customization.html> L<http://bugzilla.mozilla.org/show_bug.cgi?id=229658> L<http://bugzilla.mozilla.org/show_bug.cgi?id=298341>