Commit 1c9ddc43 authored by catch's avatar catch
Browse files

Issue #2454859 by Gábor Hojtsy, alexpott, mrjmd: Not possible to format plural...

Issue #2454859 by Gábor Hojtsy, alexpott, mrjmd: Not possible to format plural an already translated string
parent 64ac1cb8
......@@ -52,6 +52,17 @@ protected function formatPlural($count, $singular, $plural, array $args = array(
return $this->getStringTranslation()->formatPlural($count, $singular, $plural, $args, $options);
}
/**
* Formats a translated string containing a count of items.
*
* See the
* \Drupal\Core\StringTranslation\TranslationInterface::formatPluralTranslated()
* documentation for details.
*/
protected function formatPluralTranslated($count, $translated, array $args = array(), array $options = array()) {
return $this->getStringTranslation()->formatPluralTranslated($count, $translated, $args, $options);
}
/**
* Gets the string translation service.
*
......
......@@ -41,7 +41,7 @@ public function translate($string, array $args = array(), array $options = array
*
* This function ensures that the string is pluralized correctly. Since t() is
* called by this function, make sure not to pass already-localized strings to
* it.
* it. See formatPluralTranslated() for that.
*
* For example:
* @code
......@@ -70,19 +70,54 @@ public function translate($string, array $args = array(), array $options = array
* An associative array of replacements to make after translation. Instances
* of any key in this array are replaced with the corresponding value.
* Based on the first character of the key, the value is escaped and/or
* themed. See format_string(). Note that you do not need to include @count
* in this array; this replacement is done automatically for the plural case.
* themed. See \Drupal\Component\Utility\String::format(). Note that you do
* not need to include @count in this array; this replacement is done
* automatically for the plural cases.
* @param array $options
* An associative array of additional options. See t() for allowed keys.
*
* @return string
* A translated string.
*
* @see self::translate
* @see \Drupal\Component\Utility\String
* @see self::translate()
* @see t()
* @see format_string()
* @see \Drupal\Component\Utility\SafeMarkup::format()
* @see self::formatPluralTranslated
*/
public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array());
/**
* Formats an already translated string containing a count of items.
*
* This function ensures that the string is pluralized correctly. As opposed
* to the formatPlural() method, this method is designed to be invoked with
* a string already translated (such as with configuration translation).
*
* @param int $count
* The item count to display.
* @param string $translation
* The string containing the translation of a singular/plural pair. It may
* contain any number of possible variants (depending on the language
* translated to) separated by the value of the LOCALE_PLURAL_DELIMITER
* constant.
* @param array $args
* Associative array of replacements to make in the translation. Instances
* of any key in this array are replaced with the corresponding value.
* Based on the first character of the key, the value is escaped and/or
* themed. See \Drupal\Component\Utility\String::format(). Note that you do
* not need to include @count in this array; this replacement is done
* automatically for the plural cases.
* @param array $options
* An associative array of additional options. The 'context' key is not
* supported because the passed string is already translated. Use the
* 'langcode' key to ensure the proper plural logic is used.
*
* @return string
* The correct substring for the given $count with $args replaced.
*
* @see self::formatPlural()
* @see \Drupal\Component\Utility\SafeMarkup::format()
*/
public function formatPluralTranslated($count, $translation, array $args = array(), array $options = array());
}
......@@ -129,6 +129,30 @@ public function getStringTranslation($langcode, $string, $context) {
* {@inheritdoc}
*/
public function translate($string, array $args = array(), array $options = array()) {
$string = $this->doTranslate($string, $options);
if (empty($args)) {
return SafeMarkup::set($string);
}
else {
return SafeMarkup::format($string, $args);
}
}
/**
* Translates a string to the current language or to a given language.
*
* @param string $string
* A string containing the English string to translate.
* @param array $options
* An associative array of additional options, with the following elements:
* - 'langcode': The language code to translate to a language other than
* what is used to display the page.
* - 'context': The context the source string belongs to.
*
* @return string
* The translated string.
*/
protected function doTranslate($string, array $options = array()) {
// Merge in defaults.
if (empty($options['langcode'])) {
$options['langcode'] = $this->defaultLangcode;
......@@ -137,30 +161,27 @@ public function translate($string, array $args = array(), array $options = array
$options['context'] = '';
}
$translation = $this->getStringTranslation($options['langcode'], $string, $options['context']);
$string = $translation === FALSE ? $string : $translation;
if (empty($args)) {
return SafeMarkup::set($string);
}
else {
return SafeMarkup::format($string, $args);
}
return $translation === FALSE ? $string : $translation;
}
/**
* {@inheritdoc}
*/
public function formatPlural($count, $singular, $plural, array $args = array(), array $options = array()) {
$args['@count'] = $count;
// Join both forms to search a translation.
$translatable_string = implode(LOCALE_PLURAL_DELIMITER, array($singular, $plural));
// Translate as usual.
$translated_strings = $this->translate($translatable_string, $args, $options);
// Split joined translation strings into array.
$translated_array = explode(LOCALE_PLURAL_DELIMITER, $translated_strings);
$translated_strings = $this->doTranslate($translatable_string, $options);
return $this->formatPluralTranslated($count, $translated_strings, $args, $options);
}
/**
* {@inheritdoc}
*/
public function formatPluralTranslated($count, $translation, array $args = array(), array $options = array()) {
$args['@count'] = $count;
$translated_array = explode(LOCALE_PLURAL_DELIMITER, $translation);
if ($count == 1) {
return SafeMarkup::set($translated_array[0]);
return SafeMarkup::format($translated_array[0], $args);
}
// Get the plural index through the gettext formula.
......@@ -182,7 +203,8 @@ public function formatPlural($count, $singular, $plural, array $args = array(),
$return = $translated_array[1];
}
}
return SafeMarkup::set($return);
return SafeMarkup::format($return, $args);
}
/**
......
......@@ -131,6 +131,11 @@ public function testGetPluralFormat() {
$expected_plural_index = ($count == 1) ? 0 : $expected_plural_index;
$expected_plural_string = str_replace('@count', $count, $plural_strings[$langcode][$expected_plural_index]);
$this->assertIdentical(\Drupal::translation()->formatPlural($count, '1 hour', '@count hours', array(), array('langcode' => $langcode)), $expected_plural_string, 'Plural translation of 1 hours / @count hours for count ' . $count . ' in ' . $langcode . ' is ' . $expected_plural_string);
// DO NOT use translation to pass into formatPluralTranslated() this
// way. It is designed to be used with *already* translated text like
// settings from configuration. We use PHP translation here just because
// we have the expected result data in that format.
$this->assertIdentical(\Drupal::translation()->formatPluralTranslated($count, \Drupal::translation()->translate('1 hour' . LOCALE_PLURAL_DELIMITER . '@count hours', array(), array('langcode' => $langcode)), array(), array('langcode' => $langcode)), $expected_plural_string, 'Translated plural lookup of 1 hours / @count hours for count ' . $count . ' in ' . $langcode . ' is ' . $expected_plural_string);
}
}
}
......
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