Twig:从包含的模板中将项目添加到数组

2022-01-22 00:00:00 arrays php symfony twig

当数组在主文件中定义时,如何在 include 标记内向数组中添加项?

How can you add an item to an array within an include tag when the array is defined in the main file?

请注意,这个问题与 Twig 中的其他数组问题明显不同,因为我试图从主文件中包含的模板中修改值.

Please note this question is distinctly different from other array questions in Twig because I'm trying to modify the value from within an included template in the main file.

例如:

ma​​in.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 两者的组合正在尝试修改.

Currently the output from main.twig gives me only the initial test1 item, and not the combination of the two which test.twig is trying to modify.

我可能不得不使用一个附加功能.这里的目标基本上是让 included 模板能够在 HTML 文件中添加其他 CSS、JS 等,而无需修改父模板.

I may have to utilize an added function. The goal here is basically to allow included templates the ability to add other CSS, JS, etc, in HTML files without having to modify the parent templates.

这是一个 Twig Fiddle 供您使用,它会显示输出.

Here is a Twig Fiddle for you to play with which shows the output.

请注意,对于寻找此问题答案的其他人,我试图完成的可能是使用 Twig 扩展,该扩展具有向数组添加项目的功能,以及访问它的第二个函数.请在下面查看我的未标记为正确的答案,以了解可能执行此操作的方法.如上所述,我的问题是不可能的,正如 DarkBee 所示.

Please note for other people looking for an answer to this question, what I was attempting to accomplish is possible utilizing a Twig extension with a function that adds items to the array, and a second function to access it. Please view my answer below, that is not marked as correct, to see a way to potentially do this. My question, as stated, is impossible, as shown by DarkBee.

推荐答案

这不能在 Twig 中完成,从模板的编译源中可以看出,每个包含的模板都有自己的私有范围因为上下文数组是基于值而不是引用

This can't be done in Twig, as seen in the compiled source of the templates each included templats get his own private scope as the context array is based by value and not by reference

$this->loadTemplate("bar.twig", "main.twig", 2)->display($context);

然后在包含的模板中调用 doDisplay

which then calls doDisplay in the included template

受保护的函数 doDisplay(array $context, array $blocks = array())

注意

您可以通过创建您自己的 Twig_EnvironmentTwig_Template 来改变这种行为,但快速浏览一下就会发现您有很多功能d 需要覆盖.

You could alter this behaviour by creating your own Twig_Environment and Twig_Template but a quick look shows me that there are quite some functions you'd need to override.

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");
    }
}

相关文章