Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
ba5a5c40
Commit
ba5a5c40
authored
Mar 17, 2007
by
mkanat%bugzilla.org
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 374227: Create a system for localizing basic installation strings
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> (module owner) a=mkanat
parent
af516107
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
270 additions
and
7 deletions
+270
-7
Util.pm
Bugzilla/Install/Util.pm
+250
-3
checksetup.pl
checksetup.pl
+4
-4
strings.txt.pl
template/en/default/setup/strings.txt.pl
+16
-0
No files found.
Bugzilla/Install/Util.pm
View file @
ba5a5c40
...
...
@@ -28,18 +28,20 @@ use strict;
use
Bugzilla::
Constants
;
use
File::
Basename
;
use
POSIX
();
use
Safe
;
use
base
qw(Exporter)
;
our
@EXPORT_OK
=
qw(
display_version_and_os
indicate_progress
install_string
vers_cmp
)
;
sub
display_version_and_os
{
# Display version information
printf
"\n* This is Bugzilla "
.
BUGZILLA_VERSION
.
" on perl %vd\n"
,
$
^
V
;
my
@os_details
=
POSIX::
uname
;
# 0 is the name of the OS, 2 is the major version,
my
$os_name
=
$os_details
[
0
]
.
' '
.
$os_details
[
2
];
...
...
@@ -47,8 +49,12 @@ sub display_version_and_os {
require
Win32
;
$os_name
=
Win32::
GetOSName
();
}
# 3 is the minor version.
print
"* Running on $os_name $os_details[3]\n"
# $os_details[3] is the minor version.
print
install_string
(
'version_and_os'
,
{
bz_ver
=>
BUGZILLA_VERSION
,
perl_ver
=>
sprintf
(
'%vd'
,
$
^
V
),
os_name
=>
$os_name
,
os_ver
=>
$os_details
[
3
]
})
.
"\n"
;
}
sub
indicate_progress
{
...
...
@@ -63,6 +69,126 @@ sub indicate_progress {
}
}
sub
install_string
{
my
(
$string_id
,
$vars
)
=
@_
;
_cache
()
->
{
template_include_path
}
||=
template_include_path
();
my
$path
=
_cache
()
->
{
template_include_path
};
my
$string_template
;
# Find the first set of templates that defines this string.
foreach
my
$dir
(
@$path
)
{
my
$file
=
"$dir/setup/strings.txt.pl"
;
next
unless
-
e
$file
;
my
$safe
=
new
Safe
;
$safe
->
rdo
(
$file
);
my
%
strings
=
%
{
$safe
->
varglob
(
'strings'
)};
$string_template
=
$strings
{
$string_id
};
last
if
$string_template
;
}
die
"No language defines the string '$string_id'"
if
!
$string_template
;
$vars
||=
{};
my
@replace_keys
=
keys
%
$vars
;
foreach
my
$key
(
@replace_keys
)
{
my
$replacement
=
$vars
->
{
$key
};
die
"'$key' in '$string_id' is tainted: '$replacement'"
if
is_tainted
(
$replacement
);
# We don't want people to start getting clever and inserting
# ##variable## into their values. So we check if any other
# key is listed in the *replacement* string, before doing
# the replacement. This is mostly to protect programmers from
# making mistakes.
if
(
grep
(
$replacement
=~
/##$key##/
,
@replace_keys
))
{
die
"Unsafe replacement for '$key' in '$string_id': '$replacement'"
;
}
$string_template
=~
s/\Q##$key##\E/$replacement/g
;
}
return
$string_template
;
}
sub
template_include_path
{
my
(
$params
)
=
@_
;
$params
||=
{};
# Basically, the way this works is that we have a list of languages
# that we *want*, and a list of languages that Bugzilla actually
# supports. The caller tells us what languages they want, by setting
# $ENV{HTTP_ACCEPT_LANGUAGE} or $params->{only_language}. The languages
# we support are those specified in $params->{use_languages}. Otherwise
# we support every language installed in the template/ directory.
my
@wanted
;
if
(
defined
$params
->
{
only_language
})
{
@wanted
=
(
$params
->
{
only_language
});
}
else
{
@wanted
=
_sort_accept_language
(
$ENV
{
'HTTP_ACCEPT_LANGUAGE'
}
||
''
);
}
my
@supported
;
if
(
defined
$params
->
{
use_languages
})
{
@supported
=
$params
->
{
use_languages
};
}
else
{
my
@dirs
=
glob
(
bz_locations
()
->
{
'templatedir'
}
.
"/*"
);
@dirs
=
map
(
basename
(
$_
),
@dirs
);
@supported
=
grep
(
$_
ne
'CVS'
,
@dirs
);
}
my
@usedlanguages
;
foreach
my
$wanted
(
@wanted
)
{
# If we support the language we want, or *any version* of
# the language we want, it gets pushed into @usedlanguages.
#
# Per RFC 1766 and RFC 2616, things like 'en' match 'en-us' and
# 'en-uk', but not the other way around. (This is unfortunately
# not very clearly stated in those RFC; see comment just over 14.5
# in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)
if
(
my
@found
=
grep
/^\Q$wanted\E(-.+)?$/i
,
@supported
)
{
push
(
@usedlanguages
,
@found
);
}
}
# If we didn't want *any* of the languages we support, just use all
# of the languages we said we support, in the order they were specified.
# This is only done when you ask for a certain set of languages, because
# otherwise @supported just came off the disk in alphabetical order,
# and it could give you de (German) when you speak English.
# (If @supported came off the disk, we fall back on English if no language
# is available--that happens below.)
if
(
!
@usedlanguages
&&
$params
->
{
use_languages
})
{
@usedlanguages
=
@supported
;
}
# We always include English at the bottom if it's not there, even if
# somebody removed it from use_languages.
if
(
!
grep
(
$_
eq
'en'
,
@usedlanguages
))
{
push
(
@usedlanguages
,
'en'
);
}
# Now, we add template directories in the order they will be searched:
# First, we add extension template directories, because extension templates
# override standard templates. Extensions may be localized in the same way
# that Bugzilla templates are localized.
my
@include_path
;
my
@extensions
=
glob
(
bz_locations
()
->
{
'extensionsdir'
}
.
"/*"
);
foreach
my
$extension
(
@extensions
)
{
foreach
my
$lang
(
@usedlanguages
)
{
_add_language_set
(
\
@include_path
,
$lang
,
"$extension/template"
);
}
}
# Then, we add normal template directories, sorted by language.
foreach
my
$lang
(
@usedlanguages
)
{
_add_language_set
(
\
@include_path
,
$lang
);
}
return
\
@include_path
;
}
# This is taken straight from Sort::Versions 1.5, which is not included
# with perl by default.
sub
vers_cmp
{
...
...
@@ -106,6 +232,81 @@ sub vers_cmp {
@A
<=>
@B
;
}
######################
# Helper Subroutines #
######################
# Used by template_include_path.
sub
_add_language_set
{
my
(
$array
,
$lang
,
$templatedir
)
=
@_
;
$templatedir
||=
bz_locations
()
->
{
'templatedir'
};
my
@add
=
(
"$templatedir/$lang/custom"
,
"$templatedir/$lang/default"
);
my
$project
=
bz_locations
->
{
'project'
};
push
(
@add
,
"$templatedir/$lang/$project"
)
if
$project
;
foreach
my
$dir
(
@add
)
{
#if (-d $dir) {
trick_taint
(
$dir
);
push
(
@$array
,
$dir
);
#}
}
}
# Make an ordered list out of a HTTP Accept-Language header (see RFC 2616, 14.4)
# We ignore '*' and <language-range>;q=0
# For languages with the same priority q the order remains unchanged.
sub
_sort_accept_language
{
sub
sortQvalue
{
$b
->
{
'qvalue'
}
<=>
$a
->
{
'qvalue'
}
}
my
$accept_language
=
$_
[
0
];
# clean up string.
$accept_language
=~
s/[^A-Za-z;q=0-9\.\-,]//g
;
my
@qlanguages
;
my
@languages
;
foreach
(
split
/,/
,
$accept_language
)
{
if
(
m/([A-Za-z\-]+)(?:;q=(\d(?:\.\d+)))?/
)
{
my
$lang
=
$1
;
my
$qvalue
=
$2
;
$qvalue
=
1
if
not
defined
$qvalue
;
next
if
$qvalue
==
0
;
$qvalue
=
1
if
$qvalue
>
1
;
push
(
@qlanguages
,
{
'qvalue'
=>
$qvalue
,
'language'
=>
$lang
});
}
}
return
map
(
$_
->
{
'language'
},
(
sort
sortQvalue
@qlanguages
));
}
# This is like request_cache, but it's used only by installation code
# for setup.cgi and things like that.
our
$_cache
=
{};
sub
_cache
{
if
(
$ENV
{
MOD_PERL
})
{
require
Apache2::
RequestUtil
;
return
Apache2::
RequestUtil
->
request
->
pnotes
();
}
return
$_cache
;
}
###############################
# Copied from Bugzilla::Util #
##############################
sub
trick_taint
{
require
Carp
;
Carp::
confess
(
"Undef to trick_taint"
)
unless
defined
$_
[
0
];
my
$match
=
$_
[
0
]
=~
/^(.*)$/s
;
$_
[
0
]
=
$match
?
$1
:
undef
;
return
(
defined
(
$_
[
0
]));
}
sub
is_tainted
{
return
not
eval
{
my
$foo
=
join
(
''
,
@_
),
kill
0
;
1
;
};
}
__END__
=head1 NAME
...
...
@@ -173,6 +374,52 @@ ten items. Defaults to 1 if not specified.
=back
=item C<install_string>
=over
=item B<Description>
This is a very simple method of templating strings for installation.
It should only be used by code that has to run before the Template Toolkit
can be used. (See the comments at the top of the various L<Bugzilla::Install>
modules to find out when it's safe to use Template Toolkit.)
It pulls strings out of the F<strings.txt.pl> "template" and replaces
any variable surrounded by double-hashes (##) with a value you specify.
This allows for localization of strings used during installation.
=item B<Example>
Let's say your template string looks like this:
The ##animal## jumped over the ##plant##.
Let's say that string is called 'animal_jump_plant'. So you call the function
like this:
install_string('animal_jump_plant', { animal => 'fox', plant => 'tree' });
That will output this:
The fox jumped over the tree.
=item B<Params>
=over
=item C<$string_id> - The name of the string from F<strings.txt.pl>.
=item C<$vars> - A hashref containing the replacement values for variables
inside of the string.
=back
=item B<Returns>: The appropriate string, with variables replaced.
=back
=item C<vers_cmp>
=over
...
...
checksetup.pl
View file @
ba5a5c40
...
...
@@ -62,6 +62,10 @@ require 5.008001 if ON_WINDOWS; # for CGI 2.93 or higher
# Live Code
######################################################################
# When we're running at the command line, we need to pick the right
# language before ever displaying any string.
$ENV
{
'HTTP_ACCEPT_LANGUAGE'
}
||=
setlocale
(
LC_CTYPE
);
my
%
switch
;
GetOptions
(
\%
switch
,
'help|h|?'
,
'check-modules'
,
'no-templates|t'
,
'verbose|v|no-silent'
,
'make-admin=s'
);
...
...
@@ -116,10 +120,6 @@ Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
Bugzilla
->
installation_mode
(
INSTALLATION_MODE_NON_INTERACTIVE
)
if
$answers_file
;
Bugzilla
->
installation_answers
(
$answers_file
);
# When we're running at the command line, we need to pick the right
# language before ever creating a template object.
$ENV
{
'HTTP_ACCEPT_LANGUAGE'
}
||=
setlocale
(
LC_CTYPE
);
###########################################################################
# Check and update --LOCAL-- configuration
###########################################################################
...
...
template/en/default/setup/strings.txt.pl
0 → 100644
View file @
ba5a5c40
# This file contains a single hash named %strings, which is used by the
# installation code to display strings before Template-Toolkit can safely
# be loaded.
#
# Each string supports a very simple substitution system, where you can
# have variables named like ##this## and they'll be replaced by the string
# variable with that name.
#
# Please keep the strings in alphabetical order by their name.
%
strings
=
(
version_and_os
=>
"* This is Bugzilla ##bz_ver## on perl ##perl_ver##\n"
.
"* Running on ##os_name## ##os_ver##"
,
);
1
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment