3

有没有办法将 Twig 用作资产过滤器?

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

您可能会在想为什么我首先要这样做,所以让我跳到一个例子。


我正在用 JavaScript 制作游戏引擎,我需要有几个“类”的两个版本。一个版本供用户使用,另一个版本供编辑器使用。其中一个类的一个例子是单例World

此类的用户版本可能如下所示:

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

使用经典的 OO 继承,我们可以将World定义为一个类,然后用另一个类EditableWorld扩展它。然而,使用 JavaScript 中的原型继承只会继承公共函数,如果您甚至尝试扩展现有实例,您将无法访问闭包内的变量和函数。

树枝来救援!

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

因此,让我们再次将我们的基础World类视为 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 使用 Twig 作为过滤器,以便我可以执行以下操作:

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

您可能想到的一个直接解决方案是完全放弃闭包,只将我所有的变量和函数公开,并在应该是私有的前面加上下划线。但是对我来说,这不是一个有效的解决方案,因为我不仅仅是在创建一个库。游戏引擎需要从最终用户关闭所有内部结构,以阻止所有想要篡改正在运行的引擎的确定用户(并且对于那些用户,我有服务器验证以确保来自受感染客户端的非法操作不要通过服务器发送给其他客户端)。

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

4

1 回答 1

1

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

此外,您还有很多优雅地支持 JavaScript 中的 OOP 的库/语言/帮助程序(例如 CoffeeScript、Backbone.js、Underscore.js 等)

祝你好运!

于 2013-06-19T09:19:42.960 回答