使用 Symfony Messenger 异步发送电子邮件时如何翻译它们?
How to translate emails when sending them asynchronously with Symfony Messenger?
我将 Symfony 邮件程序配置为使用 Messenger 发送电子邮件。
https://symfony.com/doc/current/mailer.html#sending-messages-async
我的电子邮件有两种语言,我依靠请求来检测语言,但现在电子邮件没有翻译。
如何将消息翻译成请求中检测到的语言?
在我的控制器中:
$mailer->send(
$user->email,
$this->translator->trans('mails.recover.subject'),
'email/client/password-recovery.html.twig',
compact('user', 'hash', 'target')
);
模板:
{% extends 'email/base.html.twig' %}
{% block content %}
<h2>{{ 'mails.recover.header' | trans({'%name%': user.name}) }}</h2>
<p style="margin: 25px 0;">
{{ 'mails.recover.text1' | trans({'%url%': url('default')}) | raw }}
</p>
// More code
信使配置:
framework:
messenger:
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
# failure_transport: failed
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async: '%env(MESSENGER_TRANSPORT_DSN)%'
# failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
routing:
# Route your messages to the transports
# 'App\Message\YourMessage': async
'Symfony\Component\Mailer\Messenger\SendEmailMessage': async
如果翻译正确邮件主题更好看,邮件正文没有
如果我删除行
'Symfony\Component\Mailer\Messenger\SendEmailMessage': async
在 messegner 配置中,翻译工作。
您遇到的问题是 Symfony Translator 组件从传入的 请求 获取用户的语言环境,并且当邮件实际发送请求时异步发送您的邮件早已完成并消失了,然后是消息消费者(命令行)的上下文并且没有请求区域设置信息。
有两种解决方法:
第一个选项:将值已翻译传递给模板(这就是您对电子邮件主题所做的)。
例如像这样:
$mailer->send(
$user->email,
$this->translator->trans('mails.recover.subject'),
'email/client/password-recovery.html.twig',
[
'user' => $user,
'hash' => $hash,
'target' => $target,
'labels' => [
'header' => $this->translator
->trans('mails.recover.subject', [ 'name' => $user->getName()]),
'text1' => $this->translator
->trans('mails.recover.text1', ['url', => $defaulUrl])
]
);
然后在您的模板中直接使用这些值:
{% extends 'email/base.html.twig' %}
{% block content %}
<h2>{{ texts.header }}</h2>
<p style="margin: 25px 0;">{{ texts.text1 }}</p>
{% endblock %}
这是我的首选方法,因为它使模板尽可能简单并且易于在不同的上下文中重用。模板本身不需要知道任何与其内容的实际呈现无关的信息。
第二个选项:让模板系统知道您要翻译到的用户区域设置:
$mailer->send(
$user->email,
$this->translator->trans('mails.recover.subject'),
'email/client/password-recovery.html.twig',
[
'user' => $user,
'hash' => $hash,
'target' => $target,
'requestLocale' => $locale
// get the locale from the request
// (https://symfony.com/doc/current/translation/locale.html)
]
);
然后在您正在使用的过滤器中使用接收到的语言环境,如所述here:
<h2>{{ 'mails.recover.header' | trans({'%name%': user.name}, 'app', requestLocale) }}</h2>
虽然我更喜欢第一个,但使用任何一个选项都可以让您获得想要的结果。
我的解决方案也适用于树枝中的 url_absolute
。
$message = (new TemplatedEmail())
...
$renderer = new BodyRenderer($this->twig);
$renderer->render($message);
$this->mailer->send(new RawMessage($message->toString()),Envelope::create($message));
有Environment $twig
和MailerInterface $mailer
只要电子邮件内容不需要翻译,“第二个选项:让模板系统知道您要翻译的用户语言环境:”是最好的解决方案。
如果您有包含大量文本的复杂电子邮件,更好的方法是使用多个模板并让应用程序设置区域设置来决定必须使用哪个电子邮件模板。
或在模板电子邮件中。
{% if language is defined %}
{# Language still specified #}
{% else %}
{% set language = 'ne' %}
{% endif %}
{% if language == "en" %}
<h1>Ticket for - <code>{{ activity.name }}</code> by participant <code>{{ buyer.name }}</code> </h1>
{% else %}
<h1>Kaartje voor - <code>{{ activity.name }}</code> door deelnemer <code>{{ buyer.name }}</code> </h1>
{% endif %}
虽然这里的所有这些答案都很有趣,但其中 none 对我来说工作正常,并且包含“额外”变量,例如需要传递到上下文中的语言环境。
就我而言,使用最新的 Symfony 这足以在电子邮件模板中设置:
{% trans_default_domain 'emails' %}
简单调用:
{{ 'emails.whatevermessage'|trans|raw }}
很有魅力。
我将 Symfony 邮件程序配置为使用 Messenger 发送电子邮件。
https://symfony.com/doc/current/mailer.html#sending-messages-async
我的电子邮件有两种语言,我依靠请求来检测语言,但现在电子邮件没有翻译。
如何将消息翻译成请求中检测到的语言?
在我的控制器中:
$mailer->send(
$user->email,
$this->translator->trans('mails.recover.subject'),
'email/client/password-recovery.html.twig',
compact('user', 'hash', 'target')
);
模板:
{% extends 'email/base.html.twig' %}
{% block content %}
<h2>{{ 'mails.recover.header' | trans({'%name%': user.name}) }}</h2>
<p style="margin: 25px 0;">
{{ 'mails.recover.text1' | trans({'%url%': url('default')}) | raw }}
</p>
// More code
信使配置:
framework:
messenger:
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
# failure_transport: failed
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async: '%env(MESSENGER_TRANSPORT_DSN)%'
# failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
routing:
# Route your messages to the transports
# 'App\Message\YourMessage': async
'Symfony\Component\Mailer\Messenger\SendEmailMessage': async
如果翻译正确邮件主题更好看,邮件正文没有
如果我删除行
'Symfony\Component\Mailer\Messenger\SendEmailMessage': async
在 messegner 配置中,翻译工作。
您遇到的问题是 Symfony Translator 组件从传入的 请求 获取用户的语言环境,并且当邮件实际发送请求时异步发送您的邮件早已完成并消失了,然后是消息消费者(命令行)的上下文并且没有请求区域设置信息。
有两种解决方法:
第一个选项:将值已翻译传递给模板(这就是您对电子邮件主题所做的)。
例如像这样:
$mailer->send(
$user->email,
$this->translator->trans('mails.recover.subject'),
'email/client/password-recovery.html.twig',
[
'user' => $user,
'hash' => $hash,
'target' => $target,
'labels' => [
'header' => $this->translator
->trans('mails.recover.subject', [ 'name' => $user->getName()]),
'text1' => $this->translator
->trans('mails.recover.text1', ['url', => $defaulUrl])
]
);
然后在您的模板中直接使用这些值:
{% extends 'email/base.html.twig' %}
{% block content %}
<h2>{{ texts.header }}</h2>
<p style="margin: 25px 0;">{{ texts.text1 }}</p>
{% endblock %}
这是我的首选方法,因为它使模板尽可能简单并且易于在不同的上下文中重用。模板本身不需要知道任何与其内容的实际呈现无关的信息。
第二个选项:让模板系统知道您要翻译到的用户区域设置:
$mailer->send(
$user->email,
$this->translator->trans('mails.recover.subject'),
'email/client/password-recovery.html.twig',
[
'user' => $user,
'hash' => $hash,
'target' => $target,
'requestLocale' => $locale
// get the locale from the request
// (https://symfony.com/doc/current/translation/locale.html)
]
);
然后在您正在使用的过滤器中使用接收到的语言环境,如所述here:
<h2>{{ 'mails.recover.header' | trans({'%name%': user.name}, 'app', requestLocale) }}</h2>
虽然我更喜欢第一个,但使用任何一个选项都可以让您获得想要的结果。
我的解决方案也适用于树枝中的 url_absolute
。
$message = (new TemplatedEmail())
...
$renderer = new BodyRenderer($this->twig);
$renderer->render($message);
$this->mailer->send(new RawMessage($message->toString()),Envelope::create($message));
有Environment $twig
和MailerInterface $mailer
只要电子邮件内容不需要翻译,“第二个选项:让模板系统知道您要翻译的用户语言环境:”是最好的解决方案。
如果您有包含大量文本的复杂电子邮件,更好的方法是使用多个模板并让应用程序设置区域设置来决定必须使用哪个电子邮件模板。
或在模板电子邮件中。
{% if language is defined %}
{# Language still specified #}
{% else %}
{% set language = 'ne' %}
{% endif %}
{% if language == "en" %}
<h1>Ticket for - <code>{{ activity.name }}</code> by participant <code>{{ buyer.name }}</code> </h1>
{% else %}
<h1>Kaartje voor - <code>{{ activity.name }}</code> door deelnemer <code>{{ buyer.name }}</code> </h1>
{% endif %}
虽然这里的所有这些答案都很有趣,但其中 none 对我来说工作正常,并且包含“额外”变量,例如需要传递到上下文中的语言环境。
就我而言,使用最新的 Symfony 这足以在电子邮件模板中设置:
{% trans_default_domain 'emails' %}
简单调用:
{{ 'emails.whatevermessage'|trans|raw }}
很有魅力。