web-dev-qa-db-ja.com

Twigの親スコープに変数を設定します

Smartyでは次のことができます

{$var = 'bla' scope=parent}

Twigで可能ですか?

ブロックの使用を提案しないでください。知っている。変数が必要です。

12
disfated

base.twig

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

child.twig

{% set title = 'ChildTitle' %}
11
n3xus

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変数を定義し、子テンプレートではinsidepageブロック。

したがって、Twigは次のことを行います:

  1. _child.twig_をレンダリングすると、_base.twig_の先頭から開始され、page変数のデフォルト値が設定されます。
  2. pageblockになると、_child.twig_がそのブロックをオーバーライドすることがわかります。したがって、代わりに_child.twig_でpageブロックを実行します。
  3. _child.twig_のpageブロック内で、page変数の新しい値を設定します。次に、parent()を呼び出し、_base.twig_に戻って、親のpageブロックをレンダリングするように指示します。
  4. その後、ページのレンダリングを続行し、_child.twig_で定義されている追加のブロックを置き換えます(私の例では、contentブロックをレンダリングします)。

実例を参照してください ここ 。複数の継承レイヤー(孫テンプレートなど)を追加し始めると、これがより複雑になる可能性があることに注意してください。

8
alexw

@ n3xusは素晴らしい答えを出しました、それは実際に私も助けました(ありがとう)、しかしあなたはまたドキュメントからこのページを見たいかもしれません: Twig docs

特に優れた機能の1つは、text/htmlのチャンクを設定する機能です。

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

子テンプレートから非常に特定のコンテンツを簡単に生成できます。

7
Petar Zivkovic

変数をサブテンプレートから「オーバーライド可能」にしたいだけの場合は、次のように親に変数を設定できます。

{% 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>

私はそれがほとんどの状況でうまくいくと思います。親変数を子によって強制的にオーバーライドするのではなく、親は変数を子によってオーバーライドさせます。オーバーライドするのではなく、連結など、親でさまざまな動作を定義することもできます。

3
Moss

子ページでは次のものを使用できます。

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

私がちょうど発見したこのようなことをするための素晴らしい方法:

parent.twig

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

{# somewhere later #}

{{ subvar }}

child.twig

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

子テンプレートでブロックsubvarが定義されていない場合、parent.twigの変数は空になります。

1
Joshua

もう1つのアプローチは、アプリケーションでtwig構成をグローバルに確認することです。たとえば、Silexでは次のようになります。

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

その後、すべてのテンプレートでその変数にアクセスできます。

Hello, {{someuser.name}}
0
Dean