One of the very painful taks you may face using symfony2 is the extration of all you translation message from your twig templates. This is much more annoying knowing that symfony1.4 did the job for you with a simple command, which does not exist in symfony2.
Today I will give give you a command for symfony2 that checks all your twig messages, combine them with your already existing messages in your yaml translations files and save the new ones. It is a recent work for me and it just works with twig/yml files.
The Command
I embedded it in a Bundle on github: https://github.com/michelsalib/ExtraToolsBundle.
You just need to get it, register the namespace and the bundle.
The name of the command is [cci]bcc:trans:update locale bundleName[/cci], where the [cci]locale[/cci] is the targeted locale (en, fr, es…) and the [cci]bundleName[/cci] is the name of the targeted bundle. You have several options:
- –dump-messages to display your final messages
- –force to update/write your translation files, it also perform a backup of the old ones
- –prefix=”…” if you want to change the prefix use for your new messages, by default [cci]__ [/cci] is used
Some example:
- To extract the messages of your bundle and display them in the console:
[cci]bcc:trans:update –dump-messages fr MyBundle[/cci]
- You can save them:
[cci]bcc:trans:update –force fr MyBundle[/cci]
- In another language:
[cci]bcc:trans:update –force en MyBundle[/cci]
- Or if you want to chaneg the prefix used to generate the new messages:
[cci]bcc:trans:update –force –prefix=’myprefix’ en MyBundle[/cci]
Behind the scene
The trick behind the code is how to properly crawl your twig templates.
First to get them:
[cc lang="php"]
// get bundle directory
$foundBundle = $this->getApplication()->getKernel()->getBundle(‘MyBundle’);
// get twig templates
$finder = new Finder();
$files = $finder->files()->name(‘*.html.twig’)->in($foundBundle->getPath() . ‘/Resources/views/’);
// iterate over the files
foreach ($files as $file) {
$path = $file->getPathname();
// parse the files
}
[/cc]
Here you just need to use the kernel to retrieve the bundle data from a simple bundle name. When you have the bundle path, you can use the finder to get all the file ending by [cci].html.twig[/cci] in the relative [cci]/Resources/views/[/cci] directory.
You can now parse the twig files:
[cc lang="php"]
$tree = $twig->parse($twig->tokenize(file_get_contents($path)));
[/cc]
Then you get a tree composed of [cci]Twig_Node[/cci]. The rest is just an algorithmic problem using recursion and type checking to find [cci]SymfonyBridgeTwigNodeTransNode[/cci] (for [cci]{% trans %}…{% end trans %} syntax[/cci]) and [cci]Twig_Node_Print[/cci] that contains trans filter (for [cci]{{ … | trans }}[/cci] syntax).
When you finally have all your messages, you might want to save them into yaml. For that you have two very simple static functions:
[cc lang="php"]
// get a yaml file into a php array
$array = SymfonyComponentYamlYaml::load($path);
// transform an array into a yaml string
$yml = SymfonyComponentYamlYaml::dump($array);
[/cc]
Wrap up
I hope this command will help you building better symfony2 app, by automatizing some work. Don’t hesitate to report me bugs, suggestions or to fork me on github!
