Django-CMS: How do I get a parent item of a currently active child page to highlight in the navigation menu? - django-cms

The standard menu.html that comes with Django CMS seems really easy but I simply can't figure out how to highlight a menu item that has children that are currently active.
I tried this:
{% if child.children and child.selected %} active dropdown{% endif %}
But that, for some odd reason, doesn't work.
Below is the full code of the menu.html:
{% load i18n menu_tags cache %}
{% for child in children %}
<li class="{% if child.ancestor %}ancestor{% endif %}
{% if child.selected %} active{% endif %}
{% if child.children %} dropdown{% endif %}
---> {% if child.selected and child.children %} active dropdown{% endif %}">
{% if child.children %}
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
{{ child.get_menu_title }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
</ul>
{% else %}
<span>{{ child.get_menu_title }}</span>
{% endif %}
</li>
{% if class and forloop.last and not forloop.parentloop %}{% endif %}
{% endfor %}

Thanks to Martin Koistinen of Divio, I got a working solution:
Template tag and its config:
{% show_menu 0 1 0 0 "menu.html" %}
Menu.html:
{% load i18n menu_tags cache %}
{% for child in children %}
<li class="{% if child.ancestor %}ancestor{% endif %}{% if child.selected %} active{% endif %}">
{{ child.get_menu_title }}
</li>
{% endfor %}

Related

How to show mobile menu on Shopify Site

I have designed a new site using the Timber Framework in Shopify and I am now trying to sort out the responsive side to ensure this works on all devices properly.
The problem I am currently facing is that when the screen is resized to below 768px the desktop menu goes away which is fine but no menu shows up at all and I am not sure why this is. Initially when I added the Timber Framework then this was working and I have looked through the theme.liquid file but can't work why this is happening.
The site itself can be viewed at : http://www.prontaprint247.com
If somebody could please advise as to where I have gone wrong as not sure how to fix this issue.
Any help or advice would be appreciated.
My menu code in theme.liquid
<div id="NavDrawer" class="drawer drawer--left">
<div class="drawer__header">
<div class="drawer__title h3">{{ 'layout.drawers.browse' | t }}</div>
<div class="drawer__close js-drawer-close">
<button type="button" class="icon-fallback-text">
<span class="icon icon-x" aria-hidden="true"></span>
<span class="fallback-text">{{ 'layout.drawers.close_menu' | t }}</span>
</button>
</div>
</div>
<!-- begin mobile-nav -->
<ul class="mobile-nav">
<li class="mobile-nav__item mobile-nav__search">
{% include 'search-bar' %}
</li>
{% for link in linklists.main-menu.links %}
{% comment %}
Create a dropdown menu by naming a linklist the same as a link in the parent nav
More info on dropdowns:
- http://docs.shopify.com/manual/your-website/navigation/create-drop-down-menu
{% endcomment %}
{% assign child_list_handle = link.title | handleize %}
{% if linklists[child_list_handle].links != blank %}
<li class="mobile-nav__item{% if link.active %} mobile-nav__item--active{% endif %}" aria-haspopup="true">
<div class="mobile-nav__has-sublist">
{{ link.title }}
<div class="mobile-nav__toggle">
<button type="button" class="icon-fallback-text mobile-nav__toggle-open">
<span class="icon icon-plus" aria-hidden="true"></span>
<span class="fallback-text">See More</span>
</button>
<button type="button" class="icon-fallback-text mobile-nav__toggle-close">
<span class="icon icon-minus" aria-hidden="true"></span>
<span class="fallback-text">{{ 'cart.general.close_cart' | t | json }}</span>
</button>
</div>
</div>
<ul class="mobile-nav__sublist">
{% for childlink in linklists[child_list_handle].links %}
<li class="mobile-nav__item {% if childlink.active %} mobile-nav__item--active{% endif %}">
{{ childlink.title | escape }}
</li>
{% endfor %}
</ul>
</li>
{% else %}
<li class="mobile-nav__item{% if link.active %} mobile-nav__item--active{% endif %}">
{{ link.title }}
</li>
{% endif %}
{% endfor %}
{% comment %}
If customer accounts are enabled, provide login and create account links
{% endcomment %}
{% if shop.customer_accounts_enabled %}
{% if customer %}
<li class="mobile-nav__item">
{% if customer.first_name != blank %}
{% capture first_name %}{{ customer.first_name }}{% endcapture %}
{{ 'layout.customer.logged_in_as_html' | t: first_name: first_name }}
{% else %}
{{ 'layout.customer.account' | t }}
{% endif %}
</li>
<li class="mobile-nav__item">
{{ 'layout.customer.log_out' | t | customer_logout_link }}
</li>
{% else %}
<li class="mobile-nav__item">
{{ 'layout.customer.log_in' | t | customer_login_link }}
</li>
<li class="mobile-nav__item">
{{ 'layout.customer.create_account' | t | customer_register_link }}
</li>
{% endif %}
{% endif %}
</ul>
<!-- //mobile-nav -->
</div>

Liquid default expanded menu

I have a liquid dropdown menu with a list of products that only expand when you click. I figured out how to open it by default when loading the site.
I simply found the <ul> tag for my dropdown list and changed it from this:
<ul id="Collapsible{{ forloop.index }}" class="site-nav__submenu site-nav__submenu--expanded" aria-hidden="false">
to this:
<ul id="Collapsible{{ forloop.index }}" class="site-nav__submenu site-nav__submenu--expand" aria-hidden="false">
However, I would also like it to be closed by default on small screens.
So far I haven't been able to find a solution that allows me to do that. I'm open to both liquid and CSS solutions. Anyone got any ideas?
Here is my code as it looks now with the default expand:
<div class="grid">
<nav class="grid__item small--text-center medium-up--one-fifth" id="makeShort" role="navigation">
<hr class="hr--small medium-up--hide">
<button data-target="site-nav" id="ToggleMobileMenu" class="mobile-menu-icon medium-up--hide" aria-haspopup="true" aria-owns="SiteNav">
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
<span class="icon__fallback-text">{{ 'layout.navigation.menu' | t }}</span>
</button>
<div id="SiteNav" class="site-nav" role="menu">
<ul class="list--nav">
{% for link in menus.main-menu.links %}
{% assign child_list_handle = link.title | handleize %}
{% if menus[child_list_handle].links != blank %}
<li class="site-nav--has-submenu site-nav__element">
{% if link.title == 'Shop' %}
<button class="site-nav__link btn--link site-nav__expand hidden" aria-expanded="false" aria-controls="Collapsible{{ forloop.index }}">
{{ link.title }}
<span>+</span>
</button>
<button class="site-nav__link btn--link site-nav__collapse" aria-expanded="true" aria-controls="Collapsible{{ forloop.index }}">
{{ link.title }}
<span>-</span>
</button>
<ul id="Collapsible{{ forloop.index }}" class="site-nav__submenu site-nav__submenu--expand" aria-hidden="false">
{% for childlink in menus[child_list_handle].links %}
<li class="{% if childlink.active or collection.current_type == childlink.title or collection.current_vendor == childlink.title %}{% unless forloop.first and childlink.title contains 'All' and current_tags.size > 0 %} site-nav--active {% endunless %}{% endif %}">
{{ childlink.title | escape }}
</li>
{% endfor %}
</ul>
</li>
{% else %}
<button class="site-nav__link btn--link site-nav__expand hidden" id="hideOnLargeScreen" aria-expanded="false" aria-controls="Collapsible{{ forloop.index }}">
{{ link.title }}
<span>+</span>
</button>
<button class="site-nav__link btn--link site-nav__collapse" id="hideOnLargeScreen" aria-expanded="true" aria-controls="Collapsible{{ forloop.index }}">
{{ link.title }}
<span>-</span>
</button>
<ul id="Collapsible{{ forloop.index }}" class="site-nav__submenu site-nav__submenu--expanded" id="hideOnLargeScreen" aria-hidden="false">
{% for childlink in menus[child_list_handle].links %}
<li class="{% if childlink.active or collection.current_type == childlink.title or collection.current_vendor == childlink.title %}{% unless forloop.first and childlink.title contains 'All' and current_tags.size > 0 %} site-nav--active {% endunless %}{% endif %}">
{{ childlink.title | escape }}
</li>
{% endfor %}
</ul>
{% endif %}
{% else %}
<li class="site-nav__element {% if link.active %}site-nav--active{% endif %}">
{% if link.title == 'Shop' %}
{{ link.title }}
{% else %}
{{ link.title }}
{% endif %}
</li>
{% endif %}
{% endfor %}
{% if shop.customer_accounts_enabled %}
{% if customer %}
<li>
{{ 'layout.customer.account' | t }}
</li>
<li>
{{ 'layout.customer.log_out' | t }}
</li>
{% else %}
<li>
{{ 'layout.customer.log_in' | t }}
</li>
<li>
{{ 'layout.customer.create_account' | t }}
</li>
{% endif %}
{% endif %}
</ul>
{% include 'custom.social-bar' %}
</div>
<hr class="medium-up--hide hr--small {% if template == 'index' %}{% if settings.home_section_1 == 'banner-image' or settings.home_section_1 == 'featured-products' %}hr--border-bottom{% endif %}{% endif %}">
</nav>
It's nothing that belongs to liquid or Shopify. You easily can do this with common solutions. For example you could use jQuery by putting something like this into your theme js file:
$( window ).resize(function() {
if ($(window).width() < 700 ) { // Size of "small"
$('.list--nav ul').addClass('site-nav__submenu--expanded').removeClass('site-nav__submenu--expand');
} else {
$('.list--nav ul').addClass('site-nav__submenu--expand').removeClass('site-nav__submenu--expanded');
}
});
But you also could put the css code of .site-nav__submenu--expand into a condition for large devices like:
#media (min-width:960px) {
.site-nav__submenu--expand {...}
}

