我将Syig与Symfony2框架分开使用,进入更小的东西,以更好地满足我(感知)的需求。我的框架的一部分是一个资产管理库,用于管理js / css依赖项,在预处理,组合,缩小,gzipping之后,输出适当的<link>
和<script>
标记放在{{1}中}或在<head>
的底部。
资产助手只有三个公共职能:<body>
,require_asset($asset)
和render_head()
。第一个是在不同的模板部分中谨慎使用(我希望将资源加载到应用程序逻辑之外,因此在twig模板中)。在需要所有资产之后,需要调用另外两个资产,并且(在资产管理器执行其操作之后)返回要放置在模板中的相应标记。
所有普通模板都扩展了基本模板:
base.twig:
render_bottom()
此处<!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 }}
是通过之前声明的Twig全局变量{{ Assets.bottomAssets }}
调用上述Assets
和render_head()
方法;
在我的实例中,此基本模板是从test.twig扩展的:
render_bottom()
此处,{% 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') }}
指示资产助手包含此模板所需的css和js。
通常,如果在树枝外完成,则在需要所有需要的资源之后,将最后调用输出函数。这可以按预期工作。
我遇到的问题与twig模板中执行这些函数的顺序有关。由于首先调用base.twig,并且包含对输出函数的调用,因此在对扩展模板或包含的块/宏进行任何需求之前调用它们。因此,结果为空,并未考虑这些新要求。
我解决这个问题的一种方法是在Twig返回渲染后计算输出,并在返回的结果中替换它们。这有效,但我觉得不够优雅。
我想知道是否有办法推迟require_asset($asset)
和{{ Assets.headAssets }}
的执行,直到完成其他所有事情。我有什么方法可以实现这个目标吗?
答案 0 :(得分:2)
我认为这样可行:
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>
其他文件可以不加修改。
正如您所看到的,阻止body
调用base.twig
模板中的第一个,因此在{{ Assets.headAssets }}
调用执行时,您的所有资产都已被要求。
答案 1 :(得分:2)
对于那些仍在寻找答案的人,我写了一个允许推迟块渲染的Twig extension。