Search code examples
symfonytwig

Symfony Twig Translation does not fill in placeholders


I am currently having the situation where a twig-filtered string that contains placeholders does only translate the string itself but does not respect the available, and linked, placeholders.

My example:

{{ 'this is my test: %test%'|trans({'%test%': 'test!'|trans}) }}

I have the translation available in my XLF file (automatically generated by symfony), lets say I add __ as prefixex to the string. I clear the cache and reload, and I do see that the string itself get translated, but now, instead of:

__this is my test: __test!

The string looks like this:

__this is my test: %test%

In other words, it does not seem to insert the placeholder as expected.

Why? The placeholder translation works however, if I remove the original translation for the parent string. So, only one does work:

  • translate the parent string
  • place the placeholder correctly

But not both at the same time.

The template where I am using this is included by another template. Is this maybe an issue?


Solution

  • Default engine of translator isn't enough smart to do it, and there is a lot of confusions with word between % like %test%. To translate sentences like yours, you should use the ICU format. Here is an article about the ICU format and Symfony

    You can fix it in a few steps:

    1. Surround the parameter with { } in the sentence to translate:
    {{ 'this is my test: {test}'|trans({'test': 'test!'|trans}) }}
    
    1. Tell to symfony your using the ICU format by adding the good extension on your translation file. As example, rename your file from messages.yaml to messages+intl-icu.en.yaml
    2. Clear your cache
    3. Report modifications to your messages+intl-icu.en.yaml file.
    # translations/messages+intl-icu.en.yaml
    test!: '__test!'
    "this is my test: {test}": '__this is my test: {test}'
    

    Be aware on the non-translated parameter in translated sentence! Keep in mind that {test} shall NOT be translated because it will be replace by value after the translation process. In your code, the process is:

    1. translate test! to __test!
    2. translate this is my test: {test} to __this is my test: {test}
    3. replace {test} by __test!

    Result becomes like you expected it: __this is my test: __test!