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