What is the best way to translate JavaScript literal strings in Assetic assets?

Is there a way to create for example: myscript.js.twig files?

It seems a bad idea.


You can check https://github.com/willdurand/BazingaExposeTranslationBundle

or create it yourself, for example include this in your template:

<script type="text/javascript">
    var translations = {
       // ... 
       'yes' : {{ 'yes' | trans }},
       // ...
    }
</script>

then if your javascript file is included just before </body> you can use translations variable in it.


Here is my solution (Tested on Symfony 4 and 5):

First, we create a controller that will create JS file with all translations according to the current variable locale:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Yaml\Yaml;

/**
 * Translation controller.
 */
class TranslationController extends AbstractController
{
    /**
     * @Route("/translation.js", name="translation")
     */
    public function index(Request $request)
    {

        $locale = $request->getLocale();
        $file   = __DIR__.'/../../translations/messages.'.$locale.'.yaml';
        $parsed = Yaml::parse(file_get_contents($file));

        $translations = $this->renderView(
            'translation/translation.js.twig', 
            array(
                'json' => json_encode($parsed)
            )
        );

        return new Response($translations, 200,
            array('Content-Type' => 'text/javascript')
        );
    }
}

Then we create a TWIG template to render (/templates/translation/translation.js.twig):

var trans = JSON.parse('{{ json|raw }}');

We place our dynamic translation file in the template before other assets:

<script src="{{ path('translation') }}"></script>

For sample translation file /translations/messages.pl.yaml:

projects: Projekty
medium: Średnio
month:
  january: Styczeń
  february: Luty

We can display our translation in any JS file:

console.log(trans['month']['january']);
console.log(trans['medium']);

I hope it will be useful to someone

Tags:

Twig

Symfony