How do you get third-level menu items in Zotonic? - menubar

I would like to display third-level menu items in Zotonic.
For example if I have pages in a hierarchy like the following:
About Us
Careers
Why work here?
I want the Why work here? to be accessible in the drop-down menus.
How do you get third-level menu items in Zotonic?

I used Page Connections and a modified menu template. This requires Zotonic 0.5.0 or later.
Create a Predicate called Menu from text to text
Edit /modules/mod_menu/templates/_menu.tpl:
Turn the original menu template:
{% if menu %}
<ul id="{{ id_prefix }}navigation" class="clearfix at-menu do_superfish">
{% for mid,depth,nr,has_sub in menu %}
{% if not mid %}
{% if depth > 1 %}</ul></li>{% endif %}
{% else %}
{% if nr == 1 and not forloop.first %}<ul{% if mid|member:path %} class="onpath"{% endif %}>{% endif %}
<li id="{{ id_prefix }}nav-item-{{nr}}" class="{% if is_first %}first {% endif %}{% if is_last %}last{% endif %}">
<a href="{{ m.rsc[mid].page_url }}"
class="{{ m.rsc[mid].name }}{% if mid == id %} current{% else %}{% if mid|member:path %} onpath{% endif %}{% endif %}">{{ m.rsc[mid].short_title|default:m.rsc[mid].title }}</a>
{% if not has_sub %}</li>{% endif %}
{% endif %}
{% endfor %}
{% if forloop.last %}{% include "_menu_extra.tpl" %}{% endif %}
</ul>
{% endif %}
Into the third-level menu version:
{% if menu %}
<ul id="{{ id_prefix }}navigation" class="clearfix at-menu do_superfish">
{% for mid,depth,nr,has_sub in menu %}
{% if not mid %}
{% if depth > 1 %}</ul></li>{% endif %}
{% else %}
{% if nr == 1 and not forloop.first %}<ul{% if mid|member:path %} class="onpath"{% endif %}>{% endif %}
<li id="{{ id_prefix }}nav-item-{{nr}}" class="{% if is_first %}first {% endif %}{% if is_last %}last{% endif %}">
<a href="{{ m.rsc[mid].page_url }}"
class="{{ m.rsc[mid].name }}{% if mid == id %} current{% else %}{% if mid|member:path %} onpath{% endif %}{% endif %}">{{ m.rsc[mid].short_title|default:m.rsc[mid].title }}</a>
{% if depth == 2 %}
{% for submenu in m.rsc[mid].menu %}
{% if forloop.first %}<ul>{% endif %}
<li id="{{ id_prefix }}nav-item-{{nr}}" class="{% if is_first %}first {% endif %}{% if is_last %}last{% endif %}">
<a href="{{ m.rsc[submenu].page_url }}"
class="{{ m.rsc[submenu].name }}{% if submenu == id %} current{% else %}{% if submenu|member:path %} onpath{% endif %}{% endif %}">{{ m.rsc[submenu].short_title|default:m.rsc[submenu].title }}</a></li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
{% endif %}
{% if not has_sub %}</li>{% endif %}
{% endif %}
{% endfor %}
{% if forloop.last %}{% include "_menu_extra.tpl" %}{% endif %}
</ul>
{% endif %}
By adding a special case for the menu page connections of second-level items:
{% if depth == 2 %}
{% for submenu in m.rsc[mid].menu %}
{% if forloop.first %}<ul>{% endif %}
<li id="{{ id_prefix }}nav-item-{{nr}}" class="{% if is_first %}first {% endif %}{% if is_last %}last{% endif %}">
<a href="{{ m.rsc[submenu].page_url }}"
class="{{ m.rsc[submenu].name }}{% if submenu == id %} current{% else %}{% if submenu|member:path %} onpath{% endif %}{% endif %}">{{ m.rsc[submenu].short_title|default:m.rsc[submenu].title }}</a></li>
{% if forloop.last %}</ul>{% endif %}
{% endfor %}
{% endif %}
In Page Connections add *Menu*s to each page that needs third-level items in the menu

Related

Shopify liquid forloop.last of a certain block type

