【问题标题】:Replacing the Translator service in Symfony 3替换 Symfony 3 中的 Translator 服务
【发布时间】:2016-09-13 12:52:24
【问题描述】:

在我的 Symfony 2.8 项目中,我有一个扩展,它为 trans 方法添加了一些额外的逻辑:

parameters:
    translator.class: MyBundle\Twig\TranslationExtension

类如下所示:

namespace MyBundle\Twig\TranslationExtension;

use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;

class TranslationExtension extends BaseTranslator
{
    private $currentLocale;

    public function trans($id, array $parameters = array(), $domain = null, $locale = null)
    {
            $translation = parent::trans($id, $parameters, $domain, $locale);

            // Some extra logic here

            return $translation;
    }

    public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
    {
        return parent::transChoice($id, $number, $parameters, $domain, $locale);
    }
}

现在,我正在迁移到 Symfony 3,这些类参数已被弃用,但我如何通过覆盖 translator 服务来实现这一点?

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    与其扩展,不如装饰translator服务。现在你覆盖了类名,这也将覆盖其他想要装饰服务的包。我看到你因为 Twig 做了一个扩展,原来的 Twig {{ trans() }} 过滤器也将使用装饰服务。

    services:
      app.decorating_translator:
        class:     AppBundle\DecoratingTranslator
        decorates: translator
        arguments: ['@app.decorating_translator.inner'] # original translator
        public:    false
    

    在此处查看有关装饰的文档:http://symfony.com/doc/current/service_container/service_decoration.html

    【讨论】:

      【解决方案2】:

      这里是完整的工作示例,如何在 symfony 3 中装饰翻译服务并替换所有翻译字符串中的参数。

      在配置中装饰服务:

      # app/config/services.yml
      app.decorating_translator:
          class:     AppBundle\Translation\Translator
          decorates: translator
          arguments:
              - '@app.decorating_translator.inner'
              # passing custom parameters
              - {'%%app_name%%': '%app_name%', '%%PRETTY_ERROR%%': 'This is not nice:'}
          public:    false
      

      创建重用原始翻译器并添加服务配置中定义的参数的新翻译器。唯一的新代码是updateParameters() 方法并调用它:

      # AppBundle/Translation/Translator.php
      namespace AppBundle\Translation;
      
      use Symfony\Component\Translation\TranslatorBagInterface;
      use Symfony\Component\Translation\TranslatorInterface;
      
      class Translator implements TranslatorInterface, TranslatorBagInterface
      {
          /** @var TranslatorBagInterface|TranslatorInterface */
          protected $translator;
          /** @var array */
          private $parameters;
      
          /**
           * @param TranslatorInterface|TranslatorBagInterface $translator
           * @param array                                      $parameters
           */
          public function __construct($translator, $parameters)
          {
              $this->translator = $translator;
              $this->parameters = $parameters;
          }
      
          /**
           * @param string $id
           * @param array  $parameters
           * @param null   $domain
           * @param null   $locale
           *
           * @return string
           */
          public function trans($id, array $parameters = [], $domain = null, $locale = null)
          {
              $parameters = $this->updateParameters($parameters);
      
              return $this->translator->trans($id, $parameters, $domain, $locale);
          }
      
          /**
           * @param string $id
           * @param int    $number
           * @param array  $parameters
           * @param null   $domain
           * @param null   $locale
           *
           * @return string
           */
          public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null)
          {
              $parameters = $this->updateParameters($parameters);
      
              return $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
          }
      
          /**
           * @param string $locale
           */
          public function setLocale($locale)
          {
              $this->translator->setLocale($locale);
          }
      
          /**
           * @return string
           */
          public function getLocale()
          {
              return $this->translator->getLocale();
          }
      
          /**
           * @param string|null $locale
           *
           * @return \Symfony\Component\Translation\MessageCatalogueInterface
           */
          public function getCatalogue($locale = null)
          {
              return $this->translator->getCatalogue($locale);
          }
      
          /**
           * @param array $parameters
           *
           * @return array
           */
          protected function updateParameters($parameters)
          {
              return array_merge($this->parameters, $parameters);
          }
      }
      

      现在每次翻译消息时,%app_config% 将替换为配置中的参数(例如 parameters.yml),%PRETTY_ERROR% 将替换为静态字符串。 如果需要,可以在调用 trans 时覆盖相同的参数:

      {{ 'layout.title.home'|trans({'%app_name%': 'Real App No. 1'}) }}

      了解服务装饰here

      【讨论】:

        【解决方案3】:

        @Aurelijus 罗泽纳斯:

        将此添加到您的翻译器中:

        public function __call($method, $args)
        {
            return \call_user_func_array(array($this->translator, $method), $args);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-22
          • 1970-01-01
          • 1970-01-01
          • 2012-11-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多