Pagination on results doesn't work 'afte the first page' other papes repeats the first - django

I have an issue with pagination in Django search.html page. After search result, the results on first page of the table is repeated on the next pages continously.
For reference, this is the bit of the template that displays results:
{% for result in page_obj.object_list %}
<p>
{{ result.object.title }}
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% if page_obj.has_previous or page_obj.has_next %}
<div>
{% if page_obj.has_previous %}{% endif %}« Previous{% if page_obj.has_previous %}{% endif %}
|
{% if page_obj.has_next %}{% endif %}Next »{% if page_obj.has_next %}{% endif %}
</div>
{% endif %}

Related

Unable to add different block tag to my template

I am trying to add different block tags inside a for loop but it raise an error
Did you forget to register or load this tag?
But I register it
{% for todo in todo_list %}
{% if todo.complete %}{% else %}
{{todo.text|capfirst|truncatechars:150}} </a> <br>
<small class="text-muted">{{todo.content|capfirst}}{% empty %} {% endif %} </small> <hr>
{% endif %} {% endfor %}
Thanks
Looking into your problem, I think you need to try this:
{% for todo in todo_list %}
{% if todo.complete %}
{% else %}
{{todo.text|capfirst|truncatechars:150}} </a> <br>
{% if todo.content %}
<small class="text-muted">{{todo.content|capfirst}} </small> <hr>
{% else %}
//do something
{% endif %}
{% endif %}
{% endfor %}

How to use django paginator page range for displaying the first 10 numbers not all?

I want to change the blow script to show just the first 10 page numbers. Now it shows all page numbers. Could you please tell me how to change it? I tried several ways but it didn't work. Any help will be appreciated!
{% if forloop.counter|divisibleby:"3" or forloop.last %}
</div>
{% endif %}
{% endfor %}
{% if is_paginated %}
<div class="row">
<ul class="pagination pagination-md ">
{% if page_obj.has_previous %}
<li>«</li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }}</span></li>
{% else %}
<li><a href="?page={{ i }}{% if currentCategory %}&category={{ currentCategory }}
{% endif %}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
</div>
{% endif %}
</div>

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 cycle across 2 forloops within a django template

I have a django template where I need to cycle through a set of background colours across two different for loops. The cycle tag seems to be designed to be used either within one for loop or outside a for loop altogether. This is my code:
{% if global_adverts %}
<span style="display:none">{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolors %}</span>
{% for advert in global_adverts %}
<div class="{% cycle adcolors %}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% endfor %}
{% endif %}
{% with self.adverts.all as adverts %}
{% if adverts %}
{% for advert in adverts %}
<div class="{% cycle adcolors %}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% endfor %}
{% endif %}
{% endwith %}
Is there a way to do this without outputting the first item in the cycle before the first loop and having to hide it with css?
Just add silent
{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolors silent %}
It prevents the tag from outputting the value
EDIT AFTER COMMENT
If you need the cycle to continue for each loop just use cycle twice and change the order of the items in the second cycle:
{% if global_adverts %}
{% for advert in global_adverts %}
<div class="{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' %}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% endfor %}
{% endif %}
{% with self.adverts.all as adverts %}
{% if adverts %}
{% for advert in adverts %}
<div class="{% cycle 'advert-pale-blue' 'advert-green' 'advert-blue' 'advert-grey' %}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% endfor %}
{% endif %}
{% endwith %}
I have discovered that the following code gives the desired result:
{% if global_adverts %}
{% for advert in global_adverts %}
<div class="{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolours %}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% endfor %}
{% endif %}
{% with self.adverts.all as adverts %}
{% if adverts %}
{% for advert in adverts %}
<div class="{% cycle adcolours %}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% endfor %}
{% endif %}
{% endwith %}
I feel that having the first {% cycle %} declaration outside of the loops is cleaner, I wouldn't have expected a declaration inside of conditional loops to work, and here's how to make it work:
{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolour silent %}
{% if global_adverts %}
{% for advert in global_adverts %}
<div class="{{ adcolours }}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% cycle adcolours %}
{% endfor %}
{% endif %}
{% with self.adverts.all as adverts %}
{% if adverts %}
{% for advert in adverts %}
<div class="{{ adcolours }}">
{% if advert.url %}<a href="{{ advert.url }}">{% endif %}
<p>{{ advert.text }}</p>
{% if advert.url %}</a>{% endif %}
</div>
{% cycle adcolour %}
{% endfor %}
{% endif %}
{% endwith %}
Since {% cycle adcolour %} is silent, we use {{ adcolour }} to print the current colour. We still need to use the silent {% cycle adcolour %} to step through the colours on each iteration.

How do you access the menu model from a Zotonic template?

I want to write my own style of menu, but I would prefer to do it in the templates rather than making my own menu scomp.
I basically want to be able to do something like:
{% if m.menu %}
<ul>
{% for top_level_id in m.menu %}
{% with m.rsc[top_level_id] as top_level %}
<li>{{ top_level.title }}
{% if top_level.menu %}
<ul>
{% for mid_level_id in top_level.menu %}
{% with m.rsc[mid_level_id] as mid_level %}
<li>{{ mid_level.title }}</li>
{% endwith %}
{% endfor %}
</ul>
{% endif %}
</li>
{% endwith %}
{% endfor %}
</ul>
{% endif %}
How do you access the menu model from a Zotonic template?
To add to my previous answer. The standard _menu.tpl receives a list with all menu items. This list is the result of a depth-first tree walk of the complete menu. Every menu is a record with
{MenuRscId, DepthOfMenu, NrInSubMenu, HasSubMenuFlag}
Where the top level menu has a depth of 1 and the first menu item in a menu has a nr of 1.
All menu items that the current user is not allowed to see are filtered out.
The code of the default template:
<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>
The (upcoming) 0.5-release and tip of Zotonic use a template to display the menu. Check mod_menu/templates/_menu.tpl.
This template is called by the menu scomp.