I have two for loops looking at blocks within a section and I am using an if statement to check the block type each time. I want to show a hr to separate each block of each type, unless its the last block where I don't want the hr to show.
I thought using forloop.last would work but for some reason, the forloop.last check is only working on the second loop. It seems the initial loop is not closing or the forloop.last is not picking up on the if statement for block type. Example code below:
{% if section.settings.productaccordion_active %}
<ul class="product-accordion product-accordion-small">
{% if section.settings.accordion_description_active %}
<li id="product-accordion-1">
<div class="product-accordion-title">Description</div>
<div class="product-accordion-content">
{%- for block in section.blocks -%}
{% if block.type == "accordion_description" %}
{% if block.settings.accordion_description_title %}
<h5>{{ block.settings.accordion_description_title }}</h5>
{{ block.settings.accordion_description_content }}
{% endif %}
{% unless forloop.last %}
<hr>
{% endunless %}
{% endif %}
{%- endfor -%}
</div>
</li>
{% endif %}
{% if section.settings.accordion_ingredients_active %}
<li id="product-accordion-2">
<div class="product-accordion-title">Ingredients</div>
<div class="product-accordion-content">
{%- for block in section.blocks -%}
{% if block.type == "accordion_ingredients" %}
{% if block.settings.accordion_ingredients_title %}
<h5>{{ block.settings.accordion_ingredients_title }}</h5>
{{ block.settings.accordion_ingredients_content }}
<br><span class="product-popup-link" data-popupid="popup_ingredient_A_breakdown">See breakdown</span>
<br><span class="product-popup-link" data-popupid="popup_ingredient_A_full">See full list</span>
{% endif %}
{% unless forloop.last %}
<hr>
{% endunless %}
{% endif %}
{%- endfor -%}
</div>
</li>
{% endif %}
Any help would be greatly appreciated.
The forloop.last condition cannot be fulfilled for each loop because you add an if condition. So if the last item in the loop is not of the type you display, then <hr> will never be displayed.
Here is something that should work (not tested).
First, you create two arrays containing only blocks with needed types.
{% liquid
assign description_blocks = section.blocks | where: "type", "accordion_description"
assign ingredient_blocks = section.blocks | where: "type", "accordion_ingredients"
%}
Then you loop through each array defined above.
This way, for each one, it will always iterate the last item of the loop.
<ul class="product-accordion product-accordion-small">
{% if section.settings.accordion_description_active %}
<li id="product-accordion-1">
{%- for block in description_blocks -%}
Do something
{% unless forloop.last %}
<hr>
{% endunless %}
{%- endfor -%}
</li>
{% endif %}
{% if section.settings.accordion_ingredients_active %}
<li id="product-accordion-2">
{%- for block in ingredient_blocks -%}
Do something
{% unless forloop.last %}
<hr>
{% endunless %}
{%- endfor -%}
</li>
{% endif %}
</ul>
Here is some documentation about the where filter:
https://shopify.github.io/liquid/filters/where/
HTH

How to populate a nav with yaml in Jekyll that contains accordions

I am looking for a way to build a navigation that is populated with a .yaml file. I can iterate over the yaml to create the nav items and correct urls that also adds an active class to the nav item when you are on that particular url. I uploaded a screenshot of the existing nav
nav getting populated with active class
my yaml file
nav:
- page: Home
url: /index.html
- page: Getting Started
url: /getting-started.html
- title: Delivery
subfolderitems:
- page: Intro
url: /Delivery/delivery-intro.html
- page: Set Up
url: /Delivery/delivery-deploy.html
- page: Thing 3
url: /thing3.html
- title: Group 2
subfolderitems:
- page: Piece 1
url: /piece1.html
- page: Piece 2
url: /piece2.html
- page: Piece 3
url: /piece3.html
- title: Group 3
subfolderitems:
- page: Widget 1
url: /widget1.html
- page: Widget 2
url: /widget2.html
- page: Widget 3
url: /widget3.html
my html file
<nav>
<ul id="nav-menu" class="nav nav-list">
{% for item in site.data.static-nav.nav %}
<li class="{% if item.url == page.url %} active-item {% endif %}">
{{ item.page }}
</li>
{% if item.subfolderitems[0] %}
{% for subitem in item.subfolderitems %}
{% if subitem.url == page.url %}
{% assign activesubitem = true %}
{% endif %}
{% endfor %}
<li class="parent {% if activesubitem == true %}collapsibleListOpen{% else %}collapsibleListClosed{% endif %}">
<div class="subtree-name">{{ item.title }}</div>
<ul class="nav nav-list">
{% for subitem in item.subfolderitems %}
<li class="{% if subitem.url == page.url %} active-item {% endif %}">
{{ subitem.page }}
</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>
I am running into an issue with the subfolder items being in accordions and having the parent accordion being toggled opened when one of the subitems matches the current url and therefore being active. Is there away to find the parent item with yaml and liquid? I then could somehow check if a parent nav item contains an active sub item ?
If anyone else is stuck on this, I was able to use {% break %}inside the for loop to break out of the loop. You may need a newish version of liquid to use {% break %}. I then assigned a variable that will add the class to have the correct accordion be opened when you open a subpage that is within that accordion.
<nav>
<ul id="nav-menu" class="nav nav-list">
{% for item in site.data.static-nav.nav %}
<li class="{% if item.url == page.url %} active-item {% endif %}">
{{ item.page }}
</li>
{% assign item_isOpen = false %}
{% if item.subfolderitems[0] %}
{% for subitem in item.subfolderitems %}
{% if subitem.url == page.url %}
{% assign item_isOpen = true %}
{% break %}
{% endif %}
{% endfor %}
<li class="{% if item_isOpen == true %} parent collapsibleListOpen {% else %} parent collapsibleListClosed {% endif %}">
<div class="subtree-name">{{ item.title }}</div>
<ul class="nav nav-list">
{% for subitem in item.subfolderitems %}
<li class="{% if subitem.url == page.url %} active-item {% endif %}">
{{ subitem.page }}
</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</ul>

