如何将Twig / PHP / HTML模板块渲染为任意一组爆炸子部分?

时间:2016-06-26 05:25:38

标签: php templates model-view-controller twig template-engine

我已经打了一会儿反对这一点,因为虽然它很容易"在原始PHP中,由于PHP缺乏体面的内置模板语法,结果无法扩展。所以我安装了Twig,假设它有一个内置的爆炸功能,可以在块之间进行迭代。但似乎没有办法将内容分成任意数量的小节。

我考虑使用{% embed %},,但文档的样式将根据模板中显示的部分进行样式设置。以什么顺序(这是变量;这是一个包含大量业务逻辑的表单。)

我已经用PHP构建了这个表单,并让它以“非常漂亮”的形式工作。具有容易任意数量的子部分的静态页面,所有工作和交互,无论显示哪些(基于例如用户权限),但是将其模板化是挑战。

静态(无结构)版本依赖于我将解析后的内容导出到一个数组,然后可以使用适当样式的div为每个可见部分包装。这有效,但要求我使用包含的html和对象缓冲,这看起来很糟糕并且不易维护:

$content = include("form_content_html.php"); // return an object-buffered array
// I was including the escaped values here using if isset($data) and echo short tags.

foreach ($content as $section) { /* do something; */ }

$template = include("form_template_subsection.php");

$formview->addSubsectionTemplate($template);

echo $formview->addSubsection($content,$i++,$type); 
// fill section of $type with $content[$i] if isset

echo $formview->addSubsection($content,$i++,$sometype);
// $types have different css class for certain effects

// etc. not the best approach.

(我需要在将其绑定到表单值之前转义所有用户/数据库内容,但由于表单字段是高度自定义的,我将它们分成了自己的内容层,因此这是唯一具有内容的层目前需要逃脱。)

所以忘记了,现在我正在使用Twig。 (注意:不是Symfony2,因为项目在共享的webhost上。)

我不认为父模板有一种 {%extend%}ing 的方式,以便某些子模板块被放入"命名的父模板容器,其余被忽略;这就是我正在寻找的东西,因为我可以将所有逻辑放到顶层(表单的哪些部分可见,等等)并首先传入值。

请注意,表单部分的样式由父模板的结构决定,而不是由子内容决定。例如。第1节可以在第2节中显示内容1并在内容2上调用css;或者具有相同css的第1和第2部分可以显示不同的内容。

如果我将表单拆分为15个仅限内容的子模板,然后有条件地将它们包含在父文件中,它就可以工作。但这似乎打败了使用模板引擎的目的?虽然我认为Twig以这种方式使用包含html片段的包含文件变得更容易,但请告诉我这是否是首选解决方案。

我是否应该将内容节点分为编号{% block1 %}{% block2 %}等子部分,然后在我的PHP视图类中将renderBlock分开?

如果Twig有一个{% section %}...{% section %}语法,允许你将模板拆分成块,然后将每个块解析为一个块元素数组......好吧,我想到了一半,并希望我能添加一个自己。

2 个答案:

答案 0 :(得分:0)

这是一个可能的解决方案吗?来自Twig文档:

  

水平重用是实现与多重目标相同的一种方式   继承,但没有相关的复杂性:

{% extends "base.html" %}

{% use "blocks.html" %}

{% block title %}{% endblock %} 
{% block content %}{% endblock %}
     

use语句告诉Twig导入中定义的块   blocks.html进入当前模板(就像宏一样,但对于   块):

{# blocks.html #}

{% block sidebar %}{% endblock %}
     

注意:use标记仅导入模板(如果不是)   扩展另一个模板,如果它没有定义宏,如果是正文   是空的。但它可以使用其他模板。

嗯,这有点不太清楚。

(“它”是指导入的模板能够使用其他模板,还是“它”意味着模板可以使用多个模板,或两者兼而有?如果身体是空的,那是否意味着身体导入的块标记?如果是,那么它可能不是解决方案。)

是否可以做这样的事情:

{# form_template.html #}
{% extends "form_content.html" %}

{% block section1 %}
    <div class="{{ style1 }}"><div class="{{ style2 }}">etc.

        {{ parent() }}

    </div></div>{% endblock %} 

还是这个? ...

{# form.html #}

{% use "form_content.html" %}

{% for sections as i %}
   {% block wrapper_elements %}{% block section{{i.name}} %}{% endblock %}
   {% endblock %}
{% endfor %}

{# form_content.html #}

{% use "form_fields.html" %} 

{% block section1 %}{% if field1 %}
      Actual content here: {% block field1 %}{% endblock %} And here
   {% else %}&nbsp;{% endif %}
{% endblock %}

{% block section2 %}More actual content here{% block section2 %}

但是,如果是这样,如何在form.html中调用每个部分之前迭代这些部分?

答案 1 :(得分:0)

我找到了解决方案,认为:

(来自Twig文档)

  

set标签还可用于“捕获”文本块:

{% set foo %}
    <div id="pagination">
    ...
    </div> 
{% endset %}

Ergo,set可用于迭代匿名连续块:

{% set i=0, out=[] %}{# declare top scope #}

{% block initialize_content %}{# use once #}
    {% set i=0, out=[] %}{# prevent dupes #}
    {% set foo %}

        <div id="pagination">...</div> 

    {% endset %}{% set out=out|merge({ i: foo}) %}{% set i=i+1 %}{% set foo %}

        {{ escape_variables_here }} ... more html

    {% endset %}{% set out=out|merge({ i: foo}) %}{% set i=i+1 %}{% set foo %}

        {{ variables_all_scoped_to_same_context }} ... more html

        {# so dividers can be moved "up and down" if necessary ... #}    

    {% endset %}{% set out=out|merge({ i: foo}) %}{% set i=i+1 %}{% set foo %}

        {# ... like this. ^^a tag/macro could probably define this #}

    {% endset %}{% set out=out|merge({ i: foo}) %}
    {# or loop over i = 0..n or i = loop.index0 #}

{% endblock initialize_content %} {# end setter #}
{% block content %}

    {% if key is defined and out.key is defined %}{{ out.key |raw }}{% endif %}

    {# output top-scoped var (outputs nothing if setter not called) #}
    {# the setter doesn't have to be in its own block, but that allows
    the variables in the content to be redefined in setter's scope. #}

{% endblock %}

(参见Setting element of array from Twig