Liquid powered menu

Updated on 20-October-2016 at 10:16 AM

Basic implementation

In this section we will take a look at the most basic implementation of a Liquid powered menu rendered in a simple unordered list.

When using the collection powered render method you can render the output in whetever structure you want (table, list, group of divs).

Create the menu

The first thing to do is to create the menu structure in the Admin console. Head over to the Site Manager -> Menu panel and build your menu tree. For this example we'll use this 2 level deep structure below:

Display it on a page

Now that the menu is in place let's insert the menu on the page or template. Create a blank page and insert the menu module like so:

{module_menu render="collection" menuId="2165233" template="" collection="menu1"}

Because we are suppressing the module's output using template="" this module will not output anything. However we can use the menu1 collection and Liquid to do the rendering.

Paste the code below just below the menu.

<ul id="main-menu" class="sm sm-blue">
  {% if menu1.items %} 
	{% for i in menu1.items %}
  	<li><a href="{{i.url}}">{{i.label}}</a> 
			{% if i.items %}
     		<ul>
			{% for j in i.items %}
				<li><a href="{{j.url}}">{{j.label}}</a> 
					{% if j.items %}
        			<ul>
					{% for k in j.items %}
						<li>
            				<a href="{{k.url}}">{{k.label}}</a>
						</li>
					{% endfor %}
        			</ul>
        			{% endif %}
				</li>
			{% endfor %}
    		</ul>
    		{% endif %}
  	</li>
   {% endfor %} 
  {% endif %}
</ul>

Although the code above might look intimidating at first glace it is just a collection of nested IF and FOR loops that iterate over each menu item. We first need to check if the current menu item has children and if so iterate over all of them.

Note: If you need to have a deeper menu you need to add additional IF and FOR blocks.

The menu will be represented like so:

<ul id="main-menu" class="sm sm-blue">
  <li><a href="/">Shop</a>
    <ul>
<li><a href="https://perfume10.worldsecuresystems.com/classic-boutique">Classic</a>
        <ul>
          <li> <a href="https://perfume10.worldsecuresystems.com/woody-parfumes">Woody</a> </li>
          <li> <a href="https://perfume10.worldsecuresystems.com/spicy-perfumes">Spicy</a> </li>
        </ul>
      </li>
      <li><a href="https://perfume10.worldsecuresystems.com/designer-brands">Designer</a> </li>
    </ul>
  </li>
  <li><a href="https://perfume10.worldsecuresystems.com/BlogRetrieve.aspx?BlogID=4405">Blog</a> </li>
  <li><a href="https://perfume10.worldsecuresystems.com/ForumRetrieve.aspx?ForumID=691">Forum</a>
    <ul>
      <li><a href="https://perfume10.worldsecuresystems.com/ForumRetrieve.aspx?ForumID=691">Community</a> </li>
      <li><a href="https://perfume10.worldsecuresystems.com/ForumRetrieve.aspx?ForumID=677">Sample Forum 1</a> </li>
    </ul>
  </li>
  <li><a href="https://perfume10.worldsecuresystems.com/faqs">FAQ</a> </li>
  <li><a href="https://perfume10.worldsecuresystems.com/about-us">About Us</a> </li>
  <li><a href="https://perfume10.worldsecuresystems.com/contact">Contact Us</a> </li>
  <li><a href="https://perfume10.worldsecuresystems.com/signup">Sign-Up!</a>
    <ul>
      <li><a href="https://perfume10.worldsecuresystems.com/member/index">Member profile page</a> </li>
    </ul>
  </li>
</ul>

At this point we have the menu represented as an unordered list on the page. Moving on we can use a 3-rd party menu library to further style and animate it.

Other menu customizations

Show the menu only if the user is logged in

The logic

You have seen in a previous section how to generate a basic menu using Liquid . Let's pick up from there and see how to show it only to users that have logged in. The logic behind is simple. Take a look at your visitor details in the Liquid global object :

{{globals.user | json}}

What we need to do is just apply an IF condition to the Liquid code that generates the menu markup, so that it carries out the action only if the isLoggedIn condition is true

The build

To enable this scenario, simply wrap your Liquid menu generation markup with your If condition:

{% if globals.user.isLoggedIn contains "true" %} 
   	 Liquid Code 
    {% else %}
   	 Custom message
    {% endif %}

Here's the markup in its basic implementation, with no specific menu plugin used:

{% if {{globals.user.isLoggedIn}} contains "true" %} 
<ul> 
  {% if menu1.items %} 
    {% for i in menu1.items %} 
    <li>
      <a href="{{i.url}}">{{i.label}}</a>
      {% if i.items %} 
        <ul> 
        {% for j in i.items %} 
          <li>
          <a href="{{j.url}}">{{j.label}}</a>
          {% if j.items %} 
            <ul> 
            {% for k in j.items %} 
              <li> 
                <a href="{{k.url}}">{{k.label}}</a>
              </li> 
            {% endfor %} 
            </ul> 
          {% endif %} 
          </li> 
        {% endfor %} 
        </ul>
      {% endif %} 
    </li> 
    {% endfor %} 
  {% endif %} 
</ul> 
{% else %} 
<p>Some message, maybe</p> 
{% endif %}

Here's how this will output on an actual page:

https://liquidexamples.worldsecuresystems.com/general-show-menu-if-logged-in

