How to split a menu within a wagtail model? - django

I'm trying to create a navigation menu, that when the number of objects within the menu is even puts an image between the two halves of the menu. Here is the code that I tried to use within my menu model and templates to create the effect.
"""Splitting the menu in half for the frontend."""
#property
def is_even(self):
if (self.objects.count() % 2) == 0:
return True
else:
return False
#property
def find_halves(self):
first_half = self.objects[0:self.objects.count()/2]
second_half = self.objects[self.objects.count()/2:self.objects.count()]
return first_half, second_half
<nav class="main-nav">
{% image navigation.logo fill-115x115 as logo %}
<ul class="nav-links">
{% if navigation.is_even %}
{% for item in navigation.menu_items.first_half.all %}
<li><a href="{{ item.link }}" {% if item.open_in_new_tab %} target="_blank" {% endif %}>{{ item.title }}</a></li>
{% endfor %}
<img src="{{ logo.url }}" alt="CCCR Logo" class="logo">
{% for item in navigation.menu_items.second_half.all %}
<li><a href="{{ item.link }}" {% if item.open_in_new_tab %} target="_blank" {% endif %}>{{ item.title }}</a></li>
{% endfor %}
{% else %}
<img src="{{ logo.url }}" alt="CCCR Logo" class="logo">
{% for item in navigation.menu_items.all %}
<li><a href="{{ item.link }}" {% if item.open_in_new_tab %} target="_blank" {% endif %}>{{ item.title }}</a></li>
{% endfor %}
{% endif %}
</ul>
</nav>
However, when I run the code it goes to the else statement even though I have six menu items in the wagtail admin.

For an item like this that is related to what users see, I would suggest using the Django template tag divisibleby: https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#divisibleby
So maybe something like this:
{% if navigation.menu_items.count|divisibleby:"2" %}
You might also find the cycle template tag useful. It might let you do what you want layout-wise by alternating the placement of a class on odd and even items.

Related

Django simple pagination in detail view between items

I want to add simple back/next pagination in my item detail view.
How can I do that ?
I have something like that in my template:
{% if is_paginated %}
<div class="pagination">
<span class="page-links">
{% if page_obj.has_previous %}
Back
{% endif %}
{% if page_obj.has_next %}
Next: {{ item.title }}
{% endif %}
</span>
</div>
{% endif %}
The main thing is that I want to do this in ItemDetailView, not in ItemListView, because in list view I have all items, and I just want to go between items in detail view.
Thanks a lot for help.

how to add an image to webapp using Python flask

I need to develop a web app using python flask and I need to add an image to the view page. But I couldn't get it.please help me out of it.
In the example below the image is stored in an SQLite database. From there you can do something like:
#app.route('/show')
def show_pic():
filename = request.args.get('filename','')
t = (filename,)
cur = g.db.execute('select label from pics where filename=?', t)
label = cur.fetchone()[0]
return render_template('upload.html', filename=filename, label=label)
And then in your template:
{% macro pic_path(pic) %}
{{ url_for('return_pic', filename='%s' % pic) }}
{% endmacro %}
{% block content %}
{% if filename is defined %}
<div id="image">
<a href="{{ pic_path(filename) }}" target="_blank">
<img class="new" src="{{ pic_path(filename) }}">
</a>
</div>
{% else %}
<ul>
{% for pic in pics %}
<li class="thumb">
<a href="{{ url_for('show_pic', filename=pic.filename) }}">
<img class="thumb" src="{{ pic_path('thumb_'+pic.filename) }}">
</a>
<strong>{{ pic.label }}</strong>
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

Custom menu in Mezzanine

I have following mezzanine tree.html
{% if page_branch_in_menu %}
<ul class="nav nav-list navlist-menu-level-{{ branch_level }}">
{% for page in page_branch %}
{% if page.in_menu %}
{% if page.is_current_or_ascendant or not page.is_primary %}
<li class="
{% if page.is_current %} active{% endif %}
{% if page.is_current_or_ascendant %} active-branch{% endif %}
" id="tree-menu-{{ page.html_id }}">
{{ page.title }}
{% if page.has_children_in_menu %}{% page_menu page %}{% endif %}
</li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
{% endif %}
In the base.html I have following block:
<div class="col-md-2 left">
{% block left_panel %}
<div class="panel panel-default tree">{% page_menu "pages/menus/tree.html" %}</div>
{% endblock %}
</div>
The problem is that on some pages where the menu is empty the css styles are applied to the divs with empty menu lists and users can observe empty containers. In html it looks like:
<div class="col-md-2 left">
<div class="panel panel-default tree">
<ul class="nav nav-list navlist-menu-level-0"></ul>
</div>
</div>
I can hide the child ul with something like .nav:empty { display:none;} but the parent will still be visible. Here is the discussion about similar question: :empty selector for parent element
Is it possible to solve this problem with Mezzanine template tags?
{% if page_branch %} doesn't help because it's full of pages which are all not in_menu.
So better filter them before context.
menu_pages = page_branch.filter(in_menu=True)
Also you should put if block on top of div.tree
{% if menu_pages %}
<div class="panel panel-default tree">{% page_menu "pages/menus/tree.html" %}</div>
{% endif %}
Another way is to write custom filter
{% with menu_pages=page_branch|filter_in_menu %}
{% if menu_pages %}
...
{% endif %}
{% endif %}
But there is no way to apply extra filter to queryset with built-in syntax or Mezzanine tags.
You could wrap the code with an if tag.
{% if page_branch %}
<ul>
{% for page in page_branch %}
{% if page.in_menu %}
{% if page.is_current_or_ascendant or not page.is_primary %}
<li>
{% if not page.is_primary %}
{{ page.title }}
{% endif %}
{% page_menu page %}
</li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
{% endif %}

