Перевод сообщений fla sh с параметрами в Symfony 4 - PullRequest
2 голосов
/ 09 января 2020

У меня проблема с сообщениями fla sh в Symfony 4 и переводом. Перевод простых сообщений fla sh работает нормально:

$this->addFlash('success', 'flashmessage.project_deleted');

Но теперь я хочу добавить некоторые параметры к сообщениям fla sh и не знаю, как с этим справиться. Я много пробовал, но ничего не получается. Я хочу показать в сообщениях fla sh название проектов после удаления. Например:

$this->addFlash('success', sprintf('flashmessage.project_deleted: %s', $project->getTitle()));

Но перевод не распознается, потому что параметр заменяется до того, как перевод произойдет (я так думаю). И также должно быть возможным иметь параметры в середине строки, а не только в конце или в начале, в идеале более одного параметра.

Я использую это в моем контроллере, который расширяет AbstractController.

У кого-нибудь есть решение для этого?

Ответы [ 3 ]

1 голос
/ 09 января 2020

Обычно вы передаете параметры для перевода, поэтому ваш фрагмент кода, вероятно, должен выглядеть как ваш первый пример, а затем в ветке вы получите что-то вроде этого:

{% for message in app.flashes('success') %}
    <div class="alert alert-success">
       {{ message|trans({ 'title': project.title }) }}
    </div>
{% endfor %}

Тогда перевод должен содержать заменяемый параметр:

flashmessage:
     project_created: 'The project "%title%" was created successfully.'
     project_deleted: 'You successfully deleted the project "%title%".'
     ...

Очевидно, что недостатком является то, что вы должны динамически передавать переменные, что не имеет особого смысла для сообщений fla sh, поскольку не все из них потребуют эти параметры. Кроме того, как вы уже упоминали, при удалении проекта вы, вероятно, больше не будете иметь его в шаблоне.

Вместо этого я бы порекомендовал перевести сообщение перед передачей его в пакет fla sh:

$this->addFlash(
    'success',
    $this->translator->translate(
        'flashmessage.project_deleted',
        [
            'title' => $project->getTitle(),
        ]
    )
);

Для этого вам потребуется передать переводчик своему контроллеру. Для этого вы можете либо создать свой собственный базовый контроллер, подобный * AbstractController Symfony, и создать что-то вроде $this->trans() -метода, чтобы было проще переводить вещи внутри вашего контроллера. Кроме того, вам все равно нужно будет убедиться, что $project->getTitle() по-прежнему будет возвращать значение, так что вы, вероятно, захотите вызвать его, прежде чем фактически удалить запись или сохранить данные в памяти.

Когда вы делаете это, Кстати, тогда не стоит переводить сообщения fla sh в самом шаблоне, потому что они уже переведены. Это все равно будет работать, потому что когда Symfony попытается перевести уже переведенное сообщение, например, You successfully deleted the project "foo"., он не найдет перевод и вместо этого просто напечатает исходный текст, но вы получите предупреждения в своих журналах об отсутствующих переводах. Решение состоит в том, чтобы удалить |trans из вашего шаблона (см. Первый фрагмент).

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

Возможное решение - добавить еще один fla sh с сериализованными параметрами.

Затем, когда вы выводите сообщение fla sh, проверьте, существует ли этот дополнительный fla sh и, если да, десериализовать его и использовать в качестве аргумента. Пример:

В контроллере:

$this->addFlash('success', 'flashmessage.project_deleted');
$this->addFlash('_params', serialize(['%project%' => $project->getTitle()]));

В шаблоне:

{% flashMessage = app.session.flashbag.get('info') %}
{% if app.session.flashbag.has('_params') %}
    {% set flashParams = app.session.flashbag.get('_params')|first|unserialize %}
    {{ flashMessage|trans(flashParams) }}
{% else %}
    {{ flashMessage|trans }}
{% endif %}

Вам необходимо создать расширение Twig, определяющее фильтр unserialize (или использовать библиотека, которая обеспечивает это)

0 голосов
/ 09 января 2020

Посмотрите на формат сообщения ICU: https://symfony.com/doc/current/translation/message_format.html

...