2013-03-07 34 views
25

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

该手册确实提到了如何to force the locale for the Translator。但是我想将这个语言环境传递给render()方法,以便在该语言环境中呈现树枝模板内部的翻译。

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

因此,采取从Symfony的例子,我在寻找这样的事情:

public function indexAction($name) 
{ 
    $message = \Swift_Message::newInstance() 
     ->setSubject('Hello Email') 
     ->setFrom('[email protected]') 
     ->setTo('[email protected]') 
     ->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(...); 
} 

回答

27

你可以在使用反式过滤器时将区域设置作为参数传递(请参阅diff:https://github.com/symfony/symfony/commit/3ea31a02630412b1c732ee1647a0724378f67665)。

所以你可以在你的控制器的render方法中传递另一个user_locale变量(或者通过整个用户对象而不是单独传递name和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' 
0

U可以做到这一点:发送paramater(如语言环境)到模板

public function indexAction($name) 
{ 
    $message = \Swift_Message::newInstance() 
     ->setSubject('Hello Email') 
     ->setFrom('[email protected]') 
     ->setTo('[email protected]') 
     ->setBody(
      $this->renderView(
       'HelloBundle:Hello:email.txt.twig', 
       array('name' => $name, 'locale' => 'nl_NL'), 
      ) 
     ) 
    ; 
    $this->get('mailer')->send($message); 

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

是的,但我不认为模板会自动为{%trans%}块使用此区域设置,是不是? – rolandow 2013-03-08 12:52:35

+4

不,你可以强制转换过滤器使用语言环境,你想'{{“Hello”| trans({},“messages”,locale)}}',翻译器组件自动使用请求中定义的语言环境,if你想改变它'$ this-> get('translator') - > setLocale($ locale);' – 2013-03-25 09:47:27

12

在呈现模板之前获取转换器组件并更改其区域设置。这个解决方案不需要需要传递一个额外的值给参数的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('[email protected]') 
     ->setTo('[email protected]ple.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(...); 
} 

到用户的邮件的常用方法是存储用户的语言环境中的用户实体,并直接传递给翻译,如在此代码段:

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

包含的子模板不受影响 – 2015-11-03 06:11:33

0

这里是一个溶液(它运作良好,除了子模板(嫩枝:渲染(控制器( '的appbundle:发票/索引:productTotalPartial')))

<?php 

namespace Main\BoBundle\Service; 

use Symfony\Component\Translation\TranslatorInterface; 

/** 
* Class LocaleSwitcher 
* 
* @package Main\BoBundle\Service 
*/ 
class LocaleSwitcher 
{ 
    /** 
    * @var TranslatorInterface 
    */ 
    private $translator; 

    /** 
    * @var string 
    */ 
    private $previousLocale; 

    /** 
    * @param TranslatorInterface $translator 
    */ 
    public function __construct(TranslatorInterface $translator) 
    { 
     $this->translator = $translator; 
    } 

    /** 
    * Change the locale 
    * 
    * @param string $locale 
    */ 
    public function setLocale($locale) 
    { 
     $this->previousLocale = $this->translator->getLocale(); 

     $this->translator->setLocale($locale); 
     $this->setPhpDefaultLocale($locale); 
    } 

    /** 
    * Revert the locale 
    */ 
    public function revertLocale() 
    { 
     if ($this->previousLocale === null) { 
      return; 
     } 

     $this->translator->setLocale($this->previousLocale); 
     $this->setPhpDefaultLocale($this->previousLocale); 

     $this->previousLocale = null; 
    } 

    /** 
    * Use temporary locale in closure function 
    * 
    * @param string $locale 
    * @param \Closure $c 
    */ 
    public function temporaryLocale($locale, \Closure $c) 
    { 
     $this->setLocale($locale); 

     $c(); 

     $this->revertLocale(); 
    } 

    /** 
    * Sets the default PHP locale. 
    * Copied from Symfony/Component/HttpFoundation/Request.php 
    * 
    * @param string $locale 
    */ 
    private function setPhpDefaultLocale($locale) 
    { 
     // if either the class Locale doesn't exist, or an exception is thrown when 
     // setting the default locale, the intl module is not installed, and 
     // the call can be ignored: 
     try { 
      if (class_exists('Locale', false)) { 
       /** @noinspection PhpUndefinedClassInspection */ 
       \Locale::setDefault($locale); 
      } 
     } catch (\Exception $e) { 
     } 
    } 
} 

实施例:

if ($this->getLocale()) { 
    $this->localeSwitcher->setLocale($this->getLocale()); 
} 

$html = $this->templating->render($templatePath); 

if ($this->getLocale()) { 
    $this->localeSwitcher->revertLocale(); 
}