在Twig中的父作用域中设置变量

时间:2013-11-08 06:06:19

标签: templates variables scope twig variable-assignment

在Smarty你可以做到

{$var = 'bla' scope=parent}

在Twig有可能吗?

不建议使用块。我知道。我需要变量。

8 个答案:

答案 0 :(得分:11)

base.twig

<title>{{ title|default('example.com') }} - My cool site</title>

child.twig

{% set title = 'ChildTitle' %}

答案 1 :(得分:8)

如果您不想使用default()过滤器(即,当您希望在父模板和子模板中多次使用变量时),您实际上可以定义一个包含整个模板的块父模板中的页面,然后将其他块嵌套在其中:

{# base.twig #}

{# Default page properties.  You can override these in the `page` block of your child templates. #}
{% set page = page | default({}) | merge({
    "title"       : "My Default Title",
    "description" : "Default description"
}) %}

{% block page %}
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta name="description" content="{{ page.description }}"> 
            <title>{{ page.title }}</title>

            ...

        </head>
        <body>
            {% block content %}{% endblock %}
        </body>
    </html>
{% endblock %}

然后,您可以通过设置值然后调用page来覆盖子模板中page块中的parent()变量:

{# child.twig #}

{% extends "base.twig" %}

{% block page %}
    {# By putting this in a special block, we ensure that it will be set AFTER the default values are set in the parent template, 
    but BEFORE the page itself is rendered. #}

    {% set page = page | merge({
        "title"       : "Child Page",
        "description" : "Welcome to the child page!"
    }) %}    

    {{ parent() }}
{% endblock %}

{% block content %}
    ...
{% endblock %}

请注意,在父模板中,我们在page块之外定义page变量,而在子模板中我们定义里面 {{1}阻止。

因此,Twig将执行以下操作:

  1. 呈现page时,它会从child.twig的顶部开始,设置base.twig变量的默认值。
  2. 说到page ,它会看到page会覆盖该块。因此,它会在child.twig中运行page块。
  3. child.twig的{​​{1}}块内,它会为page变量设置新值。然后它会调用child.twig,告诉它返回page并渲染父parent()块。
  4. 然后它将继续呈现页面,替换base.twig中定义的任何其他块(在我的示例中,它将呈现page块)。
  5. 查看工作示例here。请注意,当您开始添加多层继承时(例如,孙子模板),这会变得更加复杂。

答案 2 :(得分:7)

@ n3xus给出了一个很好的答案,它实际上也帮助了我(谢谢),但您可能还想从文档中查看此页面:Twig docs

一个特别好的功能是能够设置一大块text / html:

{% set title %}
    <i class="icon-user"></i>
    {{ user.username | capitalize }}
    <small>{{ user.email | lower }}</small>
{% endset %}

可以轻松地从子模板中生成非常具体的内容。

答案 3 :(得分:3)

如果您只是希望变量可以覆盖&#39;从子模板中,您可以在父类中设置变量,如下所示:

{% set title = (title|default('My Page')) %}

所以你可以设置这样的情况......

base.twig

<html>
  <head>
    <title>{{title}}</title>
  </head>
  <body>
    {% block content %}
    {% end block %}
  </body>
</html>

parent.twig

{% extends 'base.twig' %}

{% set title = (title|default('My Page')) %}

child.twig

{% extends 'parent.twig' %} 

{% set title='My Subpage' %}   

{% block content %}
  This is the Sub-page.
{% end block %}

最终结果将是:

<html>
  <head>
    <title>My Subpage</title>
  </head>
  <body>
    This is the Sub-page.
  </body>
</html>

我认为这适用于大多数情况。父母不是强迫孩子覆盖父var,而是让孩子们覆盖父母。变量被子项覆盖。您还可以在父级中定义不同的行为,例如连接而不是覆盖。

答案 4 :(得分:2)

您可以在子页面中使用以下内容:

{% set title = 'your desired title' %}

答案 5 :(得分:1)

我刚刚发现这样做的好方法:

parent.twig

{% set subvar = block('subvar') %}

{# somewhere later #}

{{ subvar }}

child.twig

{% block subvar %}
    anything you want
{% endblock %}

如果您的子模板未定义块subvar,则parent.twig中的变量将为空。

答案 6 :(得分:0)

另一种方法是在应用程序中全局查看twig配置。例如在Silex中:

$app['twig']->addGlobal('someuser', $user);

然后,您可以在所有模板中访问该变量:

Hello, {{someuser.name}}

答案 7 :(得分:-1)

set tagembed

一起使用

示例:

parent.twig

{%  block child %}

{% endblock %}

I say: {{ var }}

child.twig

 {% embed "parent.twig" %}
     {% block child %}
 I child, but i not to fail set    
         {% endblock %}
    {%  set var='bla' %}

 {% endembed %}