В этой короткой статье я покажу преимущества функции wirePopulateStringTags
.
спринт
Обычно при переводе строки с переменными в ней вы будете использовать функцию sprintf
следующим образом:
echo sprintf(__('There are %d %s in the %s'), $count, $items, $place));
Рендеринг чего-то похожего на There are 32 apples in the basket
.
Но у этого подхода есть один недостаток. В системе управления переводом будет отображаться что-то вроде There are %d %s in the %s
, что означает, что вы должны полагаться на комментарии, чтобы дать больше контекста, чтобы переводчик мог создать правильный перевод.
wirePopulateStringTags
Эта функция доступна в ядре ProcessWire. ( https://github.com/processwire/processwire/blob/master/wire/core/Functions.php#L369).
function wirePopulateStringTags($str, $vars, array $options = array())
Для строки $str
и значений $vars
замените теги в строке значениями. $vars
также может быть объектом, и в этом случае значения будут извлечены как свойства объекта. По умолчанию теги указываются в следующем формате: {first_name}
, где first_name
- имя переменной, из которой нужно извлечь $vars
, ‘{‘
- символ открывающего тега, а ‘}’
- символ закрывающего тега. Парсер тегов также может обрабатывать подполя и теги OR, если $vars
- это объект, который это поддерживает. Например, {products.title}
- это подполе, а {first_name|title|name}
- тег ИЛИ.
Эта замечательная функция позволит более читаемым строкам в управлении переводом.
Используя предыдущий пример:
echo wirePopulateStringTags( __('There are {count} {items} in the {place}'), ['items' => 'apples', 'count' => 32, 'place' => 'basket'] );
Будет отображено что-то похожее на There are 32 apples in the basket
. И переводчик увидит There are {count} {items} in the {place}
. На мой взгляд, намного лучше, чем использовать vanillasprintf
. Другое преимущество заключается в том, что переводчик может легко изменить порядок и при необходимости повторить значение.
Используя оба
Как насчет того, когда вам нужно вывести форматированные значения ?. Например, используя эту строку The percentage is %1.1f%%
. Будет отображено что-то похожее на The percentage is 50.2%
.
Смешать обе функции очень просто. Просто примените форматирование перед отправкой параметров функции wirePopulateStringTags
.
echo wirePopulateStringTags( __('The percentage is {percent}'), ['percent' => sprintf('%1.1f%%', 50.1994)] );
Используя этот подход, мы отделяем презентацию от реализации. Теперь переводчик мог легко выполнять свою работу, не задумываясь о том, что означает %d
или %s
.
Сокращенная версия
Это специальная функция, объединяющая wirePopulateStringTags()
и __()
. Вы можете поместить его в файл ready.php
, чтобы он был доступен для всего сайта.
/** * Perform a language translation replacing string tags. * * Used as an alternative to sprintf in language string that requires variables. * uses wirePopulateStringTags function for replacing tags. * * The $vars may also be an object, in which case values will be pulled as properties of the object. * * By default, tags are specified in the format: {first_name} where first_name is the name of the * variable to pull from $vars, '{' is the opening tag character, and '}' is the closing tag char. * * The tag parser can also handle subfields and OR tags, if $vars is an object that supports that. * For instance {products.title} is a subfield, and {first_name|title|name} is an OR tag. * * @param string $text Text for translation. * @param WireData|object|array $vars Object or associative array to pull replacement values from. * @param string $context Name of context * @param string $textdomain Textdomain for the text, may be class name, filename, or something made up by you. If omitted, a debug backtrace will attempt to determine automatically. * @param array $options Array of optional changes to default behavior, including: * - tagOpen: The required opening tag character(s), default is '{' * - tagClose: The optional closing tag character(s), default is '}' * - recursive: If replacement value contains tags, populate those too? Default=false. * - removeNullTags: If a tag resolves to a NULL, remove it? If false, tag will remain. Default=true. * - entityEncode: Entity encode the values pulled from $vars? Default=false. * - entityDecode: Entity decode the values pulled from $vars? Default=false. * @return string Translated text or original text if translation not available. * */ function _st($text, $vars, $context = null, $textdomain = null, array $options = array()) { return wirePopulateStringTags(__($text, $textdomain, $context), $vars, $options); }
Пример использования
echo _st('There are {count} {items} in the {place}', ['count' => 5, 'items' => 'oranges', 'place' => 'tree']);
Заключение
ProcessWire реализует множество функций, которые могут облегчить нам жизнь как разработчикам. Функцию wirePopulateStringTags
можно использовать для улучшения процесса перевода с использованием именованных заполнителей вместо форматов проверки типов.