使用 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配置中,翻译工作。


慕码人8056858
浏览 168回答 4
4回答

慕村225694

您遇到的问题是,Symfony Translator 组件从传入请求中获取用户的区域设置,并且在实际发送邮件时异步发送邮件时,请求早已完成并消失,然后消息使用者的上下文(命令行)并且没有请求区域设置信息。对此有两种解决方案:第一个选项:您将已翻译的值传递到模板(这就是您对电子邮件主题所做的操作)。例如这样的事情:$mailer->send(&nbsp; &nbsp; &nbsp; &nbsp; $user->email,&nbsp; &nbsp; &nbsp; &nbsp; $this->translator->trans('mails.recover.subject'),&nbsp; &nbsp; &nbsp; &nbsp; 'email/client/password-recovery.html.twig',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'user' => $user,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'hash' => $hash,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'target' => $target,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'labels' => [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'header' => $this->translator&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;->trans('mails.recover.subject', [ 'name' => $user->getName()]),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'text1'&nbsp; => $this->translator&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ->trans('mails.recover.text1', ['url', => $defaulUrl])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]);然后在模板中直接使用这些值:{% extends 'email/base.html.twig' %}{% block content %}&nbsp; &nbsp; <h2>{{ texts.header }}</h2>&nbsp; &nbsp; <p style="margin: 25px 0;">{{ texts.text1 }}</p>{% endblock %}这将是我的首选方法,因为它使模板尽可能愚蠢并且易于在不同上下文中重用。模板本身不需要知道与其内容的实际呈现无关的任何内容。第二个选项:让模板系统知道您想要转换为的用户区域设置:$mailer->send(&nbsp; &nbsp; &nbsp; &nbsp; $user->email,&nbsp; &nbsp; &nbsp; &nbsp; $this->translator->trans('mails.recover.subject'),&nbsp; &nbsp; &nbsp; &nbsp; 'email/client/password-recovery.html.twig',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'user'&nbsp; &nbsp;=> $user,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'hash'&nbsp; &nbsp;=> $hash,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'target' => $target,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'requestLocale' =>&nbsp; $locale&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // get the locale from the request&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // (https://symfony.com/doc/current/translation/locale.html)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]);然后,您可以在正在使用的过滤器中使用接收到的区域设置,如下所述:<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

一只名叫tom的猫

只要电子邮件内容不需要翻译,“第二个选项:让模板系统知道您想要翻译成的用户区域设置:”就是最佳解决方案。如果您有包含大量文本的复杂电子邮件,更好的方法是使用多个模板,并让应用程序设置区域设置决定必须使用哪个电子邮件模板。或者在模板电子邮件中。{% if language is defined %}&nbsp; &nbsp; {# Language still specified #}&nbsp; &nbsp;&nbsp;{% else %}&nbsp; &nbsp; {% set language = 'ne' %}{% endif %}{% if language == "en" %}&nbsp; &nbsp; <h1>Ticket for - <code>{{ activity.name }}</code> by participant <code>{{ buyer.name }}</code> </h1>{% else %}&nbsp; &nbsp; <h1>Kaartje voor - <code>{{ activity.name }}</code> door deelnemer <code>{{ buyer.name }}</code> </h1>{% endif %}

白猪掌柜的

虽然这里所有这些答案都很有趣,但它们都不适合我,并且包含“额外”变量,例如需要传递到上下文中的语言环境。就我而言,使用最新的 Symfony 这足以在电子邮件模板中设置:{%&nbsp;trans_default_domain&nbsp;'emails'&nbsp;%}简单的调用:{{&nbsp;'emails.whatevermessage'|trans|raw&nbsp;}}奇迹般有效。
打开App,查看更多内容
随时随地看视频慕课网APP