Using autopagination in django and formatting issues - django

I'm using django-paginate and getting weird formatting issues with the {% paginate %} tag. I have attached an image of the problem.
I was just wondering what could be potentially causing this?
In the image below I'm on the first page. Notice that the 1 is cut off and also that the pages are strangely ordered and the previous/next is not really visible.
My template is just this for now:
{% extends "base.html" %}
{% load mptt_tags %}
{% load pagination_tags %}
{% load i18n %}
{% block body %}
{% autopaginate parts 20 %}
{% paginate %}

That's not related to Django, neither to Django-Paginate. It seems that you're using Bootstrap as your front-end framework, and that implies issues such that.
I've implemented a similar approach for this site manoomit.com, creating a custom template for managing pagination within django-paginate.
It looks like that:
{% if is_paginated %}
{% load i18n %}
<div class="pagination pagination-centered">
<ul>
{% if page_obj.has_previous %}
<li>‹‹ {% trans "previous" %}</li>
{% else %}
<li class="disabled">‹‹ {% trans "previous" %}</li>
{% endif %}
{% for page in pages %}
{% if page %}
{% ifequal page page_obj.number %}
<li class="active">{{ page }}</li>
{% else %}
<li>{{ page }}</li>
{% endifequal %}
{% else %}
...
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>{% trans "next" %} ››</li>
{% else %}
<li class="disabled">{% trans "next" %} ››</li>
{% endif %}
</ul>
</div>
{% endif %}

Related

'else', expected 'empty' or 'endfor'. Did you forget to register or load this tag?

{% if movies.has_other_pages %}
<ul class="pagination">
{% if movies.has_previous %}
<li class="pagination-item">
Previous
</li>
{% else %}
<li class="pagination-item">
<a>Previous</a>
</li>
{% endif %}
{% for i in movies.paginator.page_range %}
{% if movies.number == i %}
<li class="pagination-item current-page"><a>{{i}}</a></li>
{% else %}
<li class="pagination-item">{{i}}</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
I'm trying to use paginator in django but it seems like something is wrong but I can't seem to figure it out.

How do I implement a recursive and extensible Twig template?

I'm implementing a simple website menu, but this time I'm using Twig as my template language. The depth of the menu tree is one or greater. Here's my Twig code so far (sanitized and simplified):
{# file menu1.html.twig #}
<ul>
{% import _self as renderer %}
{% for item in menu.items %}
{{ renderer.renderItem(item) }}
{% endfor %}
</ul>
{% macro renderItem(item) %}
{% block itemtag %}
<li>
{% endblock %}
{{ item.name }}
{% if item.hasItems() %}
<ul>
{% import _self as renderer %}
{% for subitem in item.items %}
{{ renderer.renderItem(subitem) }}
{% endfor %}
</ul>
{% endif %}
</li>
{% endmacro %}
Now I need to override the "itemtag" element in another template:
{# file menu2.html.twig #}
{% extends "menu1.html.twig" %}
{% block itemtag %}
<li data-foo="bar">
{% endblock %}
This will not work, as explained very well here: https://stackoverflow.com/a/26650103/220817
So how do I write a Twig template that can traverse and render a tree structure, and still allow extending templates to override certain elements in the rendered markup?
You need to use macro's if you want to do something recursive as macro's can self import themself. Here is an example of a recursive macro:
{% macro menu(m, class, currentLevel, maxLevel) %}
{%if not class is defined %}
{% set class = '' %}
{% endif %}
{%if not currentLevel is defined or currentLevel is null %}
{% set currentLevel = 1 %}
{% endif %}
{%if m is iterable%}
{% set links = m %}
{% else %}
{% set links = m.getLinks() %}
{% if m.showRoot() and m.hasRoot() %}
<li class="root{%if class != ''%} {{class}}{%endif%}">
<a href="{%if m.getRoot().getTreeLeft() > 1 %}{{ m.getRoot().getRoute() }}{% else %}#site_url#{% endif %}" {% if m.getRoot().PageId in selected_page_ids %} class="selected"{% endif %}>{{ m.getRoot().name }}</a>
</li>
{% endif %}
{% if maxLevel is null %}{% set maxLevel = m.getLevel() %}{% endif %}
{% endif %}
{% if not links is empty %}
{% for link in links %}
{% if link['selected'] is defined and link['selected'] %}
{% set is_selected = true %}
{% else %}
{% set is_selected = false %}
{% endif %}
{% set anchor_class = '' %}
{% if link.PageId in selected_page_ids or is_selected %}
{% set anchor_class='selected' %}
{% endif %}
{% if method_exists(link, 'getPageCssClass') and link.getPageCssClass() != null %}
{% set class= class~' '~link.getPageCssClass().getTitle() %}
{% endif %}
<li{%if (class|trim) != '' %} class="{{ (class|trim) }}"{% endif %}>
<a href="{{ link.getRoute }}"{%if (anchor_class|trim) != '' %} class="{{ (anchor_class|trim) }}" {% endif %} {% if link.PageId > 0 %}data-page-id="{{ link.PageId }}"{% endif %}>{{ link.name }}</a>
{% if link.hasPublicChildren and currentLevel < maxLevel %}
<ul>
{{ _self.menu(link.getPublicChildren, 'sec', (currentLevel+1), maxLevel) }}
</ul>
{% endif %}
</li>
{% endfor %}
{% endif %}
{% endmacro %}

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 %}

Can I display last actions of everyone in the Django Admin index?

Is there a way to display every last actions made in the Django admin? By default the admin display only last actions of the current user but I would like to see last actions of every administrators. Since I don't have any code of this page in my project, how can I interact with this widget? Should I override the whole index?
I would like to get something like this:
instead of just the 2 first entries if I'm connected as er**** (according to the screen).
Yes, it is. Everything in the Django admin is customizable by overriding the template. All you need is to override the file templates/admin/index.html of your current Django version and change this line:
{% get_admin_log 10 as admin_log for_user user %}
and remove the for_user user part. It will display the 10 last recent actions, without filtering by user. To be perfect, you also need to change the name of the block and add action author. The sidebar block should be something like:
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% trans 'Recent Actions' %}</h2>
<h3>{% trans 'Last Actions' %}</h3> {# Title modified #}
{% load log %}
{% get_admin_log 10 as admin_log %} {# No more filtering #}
{% if not admin_log %}
<p>{% trans 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
{{ entry.object_repr }}
{% endif %}
<br/>
{% if entry.content_type %}
{# Add the author here, at the end #}
<span class="mini quiet">{% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %}, by {{ entry.user }}</span>
{% else %}
<span class="mini quiet">{% trans 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
This is very easy to override on django 1.9:
In your master urls.py where the admin interface is loaded (with admin.autodiscover()), overwrite the name of the admin index template file:
from django.contrib import admin
admin.site.index_template = 'admin/my_custom_index.html'
admin.autodiscover()
Then create the file admin\my_custom_index.html inside any application's template directory (eg. \my_app\templates\admin\my_custom_index.html). It can extend the existing template, so does not need to be that lengthy:
{% extends "admin/index.html" %}
{% load i18n static %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% trans 'Recent actions' %}</h2>
<h3>{% trans 'All users' %}</h3>
{% load log %}
{% get_admin_log 30 as admin_log %}
{% if not admin_log %}
<p>{% trans 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
{{ entry.object_repr }}
{% endif %}
<br/>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{{ entry.content_type }}{% endfilter %}, by {{ entry.user }}</span>
{% else %}
<span class="mini quiet">{% trans 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
The block has varied in django over the years, the version here is newer than that in Maximime's answer.

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.