From ca0d3d364bbfbd5fcb65c1153a21469b077ba80e Mon Sep 17 00:00:00 2001 From: "lpsolit%gmail.com" <> Date: Wed, 22 Feb 2006 22:58:39 +0000 Subject: Bug 316127: Implement an infrastructure to link to the documentation - Patch by Marc Schumann r=vladd a=justdave --- Bugzilla/Config/Common.pm | 9 +++ Bugzilla/Config/Core.pm | 7 ++ skins/standard/global.css | 11 +++ .../en/default/account/auth/ldap-error.html.tmpl | 2 + template/en/default/admin/params/core.html.tmpl | 8 +- template/en/default/global/code-error.html.tmpl | 10 +++ template/en/default/global/docslinks.html.tmpl | 53 +++++++++++++ template/en/default/global/user-error.html.tmpl | 87 +++++++++++++++++++++- 8 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 template/en/default/global/docslinks.html.tmpl diff --git a/Bugzilla/Config/Common.pm b/Bugzilla/Config/Common.pm index c87e2f713..4ca48b839 100644 --- a/Bugzilla/Config/Common.pm +++ b/Bugzilla/Config/Common.pm @@ -195,6 +195,15 @@ sub check_urlbase { return ""; } +sub check_url { + my ($url) = (@_); + return '' if $url eq ''; # Allow empty URLs + if ($url !~ m:/$:) { + return 'must be a legal URL, absolute or relative, ending with a slash.'; + } + return ''; +} + sub check_webdotbase { my ($value) = (@_); $value = trim($value); diff --git a/Bugzilla/Config/Core.pm b/Bugzilla/Config/Core.pm index e2ff8746d..21b974852 100644 --- a/Bugzilla/Config/Core.pm +++ b/Bugzilla/Config/Core.pm @@ -53,6 +53,13 @@ sub get_param_list { checker => \&check_urlbase }, + { + name => 'docs_urlbase', + type => 't', + default => 'docs/html/', + checker => \&check_url + }, + { name => 'sslbase', type => 't', diff --git a/skins/standard/global.css b/skins/standard/global.css index cddfc96f9..d98770cfd 100644 --- a/skins/standard/global.css +++ b/skins/standard/global.css @@ -287,6 +287,17 @@ body } /* generic (end) */ +div#docslinks { + float: right; + border: 1px solid black; + padding: 1ex; + font-size: 80%; +} + +#docslinks h2 { + margin: 0; +} + .bz_obsolete { text-decoration: line-through; } .bz_inactive { text-decoration: line-through; } .bz_closed, diff --git a/template/en/default/account/auth/ldap-error.html.tmpl b/template/en/default/account/auth/ldap-error.html.tmpl index c719563c8..dba43155b 100644 --- a/template/en/default/account/auth/ldap-error.html.tmpl +++ b/template/en/default/account/auth/ldap-error.html.tmpl @@ -27,6 +27,8 @@ [% PROCESS global/variables.none.tmpl %] +[% admindocslinks = {'extraconfig.html#bzldap' => 'Setting up LDAP authentication'} %] + [% SWITCH auth_err_tag %] [% CASE "cannot_retreive_attr" %] The specified LDAP attribute [% info.attr FILTER html %] was not found. diff --git a/template/en/default/admin/params/core.html.tmpl b/template/en/default/admin/params/core.html.tmpl index adf527c33..bc2dca564 100644 --- a/template/en/default/admin/params/core.html.tmpl +++ b/template/en/default/admin/params/core.html.tmpl @@ -32,6 +32,12 @@ urlbase => "The URL that is the common initial leading part of all $terms.Bugzilla " _ "URLs.", + docs_urlbase => "The URL that is the common initial leading part of all " _ + "$terms.Bugzilla documentation URLs. " _ + "It may be an absolute URL, or a URL relative to urlbase " _ + "above. " _ + "Leave this empty to suppress links to the documentation.", + sslbase => "The URL that is the common initial leading part of all HTTPS " _ "(SSL) $terms.Bugzilla URLs.", @@ -65,4 +71,4 @@ shutdownhtml => "If this field is non-empty, then $terms.Bugzilla will be completely " _ "disabled and this text will be displayed instead of all the " _ "$terms.Bugzilla pages." } -%] \ No newline at end of file +%] diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl index 141930b07..a0e4e3a9a 100644 --- a/template/en/default/global/code-error.html.tmpl +++ b/template/en/default/global/code-error.html.tmpl @@ -39,6 +39,8 @@ [% error_message = BLOCK %] [% IF error == "action_unrecognized" %] + [% docslinks = {'query.html' => "Searching for $terms.bugs", + 'list.html' => "$terms.Bug lists"} %] I don't recognize the value ([% action FILTER html %]) of the action variable. @@ -70,6 +72,7 @@ the error [% bug.error FILTER html %]. [% ELSIF error == "chart_data_not_generated" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up Charting'} %] [% IF product %] Charts for the [% product FILTER html %] product are not available yet because no charting data has been collected for it since it @@ -93,6 +96,7 @@ Unable to open the chart datafile [% filename FILTER html %]. [% ELSIF error == "chart_lines_not_installed" %] + [% admindocslinks = {'installation.html#install-perlmodules' => 'Installing perl modules necessary for Charting'} %] Charts will not work without the Chart::Lines Perl module being installed. Run checksetup.pl for installation instructions. @@ -104,6 +108,7 @@ and [% type FILTER html %] together. [% ELSIF error == "gd_not_installed" %] + [% admindocslinks = {'installation.html#install-perlmodules' => 'Installing perl modules necessary for Charting'} %] Charts will not work without the GD Perl module being installed. Run checksetup.pl for installation instructions. @@ -344,6 +349,11 @@ [% PROCESS global/header.html.tmpl %] [% END %] +[% PROCESS global/docslinks.html.tmpl + docslinks = docslinks + admindocslinks = admindocslinks +%] +

[% terms.Bugzilla %] has suffered an internal error. Please save this page and send diff --git a/template/en/default/global/docslinks.html.tmpl b/template/en/default/global/docslinks.html.tmpl new file mode 100644 index 000000000..56c020637 --- /dev/null +++ b/template/en/default/global/docslinks.html.tmpl @@ -0,0 +1,53 @@ +[%# 1.0@bugzilla.org %] +[%# 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. + # + # Contributor(s): Marc Schumann + #%] + +[%# INTERFACE: + # docslinks: hash. Hash keys will be used as text of the documentation links, + # hash values will be used as links to the document, relative to + # the main Bugzilla documentation directory. + # Example: If you want a 'FAQ' link to point to, the "faq-general" + # named anchor on faq.html, assign + # { 'FAQ' => "faq.html#faq-general" } + # to docslinks. + # You may only link to sections by their given ID; it is not allowed + # to link to a section which is not given an ID (thus getting + # assigned an automatically generated ID). Otherwise, the link + # would break on a recompilation of the documentation. + # admindocslinks: hash. Same as docslinks, but will only be displayed to + # members of the admin group. + #%] + +[% IF Param('docs_urlbase') && + docslinks.keys.size || (admindocslinks.keys.size && user.in_group('admin')) %] +

+[% END %] + +[% BLOCK docslinkslist %] + [% FOREACH docslink = docstype.keys %] +
  • + [% docstype.$docslink FILTER html %] +
  • + [% END %] +[% END %] diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index 091e4248c..3863cb150 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -31,7 +31,7 @@ # # Note that you must explicitly filter every single template variable # in this file; if you do not wish to change it, use the "none" filter. - # + # # Extension- or custom-specific error handling can be easily added # via hooks: just place your -errors.html.tmpl into # template/en/extension/hook/global/user-error.html.tmpl/errors/ @@ -109,6 +109,7 @@ [% ELSIF error == "auth_failure" %] [% title = "Authorization Required" %] + [% admindocslinks = {'group.html' => 'Group Security'} %] Sorry, [% IF group %] you aren't a member of the '[% group FILTER html %]' group, @@ -196,10 +197,12 @@ [% ELSIF error == "bug_access_denied" %] [% title = "Access Denied" %] + [% admindocslinks = {'group.html' => 'Group Security'} %] You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %]. [% ELSIF error == "bug_access_query" %] [% title = "Access Denied" %] + [% docslinks = {'myaccount.html' => 'Creating an account'} %] You are not authorized to access [% terms.bug %] #[% bug_id FILTER html %]. To see this [% terms.bug %], you must first "Searching for $terms.bugs", + 'list.html' => "$terms.Bug lists"} %] You may not search, or create saved searches, without any search terms. [% ELSIF error == "bugs_not_changed" %] @@ -348,6 +353,7 @@ [% ELSIF error == "entry_access_denied" %] [% title = "Permission Denied" %] + [% admindocslinks = {'group.html' => 'Group Security'} %] Sorry, either the product [% product FILTER html %] does not exist or you aren't authorized to enter [% terms.abug %] into it. @@ -420,11 +426,17 @@ again. [% ELSIF error == "flag_not_multiplicable" %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You can't ask more than one person at a time for [% type.name FILTER html %]. [% ELSIF error == "flag_requestee_unauthorized" %] [% title = "Flag Requestee Not Authorized" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags', + 'groups.html' => 'Group Security'} %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You asked [% requestee.identity FILTER html %] for [% flag_type.name FILTER html %] on [% terms.bug %] @@ -438,6 +450,10 @@ [% ELSIF error == "flag_requestee_unauthorized_attachment" %] [% title = "Flag Requestee Not Authorized" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags', + 'groups.html' => 'Group Security'} %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You asked [% requestee.identity FILTER html %] for [% flag_type.name FILTER html %] on @@ -449,19 +465,26 @@ [% ELSIF error == "flag_type_cc_list_invalid" %] [% title = "Flag Type CC List Invalid" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %] The CC list [% cc_list FILTER html %] must be less than 200 characters long. [% ELSIF error == "flag_type_description_invalid" %] [% title = "Flag Type Description Invalid" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %] The description must be less than 32K. [% ELSIF error == "flag_type_name_invalid" %] [% title = "Flag Type Name Invalid" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags'} %] The name [% name FILTER html %] must be 1-50 characters long and must not contain any spaces or commas. [% ELSIF error == "flag_update_denied" %] [% title = "Flag Modification Denied" %] + [% admindocslinks = {'flags-overview.html#flags-admin' => 'Administering Flags', + 'groups.html' => 'Group Security'} %] + [% docslinks = {'flags-overview.html' => 'An overview on Flags', + 'flags.html' => 'Using Flags'} %] You tried to [% IF status == "+" %] grant [% ELSIF status == "-" %] deny [% ELSIF status == "X" %] clear [% ELSE %] request [% END %] [% name FILTER html %] @@ -573,6 +596,7 @@ [% ELSIF error == "illegal_group_control_combination" %] [% title = "Your Group Control Combination Is Illegal" %] + [% admindocslinks = {'group.html' => 'Assigning Group Controls to Products'} %] Your group control combination for group " [% groupname FILTER html %]" is illegal. @@ -587,13 +611,18 @@ <, >, &. [% ELSIF error == "illegal_series_creation" %] + [% admindocslinks = {'group.html' => 'Group security'} %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You are not authorised to create series. [% ELSIF error == "illegal_series_edit" %] + [% admindocslinks = {'group.html' => 'Group security'} %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You are not authorised to edit this series. To do this, you must either be its creator, or an administrator. [% ELSIF error == "insufficient_data_points" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] We don't have enough data points to make a graph (yet). [% ELSIF error == "invalid_attach_id" %] @@ -732,6 +761,8 @@ [% ELSIF error == "milestone_already_exists" %] [% title = "Milestone Already Exists" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'milestones.html' => 'About Milestones'} %] The milestone '[% name FILTER html %]' already exists for product ' [%- product FILTER html %]'. @@ -741,6 +772,8 @@ [% ELSIF error == "milestone_is_default" %] [% title = "Default milestone not deletable" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'milestones.html' => 'About Milestones'} %] Sorry, but [% name FILTER html %] is the default milestone for product '[% product FILTER html %]', and so it can not be deleted. @@ -786,6 +819,8 @@ [% ELSIF error == "missing_component" %] [% title = "Missing Component" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'components.html' => 'Creating a component'} %] Sorry, the product [% product FILTER html %] has to have at least one component in order for you to enter [% terms.abug %] into it.

    @@ -817,6 +852,7 @@ [% ELSIF error == "missing_datasets" %] [% title = "No Datasets Selected" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You must specify one or more datasets to plot. [% ELSIF error == "missing_email_type" %] @@ -826,10 +862,12 @@ [% ELSIF error == "missing_frequency" %] [% title = "Missing Frequency" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You did not specify a valid frequency for this series. [% ELSIF error == "missing_name" %] [% title = "Missing Name" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You did not specify a name for this series. [% ELSIF error == "missing_query" %] @@ -848,6 +886,7 @@ [% ELSIF error == "missing_version" %] [% title = "Missing Version" %] + [% admindocslinks = {'versions.html' => 'Defining versions'} %] Sorry, the product [% product FILTER html %] has to have at least one version in order for you to enter [% terms.abug %] into it.

    @@ -861,6 +900,7 @@ [% ELSIF error == "need_quip" %] [% title = "Quip Required" %] + [% docslinks = {'quips.html' => 'About quips'} %] Please enter a quip in the text field. [% ELSIF error == "new_password_missing" %] @@ -869,6 +909,7 @@ [% ELSIF error == "no_axes_defined" %] [% title = "No Axes Defined" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] You didn't define any axes to plot. [% ELSIF error == "no_bugs_chosen" %] @@ -886,27 +927,32 @@ [% ELSIF error == "no_dupe_stats" %] [% title = "Cannot Find Duplicate Statistics" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] There are no duplicate statistics for today ([% today FILTER html %]) or yesterday. [% ELSIF error == "no_dupe_stats_error_today" %] [% title = "Error Reading Today's Dupes File" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] An error occurred opening today's dupes file: [% error_msg FILTER html %]. [% ELSIF error == "no_dupe_stats_error_whenever" %] [% title = "Error Reading Previous Dupes File" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] An error occurred opening [% changedsince FILTER html %] days ago ([% whenever FILTER html %])'s dupes file: [% error_msg FILTER html %]. [% ELSIF error == "no_dupe_stats_error_yesterday" %] [% title = "Error Reading Yesterday's Dupes File" %] + [% admindocslinks = {'extraconfig.html' => 'Setting up the collecstats.pl job'} %] There are no duplicate statistics for today ([% today FILTER html %]), and an error occurred opening yesterday's dupes file: [% error_msg FILTER html %]. [% ELSIF error == "no_new_quips" %] [% title = "No New Quips" %] + [% admindocslinks = {'quips.html' => 'Controlling quip usage'} %] This site does not permit the addition of new quips. [% ELSIF error == "no_page_specified" %] @@ -915,6 +961,9 @@ [% ELSIF error == "no_products" %] [% title = "No Products" %] + [% admindocslinks = {'products.html' => 'Setting up a product', + 'components.html' => 'Adding components to products', + 'groups.html' => 'Groups security'} %] Either no products have been defined to enter [% terms.bugs %] against or you have not been given access to any. @@ -975,42 +1024,51 @@ [% ELSIF error == "prod_votes_per_bug_must_be_nonnegative" %] [% title = "Maximum Votes Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] '[% maxvotesperbug FILTER html %]' is an invalid value for the 'Maximum Votes Per [% terms.Bug %]' field, which should contain a non-negative number. [% ELSIF error == "prod_votes_per_user_must_be_nonnegative" %] [% title = "Votes Per User Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] '[% votesperuser FILTER html %]' is an invalid value for the 'Votes Per User' field, which should contain a non-negative number. [% ELSIF error == "prod_votes_to_confirm_must_be_nonnegative" %] [% title = "Votes To Confirm Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] '[% votestoconfirm FILTER html %]' is an invalid value for the 'Votes To Confirm' field, which should contain a non-negative number. [% ELSIF error == "prod_cant_delete_description" %] [% title = "Cannot delete product description" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] Cannot delete the description for product '[% product FILTER html %]'. [% ELSIF error == "prod_cant_delete_name" %] [% title = "Cannot delete product name" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] Cannot delete the product name for product '[% product FILTER html %]'. [% ELSIF error == "prod_name_already_in_use" %] [% title = "Product name already in use" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] The product name '[% product FILTER html %]' is already in use. [% ELSIF error == "prod_name_diff_in_case" %] [% title = "Product name differs only in case" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] The product name '[% product FILTER html %]' differs from existing product '[% existing_product FILTER html %]' only in case. [% ELSIF error == "prod_must_define_defaultmilestone" %] [% title = "Must define new default milestone" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'milestones.html' => 'About Milestones'} %] [% IF classification %] [% classification_url_part = BLOCK %]&classification= [%- classification FILTER url_quote %] @@ -1028,39 +1086,52 @@ [% ELSIF error == "product_blank_name" %] [% title = "Blank Product Name Not Allowed" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] You must enter a name for the new product. [% ELSIF error == "product_disabled" %] [% title = BLOCK %]Product closed for [% terms.Bugs %] Entry[% END %] + [% admindocslinks = {'products.html' => 'Administering products'} %] Sorry, entering [% terms.bugs %] into the product [% product FILTER html %] has been disabled. [% ELSIF error == "product_edit_denied" %] [% title = "Product Edit Access Denied" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'groups.html' => 'Group security'} %] You are not permitted to edit [% terms.bugs %] in product [%+ product FILTER html %]. [% ELSIF error == "product_has_bugs" %] [% title = BLOCK %]Product has [% terms.Bugs %][% END %] + [% admindocslinks = {'products.html' => 'Administering products'} %] There are [% nb FILTER html %] [%+ terms.bugs %] entered for this product! You must reassign those [% terms.bugs %] to another product before you can delete this one. [% ELSIF error == "product_must_have_description" %] [% title = "Product needs Description" %] + [% admindocslinks = {'products.html' => 'Administering products'} %] You must enter a description for product '[% product FILTER html %]'. [% ELSIF error == "product_must_have_version" %] [% title = "Product needs Version" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'versions.html' => 'Administering versions'} %] You must enter a version for product '[% product FILTER html %]'. [% ELSIF error == "product_not_specified" %] [% title = "No Product Specified" %] + [% admindocslinks = {'products.html' => 'Administering products', + 'components.html' => 'Administering components', + 'milestones.html' => 'Administering milestones', + 'versions.html' => 'Administering versions'} %] No product specified when trying to edit components, milestones, versions or product. [% ELSIF error == "query_name_missing" %] [% title = "No Search Name Specified" %] + [% docslinks = {'list.html' => "About $terms.bug lists"} %] You must enter a name for your search. [% ELSIF error == "query_name_too_long" %] @@ -1087,6 +1158,7 @@ [% ELSIF error == "saved_search_used_by_whines" %] [% title = "Saved Search In Use" %] + [% docslinks = {'whining.html' => 'About Whining'} %] The saved search [% search_name FILTER html %] is being used by Whining events with the following subjects: [%+ subjects FILTER html %] @@ -1099,6 +1171,7 @@ [% ELSIF error == "series_already_exists" %] [% title = "Series Already Exists" %] + [% docslinks = {'reporting.html' => 'Reporting'} %] A series named [% series.category FILTER html %] / [%+ series.subcategory FILTER html %] / [%+ series.name FILTER html %] @@ -1159,6 +1232,7 @@ [% ELSIF error == "too_many_votes_for_bug" %] [% title = "Illegal Vote" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] You may only use at most [% max FILTER html %] votes for a single [%+ terms.bug %] in the [% prod FILTER html %] product, but you are trying to @@ -1166,6 +1240,7 @@ [% ELSIF error == "too_many_votes_for_product" %] [% title = "Illegal Vote" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] You tried to use [% votes FILTER html %] votes, which exceeds the [% max FILTER html %] vote per [% terms.bug %] limit for the [% prod FILTER html %] product. @@ -1191,6 +1266,7 @@ [% ELSIF error == "version_already_exists" %] [% title = "Version Already Exists" %] + [% admindocslinks = {'versions.html' => 'Administering versions'} %] The version '[% name FILTER html %]' already exists for product ' [%- product FILTER html %]'. @@ -1215,16 +1291,19 @@ [% ELSIF error == "users_deletion_disabled" %] [% title = "Deletion not activated" %] + [% admindocslinks = {'useradmin.html' => 'User administration'} %] Sorry, the deletion of user accounts is not allowed. [% ELSIF error == "user_has_responsibility" %] [% title = "Can't Delete User Account" %] + [% admindocslinks = {'useradmin.html' => 'User administration'} %] The user you want to delete is set up for roles as default [% terms.bug %] assignee or QA contact for at least one component. For this reason, you cannot delete the account at this time. [% ELSIF error == "user_login_required" %] [% title = "Login Name Required" %] + [% admindocslinks = {'useradmin.html' => 'User administration'} %] You must enter a login name for the new user. [% ELSIF error == "user_match_failed" %] @@ -1234,6 +1313,7 @@ [% ELSIF error == "votes_must_be_nonnegative" %] [% title = "Votes Must Be Non-negative" %] + [% admindocslinks = {'voting.html' => 'Setting up the voting feature'} %] Only use non-negative numbers for your [% terms.bug %] votes. [% ELSIF error == "wrong_token_for_cancelling_email_change" %] @@ -1280,6 +1360,11 @@ [% PROCESS global/header.html.tmpl %] [% END %] +[% PROCESS global/docslinks.html.tmpl + docslinks = docslinks + admindocslinks = admindocslinks +%] +
    -- cgit v1.2.3-24-g4f1b