Two (2) Column Blog Layout in HubSpot

I'm doing my best to learn Hubspot's HubL language and CSS but am stuck on creating a 2 column format for my blog (they only provide a 1 column format). I inserted their Blog Content module, then edited the "Listing Template" code to be more to my liking, as follows. In the blog settings page I set the number of posts per "listing page" to 10 but would like to make it wrap at 5.
I also applied this inline styling so that the first column takes up half the space, which is good, but can't figure out how to tell it to wrap posts 6-10 to another column. I am reading everything I can about how I can get this to work but nothing applies directly to my problem.
max-width: 50%; height: auto;
Caveat - I can edit the below and I can apply CSS styling but that's the extent of my knowledge. If I have to do something in Javascript, I can copy-paste into a file that applies to the site but that's about it.
<div class="blog-section">
<div class="blog-listing-wrapper cell-wrapper">
<div class="blog-section">
<div class="blog-listing-wrapper cell-wrapper">
{# simple_list_page indicates the "blog/all" page, which is a list of links to every blog post #}
<div class="post-listing{% if simple_list_page %}-simple{% endif %}">
{% if blog_author %}
<div class="hs-author-profile">
<h2 class="hs-author-name">{{ blog_author.display_name }}</h2>
{% if blog_author.avatar %} <div class="hs-author-avatar"> <img src="{{ blog_author.avatar }}" alt="{{ blog_author.display_name }}"> </div> {% endif %}
<div class="hs-author-bio">{{ blog_author.bio }}</div>
{% if blog_author.has_social_profiles %}
<div class="hs-author-social-section">
<span class="hs-author-social-label">Find me on:</span>
<div class="hs-author-social-links">
{% if blog_author.facebook %}
{% endif %}
{% if blog_author.linkedin %}
{% endif %}
{% if blog_author.twitter %}
{% endif %}
{% if blog_author.google_plus %}
{% endif %}
</div>
</div>
{% endif %}
</div>
<h3 class="hs-author-listing-header">Recent Posts</h3>
{% endif %}
{% for content in contents %}
<div class="post-item">
{% if not simple_list_page %}
{% if topic %}<h3>Posts about {{ page_meta.html_title|replace(' | ', '') }}</h3>{% endif %}
{% if content.topic_list %}
<p id="hubspot-topic_data"> >
{% for topic in content.topic_list %}
<a class="topic-link" href="{{ group.absolute_url }}/topic/{{ topic.slug }}">{{ topic.name }}</a>{% if not loop.last %},{% endif %}
{% endfor %}
</p>
{% endif %}
{{ content.publish_date_localized }}
<div class="post-header">
<h2>{{ content.name }}</h2>
</div>
<div class="post-body clearfix">
<!--post summary-->
{% if content.post_list_summary_featured_image %}
<div class="hs-featured-image-wrapper">
<a href="{{content.absolute_url}}" title="" class="hs-featured-image-link">
<img src="{{ content.post_list_summary_featured_image }}" class="hs-featured-image">
</a>
</div>
{% endif %}
{{ content.post_list_content|safe }}
{% if content_group.show_summary_in_listing %}
<a class="more-link" href="{{ content.absolute_url }}">Read More</a>
{% endif %}
</div>
{% else %}
<h2 class="post-listing-simple">{{ content.name }}</h2>
{% endif %}
</div>
{% endfor %}
</div>
{% if not simple_list_page %}
<div class="blog-pagination">
{% if last_page_num %}
<a class="previous-posts-link" href="{{ blog_page_link(last_page_num) }}">Previous</a>
{% endif %}
<a class="all-posts-link" href="{{ group.absolute_url }}/all">All posts</a>
{% if next_page_num %}
<a class="next-posts-link" href="{{ blog_page_link(next_page_num) }}">Next</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
</div>
You could reverse the loop and use modulus to split the posts into 2 columns
change your opening loop to:
<div class="span5">{% for content in contents|reverse %}
and then change the closing of the loop to:
{% if loop.index % 5 == 0 %}
</div><div class="span5">
{% endif %}
{% endfor %}
</div> <!-- close the span5 we opened -->
</div> <!-- close the parent loop container -->

How to display multi level menubar in djangoCMS

{% load i18n menu_tags cache %}
{% for child in children %}
<li class="{% if child.ancestor %}ancestor{% endif %}
{% if child.selected %} active{% endif %}
{% if child.chil`enter code here`dren %} dropdown{% endif %}">
{% if child.children %}
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
{{ child.get_menu_title }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
</ul>
{% else %}
<span>{{ child.get_menu_title }}</span>
{% endif %}
</li>
{% if class and forloop.last and not forloop.parentloop %}{% endif %}
{% endfor %}
This is code of menu.html in djagocms project.
Could anyone help to me, how we can display multi level menubar in djangocms. like:
----------
> main menu
> --sub menu
> --sub menu
> ----sub menu
> ----sub menu
I've got a multilevel menu which I include in my base template like so;
<ul class="dropdown">
{% show_menu 1 100 100 100 "partials/navigation.html" %}
</ul>
That custom template looks like this;
{% load cms_tags menu_tags cache cms_page %}
{% for child in children %}
<li>
{{ child.get_menu_title }}
{% if child.children and child.level <= 4 %}
<ul>
{% show_menu from_level to_level extra_inactive extra_active template '' '' child %}
</ul>
{% endif %}
</li>
{% endfor %}
This renders out a multilevel menu which shows all children of a page as a new list.

Divide a long list into columns with Twig

I'm still pretty new to Twig.
I'm trying to build a dropdown menu for a website. I have multiple items which need to be divided into columns. I know this question is asked a million times but I can't figure out how to do this with Twig. I want one large list divided in multiple ul's of 14 items.
So lets say I have this:
<ul class="menu">
{% for category in shop.categories %}
<li class="item">
{{ category.title }}
{% if category.subs %}
<ul class="subnav">
{% for category in category.subs %}
<li></li> //can be up to 40 items
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
I can't use CSS3 columns since every list varies in length. So far as I know you can't tell in CSS that you want 14 items per list???
I tried this solution like so:
{% for category in shop.categories %}
<li class="item">
{{ category.title }}
{% if category.subs | length %}
{% set categoriesPerColumn = (category.subs | length // 3) + 1 %}
<ul class="subnav">
{% for category in category.subs %}
{% if loop.index % categoriesPerColumn == 1 %}
<li class="col-md-4">
<ul>
{% endif %}
<li>{{ category.title }}</li>
{% if loop.index % categoriesPerColumn == 0 or loop.last %}
</ul>
</li>
{% endif %}
{% endfor %}
I'm ending up with a submenu divided into 3 columns. What I try to achieve is to divide to whole list into columns of 14 items. Depending on how long the list is will result in different amounts of columns. So I don't want to set an amount of columns.
What I'm I doing wrong? Or how can I achieve my question?
I've read about Twig's batch function but that don't give me the desired result.
UPDATE1
I added a div column just to show what I try to achieve. I know this isn't correct, but just to show!!
<ul class="nav">
{% for category in shop.categories %}
<li class="item{% if loop.last and theme.hide_brands_button %} last{% endif %}">
<a class="itemLink" href="{{ category.url | url }}" title="{{ category.title }}">{{ category.title }}</a>
{% if category.subs | length %}
<ul class="subnav">
{% for batch in category.subs | batch(14) %}
<div class="column">
{% for category in category.subs %}
<li><a class="subitemLink" href="{{ category.url | url }}" title="{{ category.title }}">{{ category.title }}</a></li>
{% endfor %}
</div>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
This give me a result like:
<ul class="subnav">
<div class="column">
<li></li>
//complete list
</div>
<div class="column">
<li></li>
//complete list
</div>
<div class="column">
<li></li>
//complete list
</div>
<div class="column">
<li></li>
//complete list
</div>
</ul>
Can anybody help me with this? If this can't be done is there a neat jQuery solutions?
I assume category.subs is a two-dimensional array and if that is the case, you need to make one more loop:
<ul class="menu">
{% for category in shop.categories %}
<li class="item">
{{ category.title }}
{% if category.subs | length %}
{% for batch in category.subs|batch(14) %}
<ul class="subnav">
{% for category in batch %}
<li>{{ category.title }}</li>
{% endfor %}
</ul>
{% endfor %}
{% endif %}
</li>
{% endfor %}
</ul>

Resources