7

我有一个Symfony2项目,我正在使用Translation组件来翻译文本。我在yml文件中有所有翻译,就像这样

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. Twig(和 PHP)看起来是一样的——我仍然只指定没有后缀的标识符。然后,翻译器会将后缀附加到标识符并尝试找到匹配项。如果没有匹配,它将尝试再次找到没有后缀的匹配。

4

3 回答 3

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) 覆盖trans提供者的功能translator componenthttps://github.com/symfony/Translation/blob/master/Translator.php

希望这可以帮助!

于 2013-03-22T09:21:12.290 回答
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;
        }

    }

?>
于 2013-03-22T15:42:57.467 回答
5

从 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());
    }
}
于 2017-03-14T08:52:51.800 回答