php 强制 Twig 语言环境
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15266673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Forcing the Twig Locale
提问by rolandow
I would like to use the Twig template system to template my e-mails. The locale of the e-mail should be based on a user setting, not from the session or request locale. How can I force the locale when rendering a Twig template?
我想使用 Twig 模板系统来模板化我的电子邮件。电子邮件的区域设置应基于用户设置,而不是会话或请求区域设置。渲染 Twig 模板时如何强制使用语言环境?
The manual does mention how to force the locale for the Translator. But i'd like pass this locale to the render() method, in order to have the translations inside the twig template to be rendered in this locale.
该手册确实提到了如何强制 Translator 的语言环境。但我想将此语言环境传递给 render() 方法,以便在此语言环境中呈现树枝模板内的翻译。
This is different from using intoin the template, because I think this forces a translation inside the template in a specific locale.
这与在模板中使用into不同,因为我认为这会强制在特定语言环境中的模板内部进行翻译。
So, taking the example from Symfony, I'm looking for something like this:
所以,以 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(...);
}
回答by Mark
You can pass the locale through as an argument when you use the trans filter (see diff: https://github.com/symfony/symfony/commit/3ea31a02630412b1c732ee1647a0724378f67665).
当您使用 trans 过滤器时,您可以将语言环境作为参数传递(参见差异:https: //github.com/symfony/symfony/commit/3ea31a02630412b1c732ee1647a0724378f67665)。
So you could pass another user_locale variable in your render method in your controller (or pass through the whole user object instead of passing name and user_locale separately, or use app.user in your template if the user will be logged in, etc... (depending on your application obviously)), then in your email template you can have something like this:
因此,您可以在控制器的渲染方法中传递另一个 user_locale 变量(或传递整个用户对象,而不是分别传递 name 和 user_locale,或者如果用户将登录,则在模板中使用 app.user 等... (显然取决于您的应用程序)),然后在您的电子邮件模板中,您可以拥有如下内容:
{{ 'greeting' | trans({}, "messages", user_locale) }} {{ name | title }}
{# rest of email template with more translation strings #}
Then in your translation file for that locale (assuming you're using yaml) just have something like this and the translations will work nicely for you on the fly:
然后在该语言环境的翻译文件中(假设您使用的是 yaml),只要有这样的东西,翻译就会很好地为您工作:
# messages.fr.yml
greeting: 'Bonjour'
回答by Marcel Hernandez
Get a hold of the Translator component and change its locale before rendering the template. This solution does notrequire passing an extra value to the parameters' array of the render() method and painfully refactoring all your Twig files.
在呈现模板之前获取翻译组件并更改其区域设置。此解决方案不需要将额外的值传递给 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]')
->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(...);
}
A common approach to user mailing is storing the user's locale in the User entity and passing it directly to the translator, such as in this code snippet:
用户邮寄的一种常见方法是将用户的语言环境存储在 User 实体中并将其直接传递给翻译器,例如在以下代码片段中:
$translator->setLocale($recipientUser->getLocale());
回答by Osoian Marcel
Here is a solution (it works well, except sub-templates (Twig: render(controller('AppBundle:Invoice/Index:productTotalPartial')))
这是一个解决方案(它运行良好,除了子模板(Twig:render(controller('AppBundle:Invoice/Index: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) {
}
}
}
Example:
例子:
if ($this->getLocale()) {
$this->localeSwitcher->setLocale($this->getLocale());
}
$html = $this->templating->render($templatePath);
if ($this->getLocale()) {
$this->localeSwitcher->revertLocale();
}
回答by Lhassan Baazzi
u can do this: send a paramater (e.g. locale) to template
你可以这样做:发送一个参数(例如语言环境)到模板
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(...);
}

