I'm new to twig, and I'm trying to create a nav menu with sub menus from a provided schema which looks like this-
menu_items: [
{
url: 'http://testurl.com',
text: 'Menu Item 1',
active: true,
sub_menu: [
{
url: 'http://testurl.com',
text: 'Sub menu Item 1',
},
{
url: 'http://testurl.com',
text: 'Sub menu Item 2',
},
],
},
]
The menu is showing up just fine, but I'm struggling to get the correct syntax to get those sub menu items populated. I put an if statement in because there's not always a sub menu, and then a for loop to create a list item for each sub menu item in the schema, but alas.
{% if menu_items %}
<nav>
<ul>
{% for item in menu_items %}
<li>
{{ item.text }}
{% if item.sub_menu %}
<ul>
{% for sub_menu in item %}
<li>
<a href="{{ item.sub_menu.url }}">
{{ item.sub_menu.text }}
</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
</nav>
{% endif %}
Anyone know where I'm going wrong?
It looks like you are not referencing the sub_menu items correctly. Try
{% for sub in item.sub_menu %} ... {% endfor %}
It's also helpful if the sub_menu array is empty. The empty test evaluates to true if the variable is null, false, an empty array, or an empty string
{% if item.sub_menu is not empty %} ... {% endif %}
Related
{% set pages = craft.entries.section('interests').all() %}
{% nav page in pages %}
<div class="nav__column">
<li class="nav__parent">
{{ page.getLink() }}
{% ifchildren %}
<ul>
{% children %}
</ul>
{% endifchildren %}
</li>
</div>
{% endnav %}
When using this every nav item has the class of nav parent
Can I determine what classes are on the nav item depending on whether it is a child or parent nav item?
Just wrap that class in the ifchildren conditional, e.g:
{% set entries = craft.entries.section('pages') %}
<ul id="nav">
{% nav entry in entries %}
<li{% ifchildren %} class="nav__parent{% endifchildren %}">
{{ entry.title }}
{% ifchildren %}
<ul>
{% children %}
</ul>
{% endifchildren %}
</li>
{% endnav %}
</ul>
As an aside, your example code is invalid markup; <li> elements can only appear within a valid list type, e.g. <ul> or <ol>.
In the product.twig file, i need to include another twig file , the file gets linked and working, but that disables the add-to-cart button in every product page
{{ header }}
<div id="product-product" class="container">
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li>{{ breadcrumb.text }}</li>
{% endfor %}
</ul>
<div class="row">{{ column_left }}
{{ include('default/template/extension/total/demo_file.twig') }}
{% if column_left and column_right %}
{% set class = 'col-sm-6' %}
{% elseif column_left or column_right %}
{% set class = 'col-md-9 col-sm-12' %}
{% else %}
{% set class = 'col-sm-12' %}
{% endif %}
Event is bind on the add to cart button. The even code lies in the same file , so make sure the id of the button is same as previous button you are replacing.
Other way could be updating the event bind function jQuery selector.
Im trying to loop through this (for me) quite complex array with Twig. I want to be able to print out all elements. How would you do that? Below is the array and the code im currently trying.
This is the array: https://pastebin.com/TZSANFpW
I have tried this so far but it gives me error: "Notice: Array to string conversion in "
{% for route in routes %}
<p>
{{ route.admin }}
</p>
{% endfor %}
In order to read out a full array, you would to create some form of recursion.
You could achieve this with a macro in the line of
macros.twig
{% macro readArray(array) %}
{% import _self as macros %}
{% if not array is iterable %}
{{ array }}
{% else %}
{% for k,v in array %}
<ul>
<li>
{{ k }}: {{ macros.readArray(v) }}
</li>
</ul>
{% endfor %}
{% endif %}
{% endmacro %}
main.twig
{% import "macros.twig" as macros %}
{{ macros.readArray(results) }}
example
{% include './partial/project.twig' with {'status': 'Past Project',
'statusClass': 'past',
'heroImage': "/dist/images/projects/project-south16th.jpg",
'logo': '/dist/images/logo-south16th.png',
'desc': '23 three- and four-bed townhomes',
'address': '15885 16 Avenue, South Surrey',
'showGallery': true,
'galleryID': 'south16th',
'link': '#',
'galleryImages': "
{% for i in range(1, 10) %}
<a data-fancybox='south16th' href='{{ theme.uri }}/dist/images/gallery/south16/{{ i }}.jpg'></a>
{% endfor %}
"
} %}
The above code is not valid because it seems like twig doesn't allow nested tag in the include tag? Or did I do something wrong?
Is there another way to achieve it? I would like to repeat this code X times and pass it to the template:
{% for i in range(1, 10) %}
<a data-fancybox='south16th' href='{{ theme.uri }}/dist/images/gallery/south16/{{ i }}.jpg'></a>
{% endfor %}
To achieve this you would need to switch up to embed instead of include
index.twig
{% embed 'include.twig' with { 'theme': { 'uri' : 'https://www.example.com', 'pictures': 10, }, } %}
{% block pictures %}
{% for i in 1..theme.pictures %}
<li><a data-fancybox='south16th' href='{{ theme.uri }}/dist/images/gallery/south16/{{ i }}.jpg'></a></li>
{% endfor %}
{% endblock %}
{% endembed %}
include.twig
<h1>Include</h1>
<h2>{{ theme.uri }} - {{ theme.pictures }}</h2>
<ul>
{% block pictures %}
{% endblock %}
</ul>
twigfiddle
note: variables you'd define in include.twig will also be available inside the embed
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?
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',
],
);
Change this in the file page1/skeleton.twig:
{% for sec in test %}
Then it will work.
I tried it. Make sure you understand why!