6

我需要为我的特殊目的覆盖标准 Twigtrans过滤器,例如我想从自定义存储中获取我的翻译。所以我不知道我需要做什么。我试图在docs中弄清楚。但是没有关于翻译的描述。我找到了Symfony\Bridge\Twig\Extension\TranslationExtension类,我想也许我只需要覆盖这个类?谢谢!

4

3 回答 3

4

只是为了扩展@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';
    }
}
于 2016-04-29T11:00:21.357 回答
2

Symfony 的 Translations 组件基本上覆盖了 Twig 的默认 trans 过滤器。该组件是核心 frameworkBundle 的一部分,不能被禁用。

但是,您可以执行相同的操作并使用您自己的 Twig 扩展重新覆盖 trans 过滤器。

只需按照此处所述创建 Twig 扩展:http: //symfony.com/doc/current/cookbook/templating/twig_extension.html

如果您添加一个 trans 过滤器,它将覆盖 Translation 组件的代码。

于 2015-04-15T14:36:24.867 回答
0

在@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 使用)

于 2019-02-13T09:47:39.923 回答