Conclusion

Before the introduction of Liquid, this would have only been possible with custom java script implementations. You would load the menu in a hidden container, and display it if the visitor was logged in. Still the menu was there.

Using Liquid, you're acutally enabling (or not) the content on the server-side, performing operations and conditions before render time, so the output is clean, fast and secure.

Show the menu only if the logged in user has access to a particular securezone

The logic

To implement this setup we will need to use module_data to check if the user is subscribed to a secure zone. The menu item will be displayed only if the secure zone with the known ID is in the user's access list.

The build

Above the menu module let's insert this module_data:

{module_data version="v3" resource="customers" resourceid="{{globals.user.entityId}}" subresource="securezones" where="\{'zoneId': 51\}" collection="userSz"}

This module will check if the secure zone with the ID 51 is in the currently logged in user's access list. If the module returns 1 item the user is subscribed to the secure zone. If the module returns 0 either:

  • nobody is logged in
  • the secure zone with the ID 51 was not found
  • the user is not subscribed to this secure zone

Next let's insert (below the module_data menu above) the code that actually renders the menu items:

{module_menu menuID="592057" version="1" template="" collection="menu1"}
                    
<ul id="main-menu" class="sm sm-blue">
  {% if menu1.items %} 
	{% for i in menu1.items %}
   
    {% if i.label != "FAQ" or  userSz.totalItemsCount > 0%}
    
  	<li><a href="{{i.url}}">{{i.label}}</a> 
			{% if i.items %}
     		<ul>
			{% for j in i.items %}
				<li><a href="{{j.url}}">{{j.label}}</a> 
					{% if j.items %}
        			<ul>
					{% for k in j.items %}
						<li>
            				<a href="{{k.url}}">{{k.label}}</a>
						</li>
					{% endfor %}
        			</ul>
        			{% endif %}
				</li>
			{% endfor %}
    		</ul>
    		{% endif %}
  	</li>
    
    {%endif%}
    
   {% endfor %} 
  {% endif %}
</ul>

Notice the extra condition - using {% if i.label != "FAQ" or userSz.totalItemsCount > 0%} we only display the menu item "FAQ" if the current user has access to the secure zone with the id 51.

Show the menu only for a specific country code

The logic

You have seen in a previous section how to generate a basic menu using Liquid . Let's pick up from there and see how to show it only to users from a specific country. The logic behind is simple. Take a look at yout visitor details in the Liquid global object :

{{globals.visitor | json}}

What we need to do is just apply an IF condition to the Liquid code that generates the menu markup, so that it carries out the action only if the visitor country is {{globals.visitor.country}}

The build

To enable this scenario, simply wrap your Liquid menu generation markup with your If condition:

{% if {{globals.site.countryCode}} contains "{{globals.visitor.country}}" %}
- Liquid Code -
{% else %}
-Custom message-
{% endif %}

Here's the markup in its basic implementation, with no specific menu plugin used:

{% if {{globals.site.countryCode}} contains "XX" %} 
<ul>
  {% if menu1.items %} 
    {% for i in menu1.items %} 
      <li> 
      <a href="{{i.url}}">{{i.label}}</a>
      {% if i.items %} 
        <ul> 
        {% for j in i.items %} 
          <li>
          <a href="{{j.url}}">{{j.label}}</a>
          {% if j.items %} 
            <ul> 
            {% for k in j.items %} 
              <li> 
              <a href="{{k.url}}">{{k.label}}</a>
              </li> 
            {% endfor %} 
            </ul> 
          {% endif %} 
          </li> 
        {% endfor %} 
      </ul>
      {% endif %} 
      </li> 
    {% endfor %} 
  {% endif %} 
    </ul> 
  {% else %} 
<p>Some message, maybe</p> 
{% endif %}

Here's how this will output on an actual page:

https://liquidexamples.worldsecuresystems.com/general-show-menu-if-country-code-is-XX

Bootstrap implementation

The following is a specific example, using the Bootstrap menu plugin:

https://liquidexamples.worldsecuresystems.com/bootstrap-show-menu-if-country-code-is-XX

<ul class="nav navbar-nav">
  {% if menu1.items %} 
	{% for i in menu1.items %}	
{% if i.items %}
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" href="{{i.url}}">{{i.label}}<span class="caret"></span></a> 
{% else %}
<li><a href="{{i.url}}">{{i.label}}</a> 
			
{% endif %}
{% if i.items %}
     		<ul class="dropdown-menu" role="menu">
			{% for j in i.items %}
				<li><a href="{{j.url}}">{{j.label}}</a> 
					{% if j.items %}
        			<ul>
					{% for k in j.items %}
						<li>
            				<a href="{{k.url}}">{{k.label}}</a>
						</li>
					{% endfor %}
        			</ul>
        			{% endif %}
				</li>
			{% endfor %}
    		</ul>
    		{% endif %}
  	</li>
   {% endfor %} 
  {% endif %}
</ul>

Conclusion

Before the introduction of Liquid, this would have only been possible with custom java script implementations. You would load the menu in a hidden container, and display it if the visitor country was a specific value, as rendered by {module_visitorcountrycode}. Still the menu was there.

Using Liquid, you're acutally enabling (or not) the content on the server-side, performing operations and conditions before render time, so the output is clean, fast and secure.