Implement an if in jekyll tag page

I have a page showing all the posts ordered by tag. The thing is that I only want some tags to be shown, not all of them. The thing would be after the "for tag in site.tags" implement an if like tag == x. I'm new to Jekyll and ruby and I don't know how to do it :/
{% capture site_tags %}{% for tag in site.tags %}{{tag | first }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
{% assign tag_words = site_tags | split:',' | sort %}
<ul class="tags">
{% for item in (0..site.tags.size) %}{% unless forloop.last %}
{% capture this_word %}{{ tag_words[item] }}{% endcapture %}
<li>
<a href="#{{ this_word | cgi_escape }}" class="tag">{{ this_word }}
<span>({{ site.tags[this_word].size }})</span>
</a>
</li>
{% endunless %}{% endfor %}
</ul>
<div>
{% for item in (0..site.tags.size) %}{% unless forloop.last %}
{% capture this_word %}{{ tag_words[item] }}{% endcapture %}
<h2 id="{{ this_word | cgi_escape }}">{{ this_word }}</h2>
{% for post in site.tags[this_word] %}{% if post.title != null %}
<div>
<span style="float: left;">
{{ post.title }}
</span>
<span style="float: right;">
{{ post.date | date_to_string }}
</span>
</div>
<div style="clear: both;"></div>
{% endif %}{% endfor %}
{% endunless %}{% endfor %}
</div>
Change this:
{% capture site_tags %}
{% for tag in site.tags %}...{% endfor %}
{% endcapture %}
Into this:
{% capture site_tags %}
{% for tag in site.tags %}
{% if tag.title != 'excludedtag' %}...{% endif %}
{% endfor %}
{% endcapture %}
And change 'excludedtag' to the tag title you want to exclude.

phalconphp for loop with numeric on volt

Help to fix my code in phalconphp with volt I think so long
{% for casing in casings %}
{% set i = 0 %}
{% for case in cases if case.casing == casing.type %} //it have 4 loop but cases length is 20
{% set i += 1 %}
{% endfor %}
{% if i == 0 %}
No values set
{% else %}
<ul>
{% for case in cases if case.casing == casing.type %} // it repeat twice in my code
<li> {{ case.description }} - {{ case.value }} </li>
{% endfor %}
<ul>
{% endif %}
{% endif %}
I know have loop.length, loop.index in for loop but when I use if in loop it have not number I want.
{% for casing in casings %}
{% if loop.first %}
<ul>
{% endif %}
{% for case in cases if case.casing == casing.type %}
<li> {{ case.description }} - {{ case.value }} </li>
{% endfor %}
{% if loop.last %}
<ul>
{% endif %}
{% else %}
No values set
{% endfor %}
{% for casing in casings %}
{% if loop.first %}
<ul>
{% endif %}
{% for case in cases if case.casing == casing.type %}
<li> {{ case.description }} - {{ case.value }} </li>
{% endfor %}
{% if loop.last %}
<ul>
{% endif %}
{% else %}
No values set
{% endfor %}
Thankyou for supported

Display an image for a specific Shopify variant

I'm trying to display an image in my Shopify store if a product has a variant of "OS" , if it doesn't then I need to display a different image. I also need to display the title of each variant for the product. This is what I have now, but it doesn't seem to be working.
<div class="homepage-sizechart">
<div class="sizes">
{% if product.variants.title contains 'OS' %}
{{ 'onesize-triangle.png' | asset_url | img_tag }}
{% else %}
{{ 'size-triangle.png' | asset_url | img_tag }}
{% endif %}
{% for variant in product.variants %}
<span class="{{ variant.title }}-product {% if variant.inventory_quantity == 0 %}outofstock{% endif %}">{{ variant.title }}</span>
{% endfor %}
</div>
</div>
product.variants is a collection, so you'll need to loop through it to determine if one of the variants has a title containing 'OS'.
Something like this:
{% assign contains_os = false %}
{% for variant in product.variants %}
{% if variant.title contains 'OS' %}
{% assign contains_os = true %}
{% endif %}
{% endfor %}
<div class="homepage-sizechart">
<div class="sizes">
{% if contains_os %}
{{ 'onesize-triangle.png' | asset_url | img_tag }}
{% else %}
{{ 'size-triangle.png' | asset_url | img_tag }}
{% endif %}
{% for variant in product.variants %}
<span class="{{ variant.title }}-product {% if variant.inventory_quantity == 0 %}outofstock{% endif %}">{{ variant.title }}</span>
{% endfor %}
</div>
</div>

Resources