summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Template.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Template.pm')
-rw-r--r--Bugzilla/Template.pm123
1 files changed, 64 insertions, 59 deletions
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index cd7507963..81202965c 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -236,7 +236,8 @@ sub quoteUrls {
~<a href=\"mailto:$2\">$1$2</a>~igx;
# attachment links
- $text =~ s~\b(attachment\s*\#?\s*(\d+)(?:\s+\[details\])?)
+ # BMO: Bug 652332 dkl@mozilla.com 2011-07-20
+ $text =~ s~\b(attachment\s*\#?\s*(\d+)(?:\s+\[diff\])?(?:\s+\[details\])?)
~($things[$count++] = get_attachment_link($2, $1, $user)) &&
("\0\0" . ($count-1) . "\0\0")
~egmxi;
@@ -281,7 +282,7 @@ sub get_attachment_link {
my $dbh = Bugzilla->dbh;
$user ||= Bugzilla->user;
- my $attachment = new Bugzilla::Attachment($attachid);
+ my $attachment = new Bugzilla::Attachment({ id => $attachid, cache => 1 });
if ($attachment) {
my $title = "";
@@ -298,19 +299,21 @@ sub get_attachment_link {
$title = html_quote(clean_text($title));
$link_text =~ s/ \[details\]$//;
+ $link_text =~ s/ \[diff\]$//;
my $linkval = "attachment.cgi?id=$attachid";
- # If the attachment is a patch, try to link to the diff rather
- # than the text, by default.
+ # If the attachment is a patch and patch_viewer feature is
+ # enabled, add link to the diff.
my $patchlink = "";
if ($attachment->ispatch and Bugzilla->feature('patch_viewer')) {
- $patchlink = '&amp;action=diff';
+ $patchlink = qq| <a href="${linkval}&amp;action=diff" title="$title">[diff]</a>|;
}
# Whitespace matters here because these links are in <pre> tags.
return qq|<span class="$className">|
- . qq|<a href="${linkval}${patchlink}" name="attach_${attachid}" title="$title">$link_text</a>|
+ . qq|<a href="${linkval}" name="attach_${attachid}" title="$title">$link_text</a>|
. qq| <a href="${linkval}&amp;action=edit" title="$title">[details]</a>|
+ . qq|${patchlink}|
. qq|</span>|;
}
else {
@@ -331,8 +334,8 @@ sub get_bug_link {
$options->{user} ||= Bugzilla->user;
my $dbh = Bugzilla->dbh;
- if (defined $bug) {
- $bug = blessed($bug) ? $bug : new Bugzilla::Bug($bug);
+ if (defined $bug && $bug ne '') {
+ $bug = blessed($bug) ? $bug : new Bugzilla::Bug({ id => $bug, cache => 1 });
return $link_text if $bug->{error};
}
@@ -399,13 +402,10 @@ sub mtime_filter {
#
# 1. YUI CSS
# 2. Standard Bugzilla stylesheet set (persistent)
-# 3. Standard Bugzilla stylesheet set (selectable)
-# 4. All third-party "skin" stylesheet sets (selectable)
-# 5. Page-specific styles
-# 6. Custom Bugzilla stylesheet set (persistent)
-#
-# "Selectable" skin file sets may be either preferred or alternate.
-# Exactly one is preferred, determined by the "skin" user preference.
+# 3. Third-party "skin" stylesheet set, per user prefs (persistent)
+# 4. Page-specific styles
+# 5. Custom Bugzilla stylesheet set (persistent)
+
sub css_files {
my ($style_urls, $yui, $yui_css) = @_;
@@ -422,18 +422,10 @@ sub css_files {
my @css_sets = map { _css_link_set($_) } @requested_css;
- my %by_type = (standard => [], alternate => {}, skin => [], custom => []);
+ my %by_type = (standard => [], skin => [], custom => []);
foreach my $set (@css_sets) {
foreach my $key (keys %$set) {
- if ($key eq 'alternate') {
- foreach my $alternate_skin (keys %{ $set->{alternate} }) {
- my $files = $by_type{alternate}->{$alternate_skin} ||= [];
- push(@$files, $set->{alternate}->{$alternate_skin});
- }
- }
- else {
- push(@{ $by_type{$key} }, $set->{$key});
- }
+ push(@{ $by_type{$key} }, $set->{$key});
}
}
@@ -450,27 +442,15 @@ sub _css_link_set {
if ($file_name !~ m{(^|/)skins/standard/}) {
return \%set;
}
-
- my $skin_user_prefs = Bugzilla->user->settings->{skin};
+
+ my $skin = Bugzilla->user->settings->{skin}->{value};
my $cgi_path = bz_locations()->{'cgi_path'};
- # If the DB is not accessible, user settings are not available.
- my $all_skins = $skin_user_prefs ? $skin_user_prefs->legal_values : [];
- my %skin_urls;
- foreach my $option (@$all_skins) {
- next if $option eq 'standard';
- my $skin_file_name = $file_name;
- $skin_file_name =~ s{(^|/)skins/standard/}{skins/contrib/$option/};
- if (my $mtime = _mtime("$cgi_path/$skin_file_name")) {
- $skin_urls{$option} = mtime_filter($skin_file_name, $mtime);
- }
+ my $skin_file_name = $file_name;
+ $skin_file_name =~ s{(^|/)skins/standard/}{skins/contrib/$skin/};
+ if (my $mtime = _mtime("$cgi_path/$skin_file_name")) {
+ $set{skin} = mtime_filter($skin_file_name, $mtime);
}
- $set{alternate} = \%skin_urls;
-
- my $skin = $skin_user_prefs->{'value'};
- if ($skin ne 'standard' and defined $set{alternate}->{$skin}) {
- $set{skin} = delete $set{alternate}->{$skin};
- }
-
+
my $custom_file_name = $file_name;
$custom_file_name =~ s{(^|/)skins/standard/}{skins/custom/};
if (my $custom_mtime = _mtime("$cgi_path/$custom_file_name")) {
@@ -556,10 +536,9 @@ $Template::Stash::SCALAR_OPS->{ 0 } =
$Template::Stash::SCALAR_OPS->{ truncate } =
sub {
my ($string, $length, $ellipsis) = @_;
- $ellipsis ||= "";
-
return $string if !$length || length($string) <= $length;
-
+
+ $ellipsis ||= '';
my $strlen = $length - length($ellipsis);
my $newstr = substr($string, 0, $strlen) . $ellipsis;
return $newstr;
@@ -615,6 +594,10 @@ sub create {
COMPILE_DIR => bz_locations()->{'template_cache'},
+ # Don't check for a template update until 1 hour has passed since the
+ # last check.
+ STAT_TTL => 60 * 60,
+
# Initialize templates (f.e. by loading plugins like Hook).
PRE_PROCESS => ["global/initialize.none.tmpl"],
@@ -666,6 +649,18 @@ sub create {
$var =~ s/>/\\x3e/g;
return $var;
},
+
+ # Sadly, different to the above. See http://www.json.org/
+ # for details.
+ json => sub {
+ my ($var) = @_;
+ $var =~ s/([\\\"\/])/\\$1/g;
+ $var =~ s/\n/\\n/g;
+ $var =~ s/\r/\\r/g;
+ $var =~ s/\f/\\f/g;
+ $var =~ s/\t/\\t/g;
+ return $var;
+ },
# Converts data to base64
base64 => sub {
@@ -829,9 +824,7 @@ sub create {
# (Wrapping the message in the WebService is unnecessary
# and causes awkward things like \n's appearing in error
# messages in JSON-RPC.)
- unless (Bugzilla->usage_mode == USAGE_MODE_JSON
- or Bugzilla->usage_mode == USAGE_MODE_XMLRPC)
- {
+ unless (i_am_webservice()) {
$var = wrap_comment($var, 72);
}
$var =~ s/\&nbsp;/ /g;
@@ -881,14 +874,9 @@ sub create {
# Currently logged in user, if any
# If an sudo session is in progress, this is the user we're faking
'user' => sub { return Bugzilla->user; },
-
+
# Currenly active language
- # XXX Eventually this should probably be replaced with something
- # like Bugzilla->language.
- 'current_language' => sub {
- my ($language) = include_languages();
- return $language;
- },
+ 'current_language' => sub { return Bugzilla->current_language; },
# If an sudo session is in progress, this is the user who
# started the session.
@@ -899,7 +887,7 @@ sub create {
# Allow templates to access docs url with users' preferred language
'docs_urlbase' => sub {
- my ($language) = include_languages();
+ my $language = Bugzilla->current_language;
my $docs_urlbase = Bugzilla->params->{'docs_urlbase'};
$docs_urlbase =~ s/\%lang\%/$language/;
return $docs_urlbase;
@@ -928,7 +916,15 @@ sub create {
Bugzilla->fields({ by_name => 1 });
return $cache->{template_bug_fields};
},
-
+
+ # A general purpose cache to store rendered templates for reuse.
+ # Make sure to not mix language-specific data.
+ 'template_cache' => sub {
+ my $cache = Bugzilla->request_cache->{template_cache} ||= {};
+ $cache->{users} ||= {};
+ return $cache;
+ },
+
'css_files' => \&css_files,
yui_resolve_deps => \&yui_resolve_deps,
@@ -975,6 +971,12 @@ sub create {
'default_authorizer' => sub { return Bugzilla::Auth->new() },
},
};
+ # Use a per-process provider to cache compiled templates in memory across
+ # requests.
+ my $provider_key = join(':', @{ $config->{INCLUDE_PATH} });
+ my $shared_providers = Bugzilla->process_cache->{shared_providers} ||= {};
+ $shared_providers->{$provider_key} ||= Template::Provider->new($config);
+ $config->{LOAD_TEMPLATES} = [ $shared_providers->{$provider_key} ];
local $Template::Config::CONTEXT = 'Bugzilla::Template::Context';
@@ -1056,6 +1058,9 @@ sub precompile_templates {
# If anything created a Template object before now, clear it out.
delete Bugzilla->request_cache->{template};
+ # Clear out the cached Provider object
+ Bugzilla->process_cache->{shared_providers} = undef;
+
print install_string('done') . "\n" if $output;
}