JBlond / twig-trans

Twig 3 translation extension

Home Page:https://github.com/JBlond/twig-trans

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

trans arguments are ignored

psociety opened this issue · comments

I'm leaving this in case anyone else encounters the same problem

{{ "hello_message"|trans({'username': user.name}) }}

Where hello_message is hi %username%!.

This case won't work because the third param of TwigFilter is being ignored.

To make it work i refactored the filter like this:

$filter = new TwigFilter(
        'trans',
        function ($string, $args) {
            return empty($args) ? _($string) : tprintf(_($string), $args);
        },
    );

But maybe it could be compatible with both scenarios with:

$filter = new TwigFilter(
        'trans',
        function ($context, $string, $args) {
            return \jblond\TwigTrans\Translation::transGetText($string, empty($args) ? $context : $args);
        },
        ['needs_context' => true]
    );
commented

I see the point. But that is in the example code. I could add that to the examples. Is there a need to change anything in the library?

Is there a need to change anything in the library?
I don't think so :)

Although i'm struggly a bit on using {% trans %}{% endtrans %} with keywords rather than a default locale.

If i set {% trans %}hello_message{% endtrans %} the shown message is hi %username%! rather than hi JBlond! :(

Seems that this extension is not ready for multilanguage applications?

Does:

{% trans %}hi {{ username }}!{% endtrans %}

Not work for you? We interpolate twig variables inside the trans tags quite a lot and it works fine. In our .po file that would show up as "hi %username%!"

Does:

{% trans %}hi {{ username }}!{% endtrans %}

Not work for you? We interpolate twig variables inside the trans tags quite a lot and it works fine. In our .po file that would show up as "hi %username%!"

Yes that works, but that means that hi %username%! is the ID of the translation. So if you ever want to change the english message, it forces you to retranslate all other languages as the key has changed :(

Ah yeah. We've just been ignoring that aspect, in that we just retranslate the other languages.

I ended up having to rewrite compileString method from TransNode:

private function compileString(Node $node) : array {
        if (
            $node instanceof NameExpression ||
            $node instanceof ConstantExpression ||
            $node instanceof TempNameExpression
        ) {
            return [$node, []];
        }

        $message = $node->getAttribute('data');

        preg_match_all('/%(\w+)%/', _($message), $matches);

        $vars = [];
        foreach ($matches[1] as $n) {
            $vars[] = new NameExpression($n, $node->getTemplateLine());
        }

        return [new Node([new ConstantExpression(trim($message), $node->getTemplateLine())]), $vars];
    }

Now {% trans %}hello_message{% endtrans %} gets translated to {% trans %}hi derikb!{% endtrans %}

commented

Well, the original code is a lot longer. I wonder if you could combine that.

It's 100% possible, BUT, it forces pages that use a default locale as key, to run the gettext/_ twice per phrase, which i don't know if it may represent a performance hit.
A way to prevent it would be setting a config var so dev can tell if it's using keywords or phrases as key but that would be more work xD

commented

That might be easier possible than you think with an optional parameter.

commented

@psociety What I just tried

msgid "Hello %name%"
msgstr "Hallo %name%"
{{ 'Hello %name%'|trans|replace({'%name%': 'James'}) }}<br><br>
commented

Issue #7 seems to go in the same direction.

@psociety What I just tried

msgid "Hello %name%"
msgstr "Hallo %name%"
{{ 'Hello %name%'|trans|replace({'%name%': 'James'}) }}<br><br>

You're using the key as a translation. That's only maintainable as long as you're only translating to a single language.
When you have several languages the key must remain a key. Otherwise you will have to update all languages every time you want to change the phrase for the language that is serving as key.

It's something that @derikb already suggested, but it's never going to be an option.

It's better to just overwrite the class using composer:

"exclude-from-classmap": ["vendor/jblond/TwigTrans/TransNode.php"],
"files": ["App/System/TransNode.php"]