title: Using Twig as an Assetic filter for JavaScript in Symfony2
body: <p>Is there a way to use Twig as an Assetic filter?</p>
  
  <p>What I want to do is have Twig parse my JavaScript files as Twig templates, and then pass them to Assetic so that they get combined and minified in production.</p>
  
  <p>You might be scratching your head thinking why I would want to do this in the first place, so let me jump to an example.</p>
  
  <hr>
  
  <p>I am making a game engine in JavaScript and I need to have two versions of several 'classes'.
  One version for the user and another for the editor. An example of one of these classes would be the singleton <strong>World</strong>.</p>
  
  <p>The user version of this class might look like this:</p>
  
  <pre><code>var World = function()
  {
      // bunch of 'private' variables and functions inside closure
      var _initialised = false;
      var _worldData;
      ...
  
      // public functions
      this.init = function(){...}
      this.update = function(){...}
      ...
  }
  </code></pre>
  
  <p>The editor version of this class might look this:</p>
  
  <pre><code>var World = function()
  {
      // bunch of 'private' variables and functions inside closure
      var _initialised = false;
      var _worldData;
      ...
  
      // bunch of new private variables and functions for editing
      var _editorserver;
      ...
  
      // public functions
      this.init = function(){...}
      this.update = function(){...}
      ...
  
      // public functions that edit the world
      this.addEntity = function(){...}
      this.removeEntity = function(){...}
      ...
  }
  </code></pre>
  
  <p>With classical OO inheritance we could define <strong>World</strong> as one class and then extend it with another class <strong>EditableWorld</strong>. However with Prototypal inheritance in JavaScript only the public functions would be inherited and if you even tried to extend the existing instance you would not be able to access the variables and functions inside the closure.</p>
  
  <p>In comes Twig to the rescue!</p>
  
  <p>With Twig we could add several blocks to any class in a file, and then create another file defining the same class with some extensions and then include <em>that</em> file.</p>
  
  <p>So let's look at our base <strong>World</strong> class again as a Twig template.</p>
  
  <pre><code>// world.js.twig
  var World = function()
  {
      // bunch of 'private' variables and functions inside closure
      var _initialised = false;
      var _worldData;
      ...
  
      {% block extended_privates %}{% endblock %}
  
      // public functions
      this.init = function(){...}
      this.update = function(){...}
      ...
  
      {% block extended_publics %}{% endblock %}
  }
  </code></pre>
  
  <p>And our extended version.</p>
  
  <pre><code>// editableworld.js.twig
  {% extends "EngineBundle::world.js.twig" %}
  var World = function()
  {
      // bunch of 'private' variables and functions inside closure
      var _initialised = false;
      var _worldData;
      ...
  
      {% block extended_privates %}
      // bunch of new private variables and functions for editing
      var _editorserver;
      ...
      {% endblock %}
  
      // public functions
      this.init = function(){...}
      this.update = function(){...}
      ...
  
      {% block extended_publics %}
      // public functions that edit the world
      this.addEntity = function(){...}
      this.removeEntity = function(){...}
      ...
      {% endblock %}
  }
  </code></pre>
  
  <hr>
  
  <p>Now here's the rub: how do you I get Assetic to use Twig as a filter so that I can do something like this:</p>
  
  <pre><code>// user version of twig template
  // gameengine.html.twig
  
  {% javascripts filter="js_twig_filter"
  "@EngineBundle/Resources/public/js/world.js.twig"
  %}
  &lt;script src="{{ asset_url }}" type="text/javascript"&gt;&lt;/script&gt;
  {% endjavascripts %}
  
  // editor version of twig template
  // gameeditor.html.twig
  
  {% javascripts filter="js_twig_filter"
  "@EngineBundle/Resources/public/js/editableworld.js.twig"
  %}
  &lt;script src="{{ asset_url }}" type="text/javascript"&gt;&lt;/script&gt;
  {% endjavascripts %}
  </code></pre>
  
  <p>One immediate solution that might come to your head is to forgo closures altogether and just make all my variables and functions public and just prefix the ones that should have been private with an underscore. However for me this isn't a valid solution as I'm not merely creating a library. The game engine needs to close off all of it's internals from the end user to stop all but determined users who would want to tamper with the running engine (and for those users I have server validation in place to make sure illegal actions from the compromised clients don't get sent to other clients via the server).</p>
  
  <p>Thanks for sticking around and I hope someone can help me (I've been banging my head against the wall for a few days now trying alternative ideas before I thought of this possible solution).</p>