我需要为我的特殊目的覆盖标准 Twigtrans
过滤器,例如我想从自定义存储中获取我的翻译。所以我不知道我需要做什么。我试图在docs中弄清楚。但是没有关于翻译的描述。我找到了Symfony\Bridge\Twig\Extension\TranslationExtension
类,我想也许我只需要覆盖这个类?谢谢!
3 回答
只是为了扩展@Webberig 上面的答案,在 Symphony v3.0.4 和 Twig v1.24.0 中,定义服务的方式似乎很重要。
我想为默认的 trans() 过滤器添加域回退功能,但不知道如何覆盖默认过滤器。我终于像这样成功了:
在 app/config/services.yml
# This is important!! Use this exact service ID (twig.extension.trans)
twig.extension.trans:
class: AppBundle\Twig\AppTranslationExtension
public: false
arguments: ['@translator']
tags:
- { name: twig.extension }
这对我来说基本上是这样做的:在我的配置中使用相同的服务 ID。
其余的我只是覆盖了 trans 过滤器方法。这里是给那些感兴趣的人:
namespace AppBundle\Twig;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Component\Translation\TranslatorInterface;
class AppTranslationExtension extends TranslationExtension
{
public function __construct(
TranslatorInterface $translator,
\Twig_NodeVisitorInterface $translationNodeVisitor = null)
{
parent::__construct($translator, $translationNodeVisitor);
}
/**
* {@inheritdoc}
*/
public function getFilters()
{
return array(
new \Twig_SimpleFilter('trans', array($this, 'trans')),
);
}
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
{
if (null === $locale) {
$locale = $this->getTranslator()->getLocale();
}
if (null === $domain) {
$domain = 'messages';
}
if ('messages' !== $domain
&& false === $this->translationExists($id, $domain, $locale)) {
$domain = 'messages';
}
return $this->getTranslator()->trans($id, $parameters, $domain, $locale);
}
protected function translationExists($id, $domain, $locale)
{
return $this->getTranslator()->getCatalogue($locale)->has((string) $id, $domain);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'app_translator';
}
}
Symfony 的 Translations 组件基本上覆盖了 Twig 的默认 trans 过滤器。该组件是核心 frameworkBundle 的一部分,不能被禁用。
但是,您可以执行相同的操作并使用您自己的 Twig 扩展重新覆盖 trans 过滤器。
只需按照此处所述创建 Twig 扩展:http: //symfony.com/doc/current/cookbook/templating/twig_extension.html
如果您添加一个 trans 过滤器,它将覆盖 Translation 组件的代码。
在@Webberig 之后进行详细说明,您可以定义自己的翻译扩展而不覆盖原始扩展(IMO 很糟糕,因为您必须至少维护构造函数签名)并且只需将原始扩展用作内部服务并访问原始trans()
成员函数至应该总是public
根据定义...
# config/services.yaml
...
App\Twig\TranslationExtension:
arguments: ['@twig.extension.trans']
tags:
- { name: twig.extension, priority: 100 }
...
// src\Twig\TranslationExtension.php
namespace App\Twig;
use Symfony\Bridge\Twig\Extension\TranslationExtension as BaseTranslationExtension;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class TranslationExtension extends AbstractExtension
{
/**
* @var BaseTranslationExtension
*/
protected $inner;
public function __construct(BaseTranslationExtension $inner)
{
$this->inner = $inner;
}
public function getFilters()
{
return [
new TwigFilter('trans', [$this, 'trans']),
];
}
public function trans($message, array $arguments = [], $domain = null, $locale = null, $count = null)
{
// do ugly stuff
return $this->inner->trans($message, $arguments, $domain, $locale, $count);
}
}
(针对 SF4.2 使用)