Using Twig as an Assetic filter for JavaScript in Symfony2(在 Symfony2 中使用 Twig 作为 JavaScript 的资产过滤器)
问题描述
有没有办法将 Twig 用作资产过滤器?
Is there a way to use Twig as an Assetic filter?
我想做的是让 Twig 将我的 JavaScript 文件解析为 Twig 模板,然后将它们传递给 Assetic,以便它们在生产中组合并缩小.
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.
你可能在想我为什么首先要这样做,所以让我跳到一个例子.
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.
我正在用 JavaScript 制作游戏引擎,我需要有多个类"的两个版本.一个版本供用户使用,另一个版本供编辑器使用.这些类之一的示例是单例 World.
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 World.
此类的用户版本可能如下所示:
The user version of this class might look like this:
var World = function()
{
// bunch of 'private' variables and functions inside closure
var _initialised = false;
var _worldData;
...
// public functions
this.init = function(){...}
this.update = function(){...}
...
}
此类的编辑器版本可能如下所示:
The editor version of this class might look this:
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 中的原型继承只会继承公共函数,如果您甚至尝试扩展现有实例,您将无法访问闭包内的变量和函数.
With classical OO inheritance we could define World as one class and then extend it with another class EditableWorld. 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.
Twig 来救援了!
使用 Twig,我们可以将多个块添加到文件中的任何类,然后创建另一个文件,使用一些扩展名定义相同的类,然后包含 那个 文件.
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 that file.
让我们再次将我们的基础 World 类视为 Twig 模板.
So let's look at our base World class again as a Twig template.
// 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 作为过滤器,以便我可以执行以下操作:
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:
// 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 %}
您可能想到的一个直接解决方案是完全放弃闭包,只将我的所有变量和函数公开,并在应该是私有的前面加上下划线.但是对我来说,这不是一个有效的解决方案,因为我不仅仅是在创建一个库.游戏引擎需要从最终用户关闭所有内部结构,以阻止所有想要篡改正在运行的引擎的确定用户(并且对于那些用户,我有服务器验证以确保来自受感染客户端的非法操作不要通过服务器发送给其他客户端).
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).
感谢您的支持,我希望有人可以帮助我(在我想到这个可能的解决方案之前,我已经把头撞在墙上几天了,现在正在尝试其他想法).
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).
推荐答案
您需要先渲染(在控制器中)所有 *.js.twig 文件并将它们保存为 *.js 文件(使用 file_put_contents()
函数在资源树的某处).然后将 *.js 文件加载到您的资产过滤器中.
You need to render (in the controller) all the *.js.twig files first and save them as *.js files (using file_put_contents()
function somewhere in the Resources tree). Then load the *.js files into your assetic filters.
此外,您还有很多优雅地支持 JavaScript 中的 OOP 的库/语言/帮助程序(例如 CoffeeScript、Backbone.js、Underscore.js 等)
Besides, you have a lot of libraries/languages/helpers that support OOP in JavaScript elegantly (like CoffeeScript, Backbone.js, Underscore.js, etc.)
祝你好运!
这篇关于在 Symfony2 中使用 Twig 作为 JavaScript 的资产过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 Symfony2 中使用 Twig 作为 JavaScript 的资产过滤器
基础教程推荐
- Chart.js 在线性图表上拖动点 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- 直接将值设置为滑块 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01