How to create a film strip in django using bootstrap and for loop?

How do I display a group of 6 thumbnails in my template to create a filmstrip. The list i am iterating through a for loop has around 30 items i want to break it into chunks of 6 and show it as a filmstrip slider. I tried using the range function for the for loop but that doesnt work
<div class="carousel-inner">
<div class="item active">
<ul class="thumbnails">
{% for show in object_list %}
<li class="span2">
<div class="thumbnail">
<a href="{{ show.get_absolute_url }}" data-title="{{ show.name }}" >
{% if show.images.exists %}
{% with show.images.all.0.image as show_image %}
<img src="{% thumbnail show_image 160x160 crop %}" alt="{{show.name}}" class="thumbnail">
{% endwith %}
{% else %}
<img src="{% static 'img/default-image.gif' %}" alt="{{show.name}}" class="thumbnail">
{% endif %}
</a>
</div>
</li>
{%endfor%}
</ul>
</div>
If you want 1 carousel per 6 images then you could do it like this
Step 1) Create a new .html file in your templates folder called film-slider.html.
{% for reel in reels %}
<div class="carousel-inner">
<div class="item active">
<ul class="thumbnails">
{% for show in reel %}
<li class="span2">
<div class="thumbnail">
<a href="{{ show.get_absolute_url }}" data-title="{{ show.name }}" >
{% if show.images.exists %}
{% with show.images.all.0.image as show_image %}
<img src="{% thumbnail show_image 160x160 crop %}" alt="{{ show.name }}" class="thumbnail">
{% endwith %}
{% else %}
<img src="{% static 'img/default-image.gif' %}" alt="{{ show.name }}" class="thumbnail">
{% endif %}
</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
Step 2) In your templatetags/tags.py (create it if you haven't)
from django import template
register = template.Library()
def filmslider(reel):
reels = []
for i in range(0, len(reel), 6):
reels.append(reel[i:i+6])
return {'reels':reels}
register.inclusion_tag('film-slider.html')(filmslider)
This will make an inclusion tag that's available in your templates once you've loaded it via {% load tags %}.
This will make this work for you like this {% filmslider object_list %} which you will replace all the above html code that you posted with.
I haven't tested this but it should work, if in the future you want to have more functionality to this tag you can simply add arguments to the tag definition, I'll give an example.
def filmslider(reel, slides):
#do the code.
which will lead you to {% filmslider object_list 9 %} and voila, now you can extend your film reel from 6 slides to 9.
Hope this helps a bit!

concise if statements in django templating system

Here is the monster inefficient code:
{% for link in header_links %}
{% if not link.image %}
{% if not link.url %}
<li>{{ link }}</li>
{% else %}
<li>{{ link }}</li>
{% endif %}
{% else %}
{% if not link.url %}
<li><img src="{{ link }}" /></li>
{% else %}
<li><img src="{{ link.image }}" /></li>
{% endif %}
{% endif%}
{% endfor %}
As you can see, this is ridiculous. A simple tertiary statement or two would be totally fitting, except within the {% %} blocks I can't access the variables with filters and things like that.
Here is my python/django pseduo code that expresses the same thing with the efficiency I think is possible.
{% for link in header_links %}
<li>{% print "<img src='" + link.image + "' />" if link.image else print link %}</li>
{% endfor %}
As you can see, using two tertiary statements would be awesome and much more visually efficient anyway. Yet this code doesn't work.
Any suggestions would be awesome!!
Thanks,
Django Noob
IN CLOSING:
We came to the conclusion that following the MVC paradigm leads me to do the "heavy" lifting to the controller section and give the view as little thinking as possible.
The pseudo code I will end up using will be as follows:
in the view
header_links = {}
links = Link.object.all()
for link in links:
header_links['url'] = (link.name if not link.url else link.url)
header_links['name'] = (link.name if not link.image else "<img src='" + link.image +"' />")
context = Context({
"header_links": header_links
})
in the controller
{% for link in header_links %}
<li><img src="{{ link['name'] }}" /></li>
{% endfor %}
Just rewrote your if statement and I think this way looks more obvious. Is not the most clever solution but It's more readable.
{% for link in header_links %}
{% if not link.image and not link.url%}
<li>{{ link }}</li>
{% endif %}
{% if not link.image and link.url%}
<li>{{ link }}</li>
{% endif %}
{% if link.image and not link.url%}
<li><img src="{{ link }}" /></li>
{% endif %}
{% if link.image and link.url%}
<li><img src="{{ link.image }}" /></li>
{% endif %}
{% endfor %}
How about this?
{% for link in header_links %}
<li>
{% if link.url and link.image %}
<img src="{{ link.image }}" />
{% elif not link.url %}
<img src="{{ link }}" />
{% elif not link.image %}
{{ link }}
{% else %}
{{ link }}
{% endif%}
</li>
{% endfor %}