I'm trying to have two separate menus in my django-cms app. One for the header and another with a different set of links for the footer:
[ Logo ] Link_A Link_B Link_C Link_D
... content ...
Link_E Link_F Link_G Link_H
Using baked in {% show_menu %}, will show all of the pages registered, links A - H, and doesn't allow me to separate the two menus.
How can I create two separate menus?
Depends what you want to do really, but I've got a base template which has a navigation menu at the top and a sitemap submenu at the bottom.
So starting with the navigation;
{% show_menu 1 100 100 100 "partials/navigation.html" %}
Which uses the template;
{% load cms_tags menu_tags cache cms_page %}
{% for child in children %}
<li>
<a href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">
{{ child.get_menu_title }}
</a>
{% if child.children and child.level <= 4 %}
<ul>
{% show_menu from_level to_level extra_inactive extra_active template '' '' child %}
</ul>
{% endif %}
</li>
{% endfor %}
Then the sitemap;
{% show_sub_menu 2 1 1 "partials/sitemap.html" %}
And sitemap.html
{% load cms_tags cms_page cache %}
{% if children %}
{% for child in children %}
<ul class="site-footer__column">
<li>
<h4>
<a href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">
{{ child.get_menu_title }}
</a>
</h4>
</li>
{% if child.children %}
{% for baby in child.children %}
<li class="footer_sub">
<a href="{{ baby.attr.redirect_url|default:baby.get_absolute_url }}">
{{ baby.get_menu_title }}
</a>
</li>
{% endfor %}
{% endif %}
</ul>
{% endfor %}
{% endif %}
Understanding the options (numbers) you can provide for a menu can enable you to display different parts of your site, but if the built in menu tags don't suit your needs, you could write a custom menu tag.
The standard menu docs are here; http://docs.django-cms.org/en/3.2.2/reference/navigation.html
And here are the docs for customising your menus; http://docs.django-cms.org/en/3.2.2/how_to/menus.html
Related
In my Django project I use django-mptt application to create hierarchical tree. Right now next code works well but I want to show only first 4 level of the tree. How to make it correctly? I am confused.
views.py:
context['caregories'] = Category.objects.get(id=5).get_descendants()
html:
{% load mptt_tags %}
<ul>
{% recursetree caregories %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
You can filter the descendants by their level
obj = Category.objects.get(id=5)
context['caregories'] = obj.get_descendants().filter(level__lte=obj.level + max_depth)
where max_depth is the depth you require
I am currently working on the navbar of a project with Django-cms. I am fairly new to this framework and language, so sorry if this is a stupid question.
This has double dropdowns, which respond to user changes in the Django-cms admin interface.
Which works. Sort of.
The problem is that get_children doesn't work (no errors or something, just not detecting children, and showing the 'should be dropdown button' as a non dropdown version), but get_descendants does. But if i use that the content of the second dropdown will be shown again in the first dropdown. So get_children will be perfect, as it will only show the direct descendants, instead of all.
{% load cms_tags menu_tags sekizai_tags staticfiles%}
{% load menu_tags %}
{% for child in children %}
<!--non dropdown 1-->
{% if child.is_leaf_node %}
<li>{{child.get_menu_title }}</li>
{% endif %}
<!--dropdown 1-->
{% if not child.is_leaf_node or child.ancestor %}
<div class="dropdown">
<li>{{child.get_menu_title }}<b class="caret"></b></li>
<!-- dropdown 1 content-->
{% if child.get_descendants %}
<div class="dropdown-content">
{% for kid in child.get_descendants %}
<!--non dropdown 2-->
{% if kid.is_leaf_node %}
<li>{{kid.get_menu_title }}</li>
{% endif %}
<!--dropdown 2 -->
{% if not child.is_leaf_node or child.ancestor %}
<li>
<a class="menu-has-sub">{{kid.get_menu_title }}<i class="fa fa-angle-down"></i></a>
<!-- dropdown 2 content-->
<ul class="sub-dropdown droppeddown">
{% for baby in kid.get_descendants %}
<li>{{baby.get_menu_title }}</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
{% endfor %}
So my question is: Why can't i use children
EDIT: *Why can't i use get_children. As in the function. No child labour here.
Nvm i fixed it! The syntax in this case should be children instead of get_children. which is funny because of that edit above.
Anyway, here's an example:
This doesn't work:
{% for kid in child.get_children %}
This does work:
{% for kid in child.children%}
hopefully this will help anyone else having this little struggle.
I am wondering how to create a jinja2 template that would allow my to put my header into a variable where I can extend the base file and then call upon the header in my child file.
Currently my code for the parent is:
{% block head %}
<div class="wrapper col2">
<div id="topbar">
<div id="topnav">
<ul>
<ul>
<li>Home</li>
<li>Sign in/up</li>
<li>Admin console
<ul>
<li>Console</li>
<li>Staff Management</li>
<li>ALERTS</li>
<li>Sign up Shooters</li>
</ul>
</li>
<li >Contact Us</li>
<li class="last">logout</li>
</ul>
</div>
<br class="clear" />
</div>
<hr>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }} </li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</div>
{% endblock %}
My child template is:
{% extends "Header.html" %}
{% block head %}
{% endblock %}
<h1>CREATE SHOOT</h1>
<form action="" method="post" name="form">
{{ form.hidden_tag() }}
<p>
<h2>Name of shoot:</h2>
{{ form.nameofshoot(size=40) }}<br>
<h2>Number of days in shoot:</h2>
{{ form.day}}
<p><input type="submit" value="Create Shoot"></p>
</form>
Am I doing something wrong or is there another approach I can take?
What you need to do is remove from your child template the lines {% block head %}{% endblock %}
Because in your child template you call {% extends "Header.html" %}, all of the content declared in Header.html (no matter what blocks it is in) will automatically be included. That's the job of extends.
By adding the {% block head %}{% endblock %} in your child template, what you have effectively said is "take everything from Header.html, but override everything in the 'head' block with what I specify in my child template". Then, because there is nothing in the block defined in your child template, you are replacing the content defined in your Header.html file with nothing.
You want to use the {% block blockname %} notation to specify what you want to change in the child template, not what you want to keep the same.
This page on inheritence is the relevant section of the Jinja documentation, and provides a nice example.
I am not sure if someone had this issue before:
I have these pages in django cms's admin.
these are the pages I created using django cms and languages come from LANGUAGES from settings.py
and I used {% language_chooser %}, it dislays all languages which are defined in LANGUAGES.
What I want is: if I am in home, in language_chooser only those languages should show up for which there is a page created. in this case, only english, german, and espaniol
how can I achieve this? any guidance is appreciated
SOLVED, BUT..
I ended up using this inside language_chooser.html
{% load i18n menu_tags %}
{% get_available_languages as languages %}
{% if languages|length > 1 %}
{% for language in languages %}
{% if language.1 in current_page.get_languages %}
<li class="lang{% ifequal current_language language.0 %} active{% endifequal %}">
<a href="{% page_language_url language.0 %}"
title="{% trans "Change to language:" %} {{ language.1 }}">{{ language.0 }}</a>
</li>
{% endif %}
{% endfor %}
{% endif %}
But this is showing up only in home page, not in other pages, any ideas? BTW, Other pages are AppHooks
I just ended up doing this:
{% if languages|length > 1 %}
{% for language in languages %}
<li class="lang{% ifequal current_language language.0 %} active{% endifequal %}">
<a href="/./{{ language.0 }}/"
title="{% trans "Change to language:" %} {{ language.1 }}">{{ language.0 }}</a>
</li>
{% endfor %}
{% endif %}
meaning.. just redirect the user to main page if they change the language.
<a href="/./{{ language.0 }}/" ..
and make sure to define in settings.py only those languages that your site has translations for..
I'm totally confused by django-cms's show_menu tag. There are four parameters but no full document on these parameters could be found. There are only several exmaples however I cannot find how to show menu under current page only.
Pages are arranged like this:
--Projects
----proj1
----proj2
--Gallery
----gal1
----gal2
In Projects template, how do I set the parameters for show_menu to show only the menu under current page?
Update
#Brandon
I tried exactly this:
{% show_sub_menu 1 "menu/cust_menu.html" %}
As exactly what the document says. However it ends up in this error:
u'menu/cust_menu.html' could not be converted to Integer
You need to use:
{% show_sub_menu 1 %}
http://django-cms.readthedocs.org/en/2.1.3/advanced/templatetags.html#show-sub-menu
There is actually an error in documentation and it seems to be also a little bug introduced in one of the last versions of django cms (planned to be solved in django-cms 3.0 version!).
https://github.com/divio/django-cms/issues/1913
I solved using this:
{% show_menu_below_id "topics_page" 0 4 100 100 "./_menus/menu_topics.html" %}
where "topics_page" is the reverse id (you configure it in advanced section in cms admin).
For recursive rendering of menu, just configure the custom id of subpages for which you want display the next menu level;
in your custom menu template, you can play with child properties and the for loop counter. Below, check a nasty example but still useful if you want to customize your menu template:
{% load menu_tags %}
{% load template_extras %}
{% for child in children %}
{# sub voices topics #}
{% if child.level == 1 %}
{% if not forloop.counter|divisibleby:2 %}
<div class="row-fluid">
{% endif %}
<div class="span6">
<div class="sub1">
<a href="{{ child.attr.redirect_url|default:child.get_absolute_url }}"><span
class="icon-play"></span>{{ child.get_menu_title|capfirst }}</a>
</div>
{% if child.children %}
{% show_menu_below_id child.attr.reverse_id 0 4 100 100 template %}
{% endif %}
</div>
{% if forloop.counter|divisibleby:2 %}
</div> <!-- end row fluid -->
{% endif %}
{% elif child.level == 2 %}
{# 2 - {{ child.attr.reverse_id}} - {{ child.get_menu_title }}#}
<div class="row-fluid">
<div class="span11 offset1">
<div class="sub2">
<a href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">{{ child.get_menu_title|capfirst }}
</a></div>
</div>
</div>
{% if child.children %}
{% show_menu_below_id child.attr.reverse_id 0 4 100 100 template %}
{% endif %}
{% elif child.level == 3 %}
{# leaf node topics #}
{# 3 - {{ child.attr.reverse_id}} - {{ child.get_menu_title }}#}
<div class="row-fluid">
<div class="span10 offset2">
<div class="sub3"><a href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">
<i class="icon-list-alt"></i> {{ child.get_menu_title|capfirst }}</a></div>
</div>
</div>
{% endif %}
{% endfor %}