john_a john_a - 2 months ago 12
Twig Question

variables {% set %} in a skeleton file's 'block' don't get recognized , and can't be used when extnding the file?

I have a symfony3/twig skeleton template

page1/skeleton.twig
{# set default values #}
{% block content %}
{% set test = {
sec1: {
title: "null",
content: 'null'
},
}
%}
{% endblock %}
<ul>
19 {% for sec in test[0:] %}
<li>
<p{{ sec.title }}</p>
<div>
<p>{{ sec.content }}</p>
</div>
</li>
{% endfor %}
</ul>


I then create a layout template that extends the skeleton with 'real' data

page1/layout.html.twig
{% extends 'page1/skeleton.html.twig' %}

{% block content %}
{% set test = {
sec1: {
title: "title1",
content: 'content2'
},
sec2: {
title: "title2",
content: 'content2'
}
%}
{% endblock %}


But when I generate/publish the page, Symfony fires an error

Variable "test" does not exist in :page1:skeleton.html.twig at line 19
500 Internal Server Error - Twig_Error_Runtime


complaining about the skeleton itself.

That 'test' array is defined in the skeleton. Afaict from reading the docs on 'block', 'extends' & 'set', and can't figure out what exactly the problem is.

What do I need to change to eliminate this error?

Answer

blocks in twig have their own variable scope.
Variables created inside a block can't be accessed outside of it.

Imo you should only test if the variable exist and otherwise create the default value :

skeleton.twig

    {% if not test  is defined %}
        {% 
            set test = {
                sec1: {
                    title:   "null",
                    content: 'null'
                },
            }
        %}
    {% endif %}
    <ul>
    {% for sec in test[0:] %}
        <li>
            <p{{ sec.title }}</p>
            <div>
                <p>{{ sec.content }}</p>
            </div>
        </li>
    {% endfor %}
    </ul>

controller.php

<?php
    echo $twig->render('page/page.twig', array(
           'foo' => [
               'title' => 'title1',
               'content' => content1',
            ],
    );