M. Galardi
M. Galardi

Reputation: 130

Variable variables in Twig

I'm trying to write a menu with 1 level submenu using hash in Twig. My code is:

{% set regiones = {
patagonia:    { title: "Patagonia"},
pampa: { title: "Pampa"},
cuyo:     { title: "Cuyo"},
noreste:     { title: "Noreste"},
noroeste:     { title: "Noroeste"}
} %}

{% set patagonia = {
neuquen:    { title: "Neuquén"},
rionegro: { title: "Río Negro"},
chubut:     { title: "Chubut"},
santacruz:     { title: "Santa Cruz"},
tierradelfuego:     { title: "Tierra del Fuego"}
} %}

{% set pampa = {
buenosaires:    { title: "Buenos Aires"},
cordoba: { title: "Córdoba"},
lapampa:     { title: "La Pampa"},
santafe:     { title: "Santa Fe"}
} %}

{% set cuyo = {
mendoza:    { title: "Mendoza"},
sanjuan: { title: "San Juan"},
sanluis:     { title: "San Luis"}
} %}


<nav>
   <ul>
      {% for slug, item in regiones %}
         <li><a href="/{{ slug }}">{{ item.title }}</a>
            <ul>
               {% for slugg, itemm in {{ slug }}  %}
                  <li><a href="/{{ slugg }}">{{ itemm.title }}</a></li>
               {% endfor %}
            </ul>
         </li>
      {% endfor %}
   </ul>
</nav>

This line: " {% for slugg, itemm in {{ slug }} %} " don't work. How I can write in twig a variable variable like ${$slug} in PHP?

Thanks, Mikel

Upvotes: 1

Views: 306

Answers (1)

Matias Kinnunen
Matias Kinnunen

Reputation: 8540

_context holds the variables in the current context, so you can do:

{% for slugg, itemm in _context[slug] %}

Because you have not set variables noreste and noroeste, you need to surround the for block with an if block (otherwise Twig will throw an exception as _context doesn't have the keys noreste and noroeste):

{% if _context[slug] is defined %}
    <ul>
        {% for slugg, itemm in _context[slug] %}
            <li><a href="/{{ slugg }}">{{ itemm.title }}</a></li>
        {% endfor %}
    </ul>
{% endif %}

See TwiggFiddle


An alternative approach is to set the cities to a new hash like this:

{% set cities = {
    patagonia: {
        neuquen:        { title: "Neuquén"},
        rionegro:       { title: "Río Negro"},
        chubut:         { title: "Chubut"},
        santacruz:      { title: "Santa Cruz"},
        tierradelfuego: { title: "Tierra del Fuego"}
    },

    pampa: {
        buenosaires: { title: "Buenos Aires"},
        cordoba:     { title: "Córdoba"},
        lapampa:     { title: "La Pampa"},
        santafe:     { title: "Santa Fe"}
    },

    cuyo: {
        mendoza: { title: "Mendoza"},
        sanjuan: { title: "San Juan"},
        sanluis: { title: "San Luis"}
    }
} %}

And then modify your loop like this:

{% if cities[slug] is defined %}
    <ul>
        {% for slugg, itemm in cities[slug] %}
            <li><a href="/{{ slugg }}">{{ itemm.title }}</a></li>
        {% endfor %}
    </ul>
{% endif %}

And one more approach is to put regions and cities in the same hash:

{% set regiones = {
    patagonia: {
        title: "Patagonia",
        cities: {
            neuquen:        { title: "Neuquén"},
            rionegro:       { title: "Río Negro"},
            chubut:         { title: "Chubut"},
            santacruz:      { title: "Santa Cruz"},
            tierradelfuego: { title: "Tierra del Fuego"},
        },
    },
    pampa: {
        title: "Pampa",
        cities: {
            buenosaires: { title: "Buenos Aires"},
            cordoba:     { title: "Córdoba"},
            lapampa:     { title: "La Pampa"},
            santafe:     { title: "Santa Fe"},
        },
    },
    cuyo: {
        title: "Cuyo",
        cities: {
            mendoza: { title: "Mendoza"},
            sanjuan: { title: "San Juan"},
            sanluis: { title: "San Luis"},
        },
    },
    noreste: {
        title: "Noreste",
    },
    noroeste: {
        title: "Noroeste",
    },
} %}

<nav>
   <ul>
      {% for slug, item in regiones %}
         <li>
             <a href="/{{ slug }}">{{ item.title }}</a>
             {% if item.cities is defined %}
                 <ul>
                     {% for slugg, itemm in item.cities %}
                         <li><a href="/{{ slugg }}">{{ itemm.title }}</a></li>
                     {% endfor %}
                 </ul>
             {% endif %}
         </li>
      {% endfor %}
   </ul>
</nav>

Upvotes: 1

Related Questions