it-roy-ru.com

Установить переменную в родительской области видимости в Twig

В Smarty вы можете сделать

{$var = 'bla' scope=parent}

Возможно ли это в Twig?

Не предлагайте использовать блоки. Я знаю. Мне нужна переменная.

10
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, в то время как в дочернем шаблоне мы определяем ее внутри блока page.

Итак, Twig сделает следующее:

  1. Когда он отображает child.twig, он начинается с вершины base.twig, устанавливая значения по умолчанию для переменной page.
  2. Когда дело доходит до блока page, он увидит, что child.twig переопределяет этот блок. Таким образом, вместо этого он будет запускать блок page в child.twig.
  3. Внутри блока page в child.twig будут установлены новые значения для переменной page. Затем он вызовет функцию parent(), которая скажет ему вернуться к base.twig и отобразить родительский блок page.
  4. Затем он продолжит рендеринг страницы, заменяя любые дополнительные блоки, как определено в child.twig (в моем примере это будет визуализировать блок content).

Смотрите рабочий пример здесь . Помните, что это может стать более сложным, когда вы начнете добавлять несколько уровней наследования (например, шаблоны для внуков).

7
alexw

@ n3xus дал хороший ответ, на самом деле он мне тоже помог (спасибо), но вы также можете взглянуть на эту страницу из документации: Twig docs

Особенно приятной особенностью является возможность установки фрагмента text/html:

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

Упрощает создание очень специфических фрагментов контента из дочерних шаблонов.

6
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

Еще один подход заключается в том, чтобы увидеть глобальную конфигурацию веток в вашем приложении. Например в Silex:

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

Затем вы можете получить доступ к этой переменной во всех шаблонах:

Hello, {{someuser.name}}
0
Dean