我有这种情况:
unit:
sqkm: Square Kilometers
my_translation: Size is %size% ## I want to append the value of unit.sqkm here ##
有没有办法引用unit.sqkm
里面my_translation
键的翻译?
编辑:请注意,我确实知道如何通过 twig 做到这一点。我的问题是:有没有办法在翻译文件中做到这一点。
我有这种情况:
unit:
sqkm: Square Kilometers
my_translation: Size is %size% ## I want to append the value of unit.sqkm here ##
有没有办法引用unit.sqkm
里面my_translation
键的翻译?
编辑:请注意,我确实知道如何通过 twig 做到这一点。我的问题是:有没有办法在翻译文件中做到这一点。
我为此扩展了 Symfony Tanslator:
<?php
namespace Bundle\Program\Translation;
use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;
class Translator extends BaseTranslator
{
/**
* Uses Symfony Translator to translate, but enables referencing other translations via @@code@@
*/
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
{
$text = parent::trans($id, $parameters, $domain, $locale);
$translations = [];
$delimiter = "@@";
$strLen = strlen($delimiter);
$pos = strpos($text, $delimiter);
while ($pos !== false) {
$startsAt = $pos + $strLen;
$endsAt = strpos($text, $delimiter, $startsAt);
$translations[] = $delimiter . substr($text, $startsAt, $endsAt - $startsAt) . $delimiter;
$pos = strpos($text, $delimiter, $endsAt + $strLen);
}
foreach ($translations as $translation) {
$translationTrim = str_replace($delimiter, '', $translation);
$text = str_replace($translation, $this->trans($translationTrim, $parameters, $domain, $locale), $text);
}
return $text;
}
}
然后通过参数替换 Symfony 翻译器类:
parameters:
translator.class: Bundle\Program\Translation\Translator
现在,您可以通过 @@other.translation@@ INSIDE 引用其他翻译。
在你的 Twig 模板中,试试这个:
{{ 'my_translation' | trans({'%size%': size, 'unit.sqkm' : ('unit.sqkm'|trans)}) }}
您可以在其他翻译中使用翻译后的值。
{{ 'paragraph' | trans({ '%size%': 3, '%unit%': 'unit' | trans()}) }}
whereunit
本身是翻译的另一个关键。但是,您的翻译文件可能如下所示:
paragraph: Size is %size% %unit%
unit: Square Kilometers
如果像我一样,你想在 Symfony 4.1 中实现这一点,这就是你的解决方案(非常感谢@Kim的回答和@Aurelijus Rozenas的回答,除了我的 4 小时尝试之外,所有的功劳都归于他们)
首先,创建新的 Translator 类(此处:src /Common/ReferenceTranslator.php)
# src/Common/ReferenceTranslator.php
namespace App\Common;
use Symfony\Component\Translation\TranslatorBagInterface;
use Symfony\Component\Translation\TranslatorInterface;
class ReferenceTranslator implements TranslatorInterface, TranslatorBagInterface
{
/** @var TranslatorBagInterface|TranslatorInterface */
protected $translator;
/**
* @param TranslatorInterface|TranslatorBagInterface $translator
*/
public function __construct($translator)
{
$this->translator = $translator;
}
/**
* Uses Symfony Translator to translate, but enables referencing other translations via @@code@@
* @param $id
* @param array $parameters
* @param null $domain
* @param null $locale
* @return mixed|string
*/
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
{
$text = $this->translator->trans($id, $parameters, $domain, $locale);
$translations = [];
$delimiter = "@@";
$strLen = strlen($delimiter);
$pos = strpos($text, $delimiter);
while ($pos !== false) {
$startsAt = $pos + $strLen;
$endsAt = strpos($text, $delimiter, $startsAt);
$translations[] = $delimiter . substr($text, $startsAt, $endsAt - $startsAt) . $delimiter;
$pos = strpos($text, $delimiter, $endsAt + $strLen);
}
foreach ($translations as $translation) {
$translationTrim = str_replace($delimiter, '', $translation);
$text = str_replace($translation, $this->trans($translationTrim, $parameters, $domain, $locale), $text);
}
return $text;
}
/**
* @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)
{
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);
}
}
然后编辑你的services.yaml文件
# app/config/services.yml
#[...]
services:
#[...]
# Custom Translator (References)
# Overrides the Translator Service (is still available as @app.decorating_translator.inner)
app.decorating_translator:
class: App\Common\ReferenceTranslator
decorates: translator
arguments:
- '@app.decorating_translator.inner'
public: false
瞧!同样,如果您知道如何改进这一点,请不要犹豫,因为我不是 Symfony 专家!
TBG 答案有效,对于 Symfony 4.4,这里是 service.yaml 中的代码
Services
App\Common\ReferenceTranslator:
arguments:
$translator: '@translator'
并且不要忘记实现LocaleAwareInterface!