2013-04-16 33 views
3

有没有一种方法可以将Twig用作资产过滤器?使用Twig作为Symfony2中JavaScript的资产过滤器

我想要做的是让Twig将我的JavaScript文件解析为Twig模板,然后将它们传递给Assetic,以便在生产中将它们合并并缩小。

你可能会挠脑袋想为什么我想这样做,所以让我跳到一个例子。


我正在制作一个JavaScript的游戏引擎,我需要有几个'类'的两个版本。 一个版本用于用户,另一个版本用于编辑器。其中一个类的例子是单身人士世界

这个类的用户版本可能是这样的:

var World = function() 
{ 
    // bunch of 'private' variables and functions inside closure 
    var _initialised = false; 
    var _worldData; 
    ... 

    // public functions 
    this.init = function(){...} 
    this.update = function(){...} 
    ... 
} 

这个类的编辑器版本看起来这样:

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(){...} 
    ... 
} 

拥有经典的面向对象的继承,我们可以定义世界为一类,然后用另一类扩展它EditableWorld。但是,在JavaScript中的原型继承只会继承公共函数,如果您甚至试图扩展现有的实例,您将无法访问闭包内的变量和函数。

在树枝来救援!

使用Twig我们可以添加几个块到文件中的任何类,然后用一些扩展名创建另一个定义相同类的文件,然后包含文件。

因此,让我们再看看我们的基地世界类再次作为树枝模板。

// 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 %} 
} 

而我们的扩展版。

// 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 %} 
} 

现在,这里的难题是:你怎么我得到Assetic用嫩枝作为一个过滤器,这样我可以做这样的事情:

// user version of twig template 
// gameengine.html.twig 

{% javascripts filter="js_twig_filter" 
"@EngineBundle/Resources/public/js/world.js.twig" 
%} 
<script src="{{ asset_url }}" type="text/javascript"></script> 
{% endjavascripts %} 

// editor version of twig template 
// gameeditor.html.twig 

{% javascripts filter="js_twig_filter" 
"@EngineBundle/Resources/public/js/editableworld.js.twig" 
%} 
<script src="{{ asset_url }}" type="text/javascript"></script> 
{% endjavascripts %} 

一个直接的解决方案,不妨来你的头脑完全放弃关闭,只是把我所有的变量和函数都公开出来,并且只是用私人的下划线作为前缀。但对我来说,这不是一个有效的解决方案,因为我不只是创建一个库。游戏引擎需要关闭其最终用户的所有内部功能,以阻止所有但确定的用户想要篡改正在运行的引擎(并且对于那些已对服务器进行验证的用户来确保受感染客户端的非法操作不要通过服务器发送给其他客户端)。

感谢您的坚持,我希望有人可以帮助我(在我想到这种可能的解决方案之前,我已经把头撞在墙上几天,现在尝试其他想法)。

回答

1

您需要首先渲染(在控制器中)所有* .js.twig文件,并将它们另存为* .js文件(使用file_put_contents()函数在资源树中的某处)。然后将* .js文件加载到您的资产过滤器中。

此外,你有很多的库/语言/佣工的支持OOP在JavaScript优雅(像的CoffeeScript,Backbone.js的,Underscore.js等)

祝你好运!