6

我有这种情况:

unit:
    sqkm: Square Kilometers

my_translation: Size is %size% ## I want to append the value of unit.sqkm here ##

有没有办法引用unit.sqkm里面my_translation键的翻译?

编辑:请注意,我确实知道如何通过 twig 做到这一点。我的问题是:有没有办法在翻译文件中做到这一点

4

5 回答 5

2

我为此扩展了 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 引用其他翻译。

于 2017-08-17T08:18:13.607 回答
1

在你的 Twig 模板中,试试这个:

{{ 'my_translation' | trans({'%size%': size, 'unit.sqkm' : ('unit.sqkm'|trans)}) }}
于 2013-01-10T13:14:16.777 回答
1

您可以在其他翻译中使用翻译后的值。

{{ 'paragraph' | trans({ '%size%': 3, '%unit%': 'unit' | trans()}) }}

whereunit本身是翻译的另一个关键。但是,您的翻译文件可能如下所示:

paragraph: Size is %size% %unit%
unit: Square Kilometers
于 2013-01-10T13:13:42.347 回答
0

如果像我一样,你想在 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 专家!

于 2018-12-01T02:29:45.610 回答
0

TBG 答案有效,对于 Symfony 4.4,这里是 service.yaml 中的代码

Services
    App\Common\ReferenceTranslator:
        arguments:
            $translator: '@translator'

并且不要忘记实现LocaleAwareInterface

于 2022-01-18T21:48:05.857 回答