2013-03-21 82 views
7

我有一個Symfony2項目,我正在使用Translation組件翻譯文本。我在yml文件中所有的翻譯,像這樣在Symfony2中高級定製翻譯

translation-identifier: Translated text here 

翻譯文本看起來像這樣從Twig

'translation-identifier'|trans({}, 'domain') 

的事情是,在某些情況下,我想有同樣的翻譯兩個不同的文本(不適用於複數)。這是我想它是如何工作的:

  1. 定義在yml文件兩份案文爲需要有不同的文本翻譯。每個將有它自己獨特的後綴

    translation-identifier-suffix1 
    
    translation-identifier-suffix2 
    
  2. 定義全球規則,將定義哪些後綴應作爲選。下面的僞代碼:

    public function getSuffix() { 
        return rand(0, 10) < 5 ? '-suffix1' : '-suffix2'; 
    } 
    
  3. 嫩枝(和PHP)將看起來是一樣的 - 我還是隻指定標識不帶後綴。翻譯員然後將追加後綴到標識符並嘗試找到一個匹配。如果沒有匹配,它會嘗試再次找到沒有後綴的匹配。

回答

9

AFAIK,翻譯器組件不支持它。

但是,如果您想要同樣的行爲,您可以通過覆蓋翻譯器服務來完成。

1)覆蓋服務

# app/config/config.yml 
parameters: 
    translator.class:  Acme\HelloBundle\Translation\Translator 

首先,你可以設置參數在app/config/config.yml設置它持有該服務的類名,以你自己的類。 供參考:https://github.com/symfony/FrameworkBundle/blob/master/Resources/config/translation.xml

2)擴展翻譯類提供symfony framework bundle。 供參考:https://github.com/symfony/FrameworkBundle/blob/master/Translation/Translator.php

3)覆蓋由translator component提供的trans函數。 https://github.com/symfony/Translation/blob/master/Translator.php

希望這有助於!

+0

謝謝,我得到它的工作 – 2013-03-22 15:40:27

+0

謝謝。這個對我有用。 – bharatesh 2015-03-20 17:08:52

+0

這不再與Symfony 3一起工作。有關另一個解決方案,請看下面。 – Markus 2017-07-27 12:31:22

5

這裏是任何人的情況下擴展的翻譯類永遠需要它

<?php 

    namespace Acme\HelloBundle\Translation; 

    use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator; 
    use Symfony\Component\Translation\MessageSelector; 
    use Symfony\Component\DependencyInjection\ContainerInterface; 

    class Translator extends BaseTranslator { 

     const SUFFIX_1 = '_suffix1'; 
     const SUFFIX_2 = '_suffix2'; 

     private $suffix; 

     public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array()) { 
      parent::__construct($container, $selector, $loaderIds, $options); 
      $this->suffix = $this->getSuffix($container); 
     } 

     public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null) {  
      if ($locale === null) 
       $locale = $this->getLocale(); 

      if (!isset($this->catalogues[$locale])) 
       $this->loadCatalogue($locale); 

      if($this->suffix !== null && $this->catalogues[$locale]->has((string) ($id . $this->suffix), $domain)) 
       $id .= $this->suffix; 

      return strtr($this->catalogues[$locale]->get((string) $id, $domain), $parameters); 
     } 

     private function getSuffix($container) { 
      return rand(0, 10) < 5 ? self::SUFFIX_1 : self::SUFFIX_2; 
     } 

    } 

?> 
2

因爲symfony 3,VENU的回答不再完全適用,因爲translator.class參數不再使用。

要載入您的自定義翻譯器類,您現在需要創建一個編譯器傳遞。

<?php 

namespace Acme\HelloBundle\DependencyInjection\Compiler; 

use Acme\HelloBundle\Translation\Translator; 
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

class TranslatorOverridePass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $container->getDefinition('translator.default')->setClass(Translator::class); 
    } 
} 

而這個編譯過程需要被添加到容器中。

<?php 

namespace Acme\HelloBundle; 

use Acme\HelloBundle\DependencyInjection\Compiler\TranslatorOverridePass; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 
use Symfony\Component\HttpKernel\Bundle\Bundle; 

class AcmeHelloBundle extends Bundle 
{ 
    public function build(ContainerBuilder $container) 
    { 
     $container->addCompilerPass(new TranslatorOverridePass()); 
    } 
} 
+2

作爲一種替代方法,您還可以修飾現有翻譯器:https://symfony.com/doc/current/service_container/service_decoration.html – Markus 2017-07-27 12:30:51