强制树枝区域设置

2022-08-30 14:14:43

我想使用Twig模板系统来模板化我的电子邮件。电子邮件的区域设置应基于用户设置,而不是来自会话或请求区域设置。如何在渲染 Twig 模板时强制使用区域设置?

该手册确实提到了如何强制翻译器的区域设置。但是我想将此区域设置传递给 render() 方法,以便在此区域设置中呈现树枝模板内的翻译。

这与在模板中使用 into 不同,因为我认为这会在特定区域设置中强制在模板内进行翻译。

所以,以Symfony为例,我正在寻找这样的东西:

public function indexAction($name)
{
    $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('send@example.com')
        ->setTo('recipient@example.com')
        ->setBody(
            $this->renderView(
                'HelloBundle:Hello:email.txt.twig',
                array('name' => $name),
                'nl_NL' // <-- This would be nice!
            )
        )
    ;
    $this->get('mailer')->send($message);

    return $this->render(...);
}

答案 1

使用 trans 筛选器时,可以将区域设置作为参数传递(请参阅 diff:https://github.com/symfony/symfony/commit/3ea31a02630412b1c732ee1647a0724378f67665)。

因此,您可以在控制器的渲染方法中传递另一个user_locale变量(或者传递整个用户对象而不是单独传递名称和user_locale,或者在模板中使用app.user(如果用户将登录),等等...(显然取决于您的应用程序)),然后在您的电子邮件模板中,您可以拥有如下内容:

{{ 'greeting' | trans({}, "messages", user_locale) }} {{ name | title }}
{# rest of email template with more translation strings #}

然后在该区域的翻译文件中(假设您使用的是 yaml),只需有类似这样的东西,翻译就会在飞行中很好地为您工作:

# messages.fr.yml    
greeting: 'Bonjour'

答案 2

在呈现模板之前,请先获取转换器组件并更改其区域设置。此解决方案不需要将额外的值传递给 render() 方法的参数数组,也不需要痛苦地重构所有 Twig 文件。

public function indexAction($name)
{
    $translator = $this->get('translator');

    // Save the current session locale
    // before overwriting it. Suppose its 'en_US'
    $sessionLocale = $translator->getLocale();

    $translator->setLocale('nl_NL');

    $message = \Swift_Message::newInstance()
        ->setSubject('Hello Email')
        ->setFrom('send@example.com')
        ->setTo('recipient@example.com')
        ->setBody(
            $this->renderView(
                'HelloBundle:Hello:email.txt.twig',
                array('name' => $name)
            )
        )
    ;

    $this->get('mailer')->send($message);

    // Otherwise subsequent templates would also
    // be rendered in Dutch instead of English
    $translator->setLocale($sessionLocale);

    return $this->render(...);
}

用户邮件的一种常见方法是将用户的区域设置存储在 User 实体中,并将其直接传递给转换器,例如在以下代码段中:

$translator->setLocale($recipientUser->getLocale());

推荐