Поддерживает ли система перевода symfony список элементов произвольной длины для объединения? - PullRequest
1 голос
/ 16 марта 2020

Мне нужно перевести предложения переменной длины в Symfony 3.4.

Пример предложения: «Включено: 4 завтрака, 1 поздний завтрак и 3 ужина».

Для примера скажем следующие ограничения:

  1. Мне нужно express количество завтраков, бранчей, обедов и ужинов, которые могут быть в путешествии по полному маршруту
  2. Список «вещей» перечислять известно и конечно. Для каждого из ключевых слов существует перевод в единственном и множественном числе.
  3. Не все из них должны появляться. Если будет 0 единиц, полный блок будет опущен.
  4. Список разделен запятыми.
  5. За исключением последнего блока, который добавляется с помощью соединителя "и".
  6. Если есть только 1 блок, нет запятой и нет соединителя "и".
  7. Каждый может быть в единственном или множественном числе.
  8. Существует несколько языков, в этом примере я буду использовать Engli sh и Spani sh, но в реальности также есть каталанский.

Ключевыми словами являются следующие: engli sh -ingular / engli sh -plural / spani sh -singular / spani sh -plural:

breakfast / breakfasts / desayuno / desayunos
brunch / brunches / alumerzo-desayuno / almuerzo-desayunos
lunch / lunches / almuerzo / almuerzos
dinner / dinners / cena / cenas

Итак ... Я могу представить себе следующие тестовые случаи:

[
    'language' => 'en-US',
    'parameters' => [
        'breakfast' => 4,
        'dinner' => 1,
    ],
    'expectedOutput' => 'Included: 4 breakfasts and 1 dinner.'
],
[
    'language' => 'es-ES',
    'parameters' => [
        'breakfast' => 2,
        'brunch' => 1,
        'lunch' => 5,
        'dinner' => 2,
    ],
    'expectedOutput' => 'Incluido: 2 desayunos, 1 desayuno-almuerzo, 5 almuerzos y 2 cenas.'
],
[
    'language' => 'en-US',
    'parameters' => [
        'breakfast' => 1,
    ],
    'expectedOutput' => 'Included: 1 breakfast.'
],
[
    'language' => 'es-ES',
    'parameters' => [
        'dinner' => 4,
        'lunch' => 3,
    ],
    'expectedOutput' => 'Incluido: 3 almuerzos y 4 cenas.'
],

Вопросы

  • Поддерживается ли это встроенным механизмом перевода в Symfony 3.4?
  • Если нет, поддерживается ли это встроенным механизмом перевода Symfony 4 или 5?
  • В противном случае, есть ли известный шаблон или стратегия, которая подходит для этого случая?

1 Ответ

0 голосов
/ 18 марта 2020

Что может сделать движок перевода, так это использовать число для переключения между разными падежами (для единственного / множественного числа). Взгляните на transChoice для symfony 3.4 (до 4.1.x очевидно). Начиная с symfony 4.2, формат сообщения ICU (следуйте также ссылкам) может использоваться для обработки множественного числа.

Однако (условное) построение строки на самом деле не является задачей для механизма перевода вообще (хотя для простых случаев transChoice или формат сообщений ICU могут работать нормально). Таким образом, вы, вероятно, в итоге соберете строки из кусочков.

Сборка строки в php

// fetch translations for the itemss
$items = [];
foreach($parameters as $key => $count) {
    if($count <= 0) {
        continue;
    } 

    $items[] = $translator->transChoice($key, $count);
}

// handle 2+ items differently from 1 item
if(count($items) > 1) {
    // get last item
    $last = array_pop($items);
    // comma-separate all other items, add last item with "and"
    $itemstring = implode(', ', $items)
        . $translator->trans('included_and') 
        . $last; 
} else {
    $itemstring = $items[0] ?? ''; // if no items or something like 
                                   // $translator->trans('included_none')
}

return $translator->trans('included', ['%items%' => $itemstring]);

и в файле перевода (engli sh):

'included' => 'Included: %items%.',
'included_and' => ' and ',
'breakfast' => '%count% breakfast|%count% breakfasts', // etc. for all other stuff

Обратите внимание, что transChoice должен автоматически установить для заполнителя %count% значение, указанное в качестве второго параметра, transChoice.

альтернативные подходы

Вы можете легко разбить переводимые строки на breakfast_singular и breakfast_plural, если вы хотите избежать использования transChoice, вам придется заменить

transChoice($key, $count)

с

trans($key.($count > 1 ? '_plural' : '_singular'), ['%count%' => $count])

Вы также можете расширить строку included до included_single и included_multiple, где последняя переводится как 'Included: %items% and %last%', с соответствующими параметрами и условиями.

В конечном счете, генерация строк или, более конкретно, генерация языка на самом деле не является задачей простого движка перевода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...