['brein-jæk]

randomized bits and well-structured thoughts

Using dynamic javascript in Symfony

This is definitly nothing average users or even average programmers have to know, but if you’re a Symfony developer this might come very handy and could save you hours of searching and evenings of frustration :)

You are qualified if :

  • You are developing an application within the Symfony framework
  • You make heavy use of your own javascript files because you don’t want to produce that much inline javascript code
  • You really need to use dynamic javascript, maybe you want to integrate with the built-in i18n framework
  • You’ve never ever heard of dynamic_javacript_include_tag() and use_dynamic_javascript() or weren’t able to make them work

So here is my solution:

The helper function “use_dynamic_javascript” just doesn’t work (or at least I wasn’t able get it to work). Lump it and dump it. We’ll use the other function, which does its job. Here’s how:

As we have to place our dynamic JS within an module you should decide which module you want to use, say we just need i18n in JS so let’s call it “modI18n”. Later we probably include more stuff in this module, so we won’t use the index action. Instead let’s create an empty action called “JsI18n”. You can obviously decide on your own whether you want to use a single file (JsI18nAction.class.php) or the gathering actions.class.php (function executeJsI18n) variant.

Next, create a template called “jsI18nSuccess.js.php”. You already know the rest, don’t you? This is the place where you can mix up Javascript and PHP, great! In my case this file looks like this:

var i18n = {
  'Hello World': '<?php echo __('Hello World')?>'
}
function __(key) {
  return (i18n[key] ? i18n[key] : key );
}

Almost finished, only one point is left: How to actually include this? If you stick with the default routing, there’s nothing easier than that, just type

<?php echo dynamic_javascipt_include_tag('modI18n/JsI18n') ?>

in the head section of your layout or anywhere in your template (the earlier the better) and you’re done. If you use custom routing rules, you may have to add a corresponding route for the action and use this route in the helper. Now you can easily access translated strings within Javascript with the well known __() function. Of course you have to maintain the template, however it seems this is worth the work.

Summing it up this is a bit more convenient than other methods, but nevertheless you’ll end up writing many additional lines of code.

~~~Cheers

3 ResponsesLeave one →

  1. Hi Jörg,

    genial, danke! War genau das, was ich gesucht habe.

    >> Of course you have to maintain the template, however it seems this is worth the work.
    Ich werd das so machen, dass ich mir einfach alle JS-Uebersetzungen aus einem entsprechenden XLIFF-Katalog (in meinem Fall aus der DB) hole und einfach dumpe. Sollte ziemlich easy sein.

    Eine Frage aber: hast du zufällig eine Idee, wie man die erzeugte Ausgabe am elegantesten statisch speichern kann? Ich verwende nämlich minify (was ich sehr empfehlen kann) und brauche die JS-Übersetzungen in diesem Fall tatsächlich als echte JS-Datei.

    Viele Grüße aus Würzburg,
    Martin

  2. Hi Eddi,
    I’m glad I could help you. Regarding your question concerning caching static and in that sense pre-compiled versions of dynamic js files, I’ve got no idea. In fact, after you’ve pointed me towards minify (sfMinifyPlugin/sfMinifyTSPlugin) I’ve given it a try (had to modify some things to get it to work). It’s quite cool, but now I’m facing your problem, too. So I’ve decided to stay with what I’ve got and did not try to minify the dynamic js. I guess it’s up to the plugin author to provide support for this and I’m afraid this won’t be too easy.

    If you find a solution, I would be happy to hear from you again.

    ps. I hope you don’t mind this reply not being in German.

  3. Cristian Navalici

     /  January 29, 2010

    Hello Jörg,

    Well, here is “my research” on this issue:

    http://goodies.lemonsoftware.eu/doku.php?id=sym:dynamicjs

    Best for all of you!

Leave a Reply