2

我将 Twig 与 Symfony2 框架分开使用,以更小的滚动以更好地满足我的(感知的)需求。我的框架的一部分是一个资产管理库,它管理 js/css 依赖关系,经过预处理、组合、缩小、gzip 压缩,输出适当的<link><script>标签以放置<head><body>.

资产助手只有三个公共函数require_asset($asset)render_head()render_bottom()。第一个在不同的模板部分中很少使用(我想将资产的加载保持在应用程序逻辑之外,因此在树枝模板内)。在需要所有资产之后需要调用另外两个,并且(在资产管理器完成它的事情之后)返回要放置在模板中的适当和标签。

所有普通模板都扩展了基本模板:

base.twig:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{ title }}</title>
        <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
        {{ Assets.headAssets }}
    </head>
    </body>
        {% block body %}
        {% endblock %}
        {{ Assets.bottomAssets }}
    <body>
</html>

这里{{ Assets.headAssets }}{{ Assets.bottomAssets }}是通过先前声明的 Twig 全局变量Assets对上述render_head()render_bottom()方法的调用;

在我的例子中,这个基本模板是从 test.twig 扩展而来的:

{% extends "base.twig" %}
{% import "forms.twig" as forms %}

{% block body %}
    {{ Assets.requires('formtest.css') }}
    {{ Assets.requires('testscript.js') }}
    <form method="post">

        {{ forms.form(form) }}

        <input type="submit"/>
    </form>

{% endblock %}

在这里,{{ Assets.requires('formtest.css') }}{{ Assets.requires('testscript.js') }}通过调用require_asset($asset).

通常,如果在 twig 之外完成,则在需要所有需要的资产之后,最后调用输出函数。这按预期工作。

我遇到的问题与树枝模板中这些函数的执行顺序有关。由于首先调用 base.twig 并包含对输出函数的调用,因此在从扩展模板或包含的块/宏提出任何要求之前调用这些函数。因此,结果是空的,并且没有考虑到这些新要求。

我想解决这个问题的一种方法是在 Twig 返回渲染后计算输出,并在返回的结果中替换它们。这行得通,但我觉得不够优雅。

我想知道是否有办法推迟执行,{{ Assets.headAssets }}直到{{ Assets.bottomAssets }}twig 完成其他所有操作。我有什么办法可以做到这一点?

4

2 回答 2

2

对于那些仍在寻找答案的人,我编写了一个允许延迟块渲染的Twig 扩展。

于 2014-05-14T11:56:01.087 回答
2

我认为这会起作用:

基地.twig

{% set bodyContent %}
    {% block body %}{% endblock body %}
{% endset %}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{ title }}</title>
        <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
        {{ Assets.headAssets }}
    </head>
    </body>
        {{ bodyContent }}
        {{ Assets.bottomAssets }}
    <body>
</html>

其他文件可以不修改。

如您所见,body在模板中首先阻止调用base.twig,因此在执行{{ Assets.headAssets }}调用时已经需要您的所有资产。

于 2014-02-13T07:48:44.963 回答