Commit 52a6e7e1 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Modify get_string to take plural forms (bug #901051)

Allows language packs to specify an array of strings (one for each
plural form in the language) instead of a single string.

The first of the variable (sprintf) arguments is assumed to be the
number we need to check to choose a plural form.  This argument is
passed into a language-specific function defined in langconfig.php,
which returns the appropriate plural form based on a formula.

A similar scheme is used for strings formatted by the javascript
get_string function in mahara.js.

See http://www.gnu.org/s/hello/manual/gettext/Plural-forms.html



Change-Id: Ifb58ac4f1e13a54edbc57e5c0a9faaf8454e53a4
Signed-off-by: default avatarRichard Mansfield <richard.mansfield@catalyst.net.nz>
parent a0a92f06
...@@ -28,11 +28,21 @@ function get_string(s) { ...@@ -28,11 +28,21 @@ function get_string(s) {
return '[[[' + s + ((args.length > 0) ? ('(' + args.join(',') + ')') : '') + ']]]'; return '[[[' + s + ((args.length > 0) ? ('(' + args.join(',') + ')') : '') + ']]]';
} }
var str = strings[s]; var str = strings[s];
// @todo Need to sprintf these strings properly. if (typeof(str) == 'object') {
for (var i = 0; i < args.length; i++) { var index = 0;
str = str.replace('%s',args[i]); if (args.length > 0 && typeof(plural) == 'function') {
index = plural(parseInt(args[0]));
if (typeof(index) == 'boolean') {
index = index ? 1 : 0;
}
}
if (typeof(str[index]) != 'string') {
return '[[[' + s + ((args.length > 0) ? ('(' + args.join(',') + ')') : '') + ']]]';
}
str = str[index];
} }
return str; var i = 0;
return str.replace(/%((%)|s)/g, function (m) { return m[2] || args[i++]; });
} }
// Expects an image/css path to fetch url for (requires config.theme[] to be // Expects an image/css path to fetch url for (requires config.theme[] to be
......
...@@ -46,3 +46,13 @@ $string['strftimew3cdatetime'] = '%%Y-%%m-%%dT%%H:%%M:%%S%%z'; ...@@ -46,3 +46,13 @@ $string['strftimew3cdatetime'] = '%%Y-%%m-%%dT%%H:%%M:%%S%%z';
$string['strftimew3cdate'] = '%%Y-%%m-%%d'; $string['strftimew3cdate'] = '%%Y-%%m-%%d';
$string['thislanguage'] = 'English'; $string['thislanguage'] = 'English';
$string['locales'] = 'en_US.utf8,en_GB.utf8,en,english-us,english-uk,english'; $string['locales'] = 'en_US.utf8,en_GB.utf8,en,english-us,english-uk,english';
// Rule to choose from the language's plural forms.
// See the gettext manual, http://www.gnu.org/s/hello/manual/gettext/Plural-forms.html
// For language packs converted from PO format, the following strings and function will be
// automatically generated from the expression in the PO file's "Plural-Forms:" header.
$string['pluralrule'] = 'n != 1';
$string['pluralfunction'] = 'plural_en_utf8';
function plural_en_utf8($n) {
return (int) $n != 1;
}
...@@ -469,7 +469,7 @@ function get_string_location($identifier, $section, $variables, $replacefunc='fo ...@@ -469,7 +469,7 @@ function get_string_location($identifier, $section, $variables, $replacefunc='fo
// First check all the normal locations for the string in the current language // First check all the normal locations for the string in the current language
$result = get_string_local($langstringroot . $langdirectory, $lang . '/' . $section . '.php', $identifier); $result = get_string_local($langstringroot . $langdirectory, $lang . '/' . $section . '.php', $identifier);
if ($result !== false) { if ($result !== false) {
return $replacefunc($result, $variables); return $replacefunc($result, $variables, $lang);
} }
// If the preferred language was English (utf8) we can abort now // If the preferred language was English (utf8) we can abort now
...@@ -484,7 +484,7 @@ function get_string_location($identifier, $section, $variables, $replacefunc='fo ...@@ -484,7 +484,7 @@ function get_string_location($identifier, $section, $variables, $replacefunc='fo
if ($parentlang = get_string_from_file('parentlanguage', $langfile)) { if ($parentlang = get_string_from_file('parentlanguage', $langfile)) {
$result = get_string_local(get_language_root($parentlang) . 'lang/', $parentlang . '/' . $section . '.php', $identifier); $result = get_string_local(get_language_root($parentlang) . 'lang/', $parentlang . '/' . $section . '.php', $identifier);
if ($result !== false) { if ($result !== false) {
return $replacefunc($result, $variables); return $replacefunc($result, $variables, $parentlang);
} }
} }
} }
...@@ -1057,10 +1057,20 @@ function current_language() { ...@@ -1057,10 +1057,20 @@ function current_language() {
* Helper function to sprintf language strings * Helper function to sprintf language strings
* with a variable number of arguments * with a variable number of arguments
* *
* @param string $string raw string to use * @param mixed $string raw string to use, or an array of strings, one for each plural form
* @param array $args arguments to sprintf * @param array $args arguments to sprintf
* @param string $lang The language
*/ */
function format_langstring($string,$args) { function format_langstring($string, $args, $lang='en.utf8') {
if (is_array($string) && isset($args[0]) && is_numeric($args[0])) {
// If there are multiple strings here, there must be one for each plural
// form in the language. The first argument is passed into the plural
// function, which returns an index into the array of strings.
$pluralfunction = get_string_location('pluralfunction', 'langconfig', array(), 'raw_langstring', $lang);
$index = function_exists($pluralfunction) ? $pluralfunction($args[0]) : 0;
$string = isset($string[$index]) ? $string[$index] : current($string);
}
return call_user_func_array('sprintf',array_merge(array($string),$args)); return call_user_func_array('sprintf',array_merge(array($string),$args));
} }
......
...@@ -326,6 +326,7 @@ EOF; ...@@ -326,6 +326,7 @@ EOF;
$stringjs = '<script type="text/javascript">'; $stringjs = '<script type="text/javascript">';
$stringjs .= 'var strings = ' . json_encode($strings) . ';'; $stringjs .= 'var strings = ' . json_encode($strings) . ';';
$stringjs .= "\nfunction plural(n) { return " . get_string('pluralrule', 'langconfig') . "; }\n";
$stringjs .= '</script>'; $stringjs .= '</script>';
// stylesheet set up - if we're in a plugin also get its stylesheet // stylesheet set up - if we're in a plugin also get its stylesheet
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment