У меня есть проект Symfony2
и я использую компонент Translation
для перевода текста. У меня есть все переводы в yml
файле
translation-identifier: Translated text here
Перевод текста выглядит так: Twig
'translation-identifier'|trans({}, 'domain')
Дело в том, что в некоторых случаях я хотел бы иметь два разных текста для одного перевода (а не для плюрализации ). Вот как я хотел бы, чтобы он работал:
Определите два текста в yml
файле для переводов, которые должны иметь разные тексты. У каждого будет свой собственный уникальный суффикс
translation-identifier-suffix1 translation-identifier-suffix2
Определите глобальное правило, определяющее, какой суффикс следует выбрать. Psuedocode ниже:
public function getSuffix() { return rand(0, 10) < 5 ? '-suffix1' : '-suffix2'; }
Twig (и PHP) будут выглядеть одинаково – я бы все же указал только идентификатор без суффикса. Затем переводчик добавит суффикс к идентификатору и попытается найти совпадение. Если совпадение не будет, оно попытается найти совпадение без суффикса.
AFAIK, компонент Translator не поддерживает его.
Но если вы хотите такого же поведения, вы можете сделать, переопределив услугу переводчика.
1) Отменить службу
# app/config/config.yml parameters: translator.class: Acme\HelloBundle\Translation\Translator
Во-первых, вы можете установить параметр, содержащий имя класса службы, в свой собственный класс, установив его в app/config/config.yml
. FYI: https://github.com/symfony/FrameworkBundle/blob/master/Resources/config/translation.xml
2) Расширьте класс переводчика, предоставляемый symfony framework bundle
. FYI: https://github.com/symfony/FrameworkBundle/blob/master/Translation/Translator.php
3) Перезаписать функцию trans
которая является поставщиком по translator component
. 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()); } }