当在主文件中定义数组时,如何将项添加到include
标记内的数组中?
请注意,这个问题与Twig中的其他数组问题明显不同,因为我试图修改主文件中包含的模板中的值。
例如:
main.twig
{% set includes = ["test1"] %}
{% include "test.twig" %}
{{includes|json_encode}} {# "How do I make this `includes` contain the "test2" array item?" #}
test.twig
{% set includes = includes|merge(["test2"]) %}
{{includes|json_encode}}
目前main.twig
的输出只给我初始test1
项,而不是test.twig
试图修改的两者的组合。
我可能必须使用附加功能。这里的目标基本上是允许include
d模板在HTML文件中添加其他CSS,JS等,而无需修改父模板。
以下是您可以使用的Twig Fiddle来显示输出。
请注意,对于寻找这个问题答案的其他人,我试图完成的是使用带有向数组添加项目的功能的Twig扩展,以及第二个访问它的功能。请查看下面的答案,该答案未标记为正确,以查看可能执行此操作的方法。如上所述,我的问题是不可能的,如DarkBee所示。
答案 0 :(得分:1)
这不能在Twig
中完成,如模板的编译源中所示,每个包含的templats都有自己的私有范围,因为上下文数组是基于值而不是引用
$this->loadTemplate("bar.twig", "main.twig", 2)->display($context);
然后在包含的模板中调用doDisplay
protected function doDisplay(array $context, array $blocks = array())
注意强>
你可以通过创建自己的Twig_Environment
和Twig_Template
来改变这种行为,但快速浏览一下我会发现你需要覆盖一些功能
main.twig
{% set foo = 'bar' %}
{% include 'bar.twig' %}
Foo in foo: {{ foo }}
bar.twig
{% set foo = 'foo' %}
Foo in bar: {{ foo }}
来源main.twig
/* main.twig */
class __TwigTemplate_4ba23e628289532331bb5889dca1a4ec57774924d21a760ca6fe6f575a3978b5 extends Twig_Template
{
public function __construct(Twig_Environment $env)
{
parent::__construct($env);
$this->parent = false;
$this->blocks = array(
);
}
protected function doDisplay(array $context, array $blocks = array())
{
// line 1
$context["foo"] = "bar";
// line 2
$this->loadTemplate("bar.twig", "main.twig", 2)->display($context);
// line 3
echo "
Foo in foo: ";
// line 4
echo twig_escape_filter($this->env, ($context["foo"] ?? null), "html", null, true);
}
public function getTemplateName()
{
return "main.twig";
}
public function isTraitable()
{
return false;
}
public function getDebugInfo()
{
return array ( 26 => 4, 23 => 3, 21 => 2, 19 => 1,);
}
public function getSourceContext()
{
return new Twig_Source("", "main.twig", "/fuz/twigfiddle.com/files/environment/k85WDdymIFgSoXLc/twig/main.twig");
}
}
来源bar.twig
<?php
/* bar.twig */
class __TwigTemplate_16789decfbb837d4631acf2e648380c0658722c50a0b53184b3f3c5f68f9b0ae extends Twig_Template
{
public function __construct(Twig_Environment $env)
{
parent::__construct($env);
$this->parent = false;
$this->blocks = array(
);
}
protected function doDisplay(array $context, array $blocks = array())
{
// line 1
$context["foo"] = "foo";
// line 2
echo "Foo in bar: ";
echo twig_escape_filter($this->env, ($context["foo"] ?? null), "html", null, true);
}
public function getTemplateName()
{
return "bar.twig";
}
public function isTraitable()
{
return false;
}
public function getDebugInfo()
{
return array ( 21 => 2, 19 => 1,);
}
public function getSourceContext()
{
return new Twig_Source("", "bar.twig", "/fuz/twigfiddle.com/files/environment/k85WDdymIFgSoXLc/twig/bar.twig");
}
}
答案 1 :(得分:0)
我找到了一种方法来完成我想要的东西,但问题并不是问题,所以它不会被标记为答案,但我发布的是如果其他人试图弄清楚如何做我想做的事情,请在这里快速回答。
具体来说,我试图在嵌套的Twig模板中包含JS和CSS文件,而我最初想要的方式是使用merge
标记,但是,如标记答案中的DarkBee所示,这是不可能的。
作为替代方案,我能够创建一个扩展程序,允许我执行我在全球范围内寻找的内容,使用尽可能多的不同阵列名称:
class arrayDefinitionExtension extends \Twig_Extension
{
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('addToArray', [$this, "addToArray"]),
new \Twig_SimpleFunction('getArray', [$this, "getArray"]),
);
}
private $arrays = [];
public function addToArray($name, $val) {
$this->arrays[$name][] = $text;
return "";
}
public function getArray($name) {
if(isset($this->arrays[$name])) {
return $this->arrays[$name];
} else {
return [];
}
}
}
用法:
base.php
$loader = new \Twig_Loader_Filesystem('/path/to/templates');
$twig = new \Twig_Environment($loader);
$twig->addExtension(new \arrayDefinitionExtension());
base.twig
{% block content %}
{% endblock %}
{% set includes = getArray("includes") %}
{% for include in includes %}
<script src="{{include}}" type="application/javascript"></script>
{% endfor %}
main.twig
{% extends "base.twig" %}
{% block content %}
{% include "test.twig" %}
{% endblock %}
test.twig
{% do addToArray("includes", "path/to/some/file.js") %}
请注意,这是顺序的,因此如果您在打印
content
标签后放置了<script>
块,则无法输出任何内容。