在Symfony2中高级定制翻译
我有一个Symfony2
项目,我正在使用Translation
组件翻译文本。我在yml
文件中所有的翻译,像这样在Symfony2中高级定制翻译
translation-identifier: Translated text here
翻译文本看起来像这样从Twig
'translation-identifier'|trans({}, 'domain')
的事情是,在某些情况下,我想有同样的翻译两个不同的文本(不适用于复数)。这是我想它是如何工作的:
-
定义在
yml
文件两份案文为需要有不同的文本翻译。每个将有它自己独特的后缀translation-identifier-suffix1 translation-identifier-suffix2
-
定义全球规则,将定义哪些后缀应作为选。下面的伪代码:
public function getSuffix() { return rand(0, 10) < 5 ? '-suffix1' : '-suffix2'; }
嫩枝(和PHP)将看起来是一样的 - 我还是只指定标识不带后缀。翻译员然后将追加后缀到标识符并尝试找到一个匹配。如果没有匹配,它会尝试再次找到没有后缀的匹配。
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
希望这有助于!
这里是任何人的情况下扩展的翻译类永远需要它
<?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;
}
}
?>
因为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());
}
}
作为一种替代方法,您还可以修饰现有翻译器:https://symfony.com/doc/current/service_container/service_decoration.html – Markus 2017-07-27 12:30:51
谢谢,我得到它的工作 – 2013-03-22 15:40:27
谢谢。这个对我有用。 – bharatesh 2015-03-20 17:08:52
这不再与Symfony 3一起工作。有关另一个解决方案,请看下面。 – Markus 2017-07-27 12:31:22