【问题标题】:Defer execution/completion in Twig在 Twig 中延迟执行/完成
【发布时间】:2013-05-18 17:21:23
【问题描述】:

我将 Twig 与 Symfony2 框架分开使用,转成更小的东西,以更好地满足我的(感知的)需求。我的部分框架是一个资产管理库,负责管理js/css依赖,经过预处理、合并、缩小、gzipping,输出相应的<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)来指示assets helper包含这个模板需要的css和js。

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

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

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

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

【问题讨论】:

    标签: php twig


    【解决方案1】:

    我认为这可行:

    base.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>
    

    其他文件可以不修改。

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

    【讨论】:

    • 它可以正常工作,但稍微无关紧要的是,使用body-content 作为twig 变量会导致解析错误,因为- 被暗示为减法运算。冒昧地修复它。
    • @Andri 如果答案有问题,请留下评论让 OP 修复它。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多