如何将 Twig / PHP / HTML 模板块渲染为任意的分解小节数组?
How to render Twig / PHP / HTML template blocks as an arbitrary array of exploded subsections?
我已经为此苦苦思索了一段时间,因为虽然 "easy" 在原始 PHP 中进行,但由于 PHP 的原因,结果无法扩展缺乏体面的内置模板语法。所以我安装了 Twig,假设它有一个内置的 explode 函数来在块之间迭代。但是似乎无法 div 将内容放入任意数量的小节中。
我使用 {% embed %},
反对 idered,但文档的样式将根据出现在 parent 模板中的部分来设置。以及以什么顺序(这是可变的;这是针对其中包含大量业务逻辑的表单。)
我在 PHP 中构建了表单,并使其作为一个 "very pretty" 静态页面工作,可以轻松地包含任意数量的小节,无论显示哪个小节,所有小节都可以工作和交互(基于例如用户权限),但将其模板化是一个挑战。
静态(无树枝)版本依赖于我将解析的内容导出到一个数组,然后可以用适当样式的 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,因为该项目位于共享虚拟主机上。)
我认为没有办法 {%extend%}ing
父模板使得一些子模板块是 "dropped into" 指定的父模板容器,其余忽略;这就是我正在寻找的,因为这样我可以将所有逻辑放入顶层(表单的哪些部分可见等)并首先传入值。
请注意,表单部分的样式由父模板的结构决定,而不是由子内容决定。例如。 section 1 可能显示内容 1,并在 section 2 中对内容 2 调用 css;或具有相同 css 的部分 1 和 2 可能显示不同的内容。
如果我将表单拆分为 15 个仅包含内容的子模板,然后有条件地将它们包含在父文件中,就可以了。但这似乎违背了使用模板引擎的目的?尽管我认为 Twig 可以更轻松地以这种方式处理包含 html 片段的包含文件,所以请告诉我这是否是首选解决方案。
我是否应该 divide 将内容节点向上划分为编号 {% block1 %}
、{% block2 %}
等小节,然后在我的 PHP 视图 class?
如果 Twig 具有 {% section %}...{% section %}
语法,允许您将模板拆分为块,然后将每个块解析为块元素数组...好吧,我有一半预料到了,希望我能自己加一个。
这是可行的解决方案吗? 来自 Twig 文档:
Horizontal reuse is a way to achieve the same goal as multiple
inheritance, but without the associated complexity:
{% extends "base.html" %}
{% use "blocks.html" %}
{% block title %}{% endblock %}
{% block content %}{% endblock %}
The use statement tells Twig to import the blocks defined in
blocks.html into the current template (it's like macros, but for
blocks):
{# blocks.html #}
{% block sidebar %}{% endblock %}
Note: The use
tag only imports a template if it does not
extend another template, if it does not define macros, and if the body
is empty. But it can use other templates.
嗯,这有点不太清楚。
( "it" 是指导入的模板可以使用其他模板,还是 "it" 表示一个模板可以使用多个模板,或两者兼而有之?如果正文为空, 是指导入块标签的主体吗?如果是这样,那么它可能不是解决方案。)
是否可以这样做:
{# 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 %} {% endif %}
{% endblock %}
{% block section2 %}More actual content here{% block section2 %}
但如果是这样,如何在 form.html 中调用每个部分之前迭代这些部分?
我找到了解决方案,我认为:
(来自 Twig 文档)
The set tag can also be used to 'capture' chunks of text:
{% set foo %}
<div id="pagination">
...
</div>
{% endset %}
因此,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)
我已经为此苦苦思索了一段时间,因为虽然 "easy" 在原始 PHP 中进行,但由于 PHP 的原因,结果无法扩展缺乏体面的内置模板语法。所以我安装了 Twig,假设它有一个内置的 explode 函数来在块之间迭代。但是似乎无法 div 将内容放入任意数量的小节中。
我使用 {% embed %},
反对 idered,但文档的样式将根据出现在 parent 模板中的部分来设置。以及以什么顺序(这是可变的;这是针对其中包含大量业务逻辑的表单。)
我在 PHP 中构建了表单,并使其作为一个 "very pretty" 静态页面工作,可以轻松地包含任意数量的小节,无论显示哪个小节,所有小节都可以工作和交互(基于例如用户权限),但将其模板化是一个挑战。
静态(无树枝)版本依赖于我将解析的内容导出到一个数组,然后可以用适当样式的 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,因为该项目位于共享虚拟主机上。)
我认为没有办法 {%extend%}ing
父模板使得一些子模板块是 "dropped into" 指定的父模板容器,其余忽略;这就是我正在寻找的,因为这样我可以将所有逻辑放入顶层(表单的哪些部分可见等)并首先传入值。
请注意,表单部分的样式由父模板的结构决定,而不是由子内容决定。例如。 section 1 可能显示内容 1,并在 section 2 中对内容 2 调用 css;或具有相同 css 的部分 1 和 2 可能显示不同的内容。
如果我将表单拆分为 15 个仅包含内容的子模板,然后有条件地将它们包含在父文件中,就可以了。但这似乎违背了使用模板引擎的目的?尽管我认为 Twig 可以更轻松地以这种方式处理包含 html 片段的包含文件,所以请告诉我这是否是首选解决方案。
我是否应该 divide 将内容节点向上划分为编号 {% block1 %}
、{% block2 %}
等小节,然后在我的 PHP 视图 class?
如果 Twig 具有 {% section %}...{% section %}
语法,允许您将模板拆分为块,然后将每个块解析为块元素数组...好吧,我有一半预料到了,希望我能自己加一个。
这是可行的解决方案吗? 来自 Twig 文档:
Horizontal reuse is a way to achieve the same goal as multiple inheritance, but without the associated complexity:
{% extends "base.html" %} {% use "blocks.html" %} {% block title %}{% endblock %} {% block content %}{% endblock %}The use statement tells Twig to import the blocks defined in blocks.html into the current template (it's like macros, but for blocks):
{# blocks.html #} {% block sidebar %}{% endblock %}Note: The
use
tag only imports a template if it does not extend another template, if it does not define macros, and if the body is empty. But it can use other templates.
嗯,这有点不太清楚。
( "it" 是指导入的模板可以使用其他模板,还是 "it" 表示一个模板可以使用多个模板,或两者兼而有之?如果正文为空, 是指导入块标签的主体吗?如果是这样,那么它可能不是解决方案。)
是否可以这样做:
{# 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 %} {% endif %}
{% endblock %}
{% block section2 %}More actual content here{% block section2 %}
但如果是这样,如何在 form.html 中调用每个部分之前迭代这些部分?
我找到了解决方案,我认为:
(来自 Twig 文档)
The set tag can also be used to 'capture' chunks of text:
{% set foo %} <div id="pagination"> ... </div> {% endset %}
因此,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)