page templates & views reordering

This commit is contained in:
bkfox 2020-09-22 00:51:00 +02:00
parent 5a17d034c4
commit ea17141321
13 changed files with 172 additions and 145 deletions

View File

@ -42,6 +42,7 @@ class SoundAdmin(admin.ModelAdmin):
'type', 'duration', 'is_public', 'is_good_quality',
'audio']
list_filter = ('type', 'is_good_quality', 'is_public')
list_editable = ['name', 'type', 'is_public']
search_fields = ['name', 'program__title']
fieldsets = [

View File

@ -218,25 +218,25 @@ class NavItem(models.Model):
page = models.ForeignKey(StaticPage, models.CASCADE,
verbose_name=_('page'), blank=True, null=True,
limit_choices_to={'attach_to__isnull': True})
#target_type = models.ForeignKey(
# ContentType, models.CASCADE, blank=True, null=True)
#target_id = models.PositiveSmallIntegerField(blank=True, null=True)
#target = GenericForeignKey('target_type', 'target_id')
class Meta:
verbose_name = _('Menu item')
verbose_name_plural = _('Menu items')
ordering = ('order', 'pk')
def get_url(self):
return self.url if self.url else \
self.page.get_absolute_url() if self.page else None
def render(self, request, css_class='', active_class=''):
if active_class and request.path.startswith(self.url):
url = self.get_url()
if active_class and request.path.startswith(url):
css_class += ' ' + active_class
if not self.url:
if not url:
return self.text
elif not css_class:
return format_html('<a href="{}">{}</a>', self.url, self.text)
return format_html('<a href="{}">{}</a>', url, self.text)
else:
return format_html('<a href="{}" class="{}">{}</a>', self.url,
return format_html('<a href="{}" class="{}">{}</a>', url,
css_class, self.text)

View File

@ -10,21 +10,6 @@ Usefull context:
- sidebar_object_list: item to display in sidebar
- sidebar_url_name: url name sidebar item complete list
- sidebar_url_parent: parent page for sidebar items complete list
Blocks:
- assets
- head_title
- head_extra
- top_nav
- header:
- title
- subtitle
- header_meta
- main:
- filters
- cover
- sidebar:
- sidebar_title
{% endcomment %}
{% load static i18n thumbnail aircox %}
@ -112,6 +97,7 @@ Blocks:
{% endif %}
{% endblock %}
{# TODO: change block name #}
{% if has_filters %}
{% comment %}Translators: extra toolbar displayed on the top of page lists {% endcomment %}
<nav class="navbar toolbar"

View File

@ -1,8 +1,5 @@
{% extends "aircox/base.html" %}
{% comment %}
This template is only used in order to have correct page <title></title>,
otherwise use base.html
{% endcomment %}
{% comment %}Display detail of a BasePage{% endcomment %}
{% block head_title %}
{% block title %}{{ page.title }}{% endblock %}

View File

@ -0,0 +1,85 @@
{% extends "aircox/base.html" %}
{% comment %}Display a list of BasePages{% endcomment %}
{% load i18n aircox %}
{% block head_title %}
{% block title %}
{% if not page or not page.title %}
{% if not parent %}{{ view.model|verbose_name:True|title }}
{% else %}
{% with parent.title as title %}
{% with model|default:"Publications"|verbose_name:True|capfirst as model %}
{% comment %}Translators: title when pages are filtered for a specific parent page, e.g.: Articles of My Incredible Show{% endcomment %}
{% blocktrans %}{{ model }} of {{ title }}{% endblocktrans %}
{% endwith %}
{% endwith %}
{% endif %}
{% else %}{{ block.super }}
{% endif %}
{% endblock %}
&mdash;
{{ station.name }}
{% endblock %}
{% block main %}{{ block.super }}
<section role="list">
{% block pages_list %}
{% with has_headline=True %}
{% for object in object_list %}
{% block list_object %}
{% include object.item_template_name|default:item_template_name %}
{% endblock %}
{% empty %}
{% blocktrans %}There is nothing published here...{% endblocktrans %}
{% endfor %}
{% endwith %}
{% endblock %}
</section>
{% if is_paginated %}
<hr/>
{% update_query request.GET.copy page=None as GET %}
{% with GET.urlencode as GET %}
<nav class="pagination is-centered" role="pagination" aria-label="{% trans "pagination" %}">
{% block pagination %}
{% if page_obj.has_previous %}
<a href="?{{ GET }}&page={{ page_obj.previous_page_number }}" class="pagination-previous">
{% else %}
<a class="pagination-previous" disabled>
{% endif %}
{% comment %}Translators: Bottom of the list, "previous page"{% endcomment %}
{% trans "Previous" %}</a>
{% if page_obj.has_next %}
<a href="?{{ GET }}&page={{ page_obj.next_page_number }}" class="pagination-next">
{% else %}
<a class="pagination-next" disabled>
{% endif %}
{% comment %}Translators: Bottom of the list, "Nextpage"{% endcomment %}
{% trans "Next" %}</a>
<ul class="pagination-list">
{% for i in paginator.page_range %}
<li>
{% comment %}
<form action="?{{ GET }}">
{% for get in GET %}
<input type="hidden" name="{{ get.0 }}" value="{{ get.1 }}" />
{% endfor %}
<input type="number" name="page" value="{{ page_obj.number }}" />
</form>
{% endcomment %}
<a class="pagination-link {% if page_obj.number == i %}is-current{% endif %}"
href="?{{ GET }}&page={{ i }}">{{ i }}</a>
</li>
{% endfor %}
</ul>
{% endblock %}
</nav>
{% endwith %}
{% endif %}
{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "aircox/page.html" %}
{% extends "aircox/page_list.html" %}
{% comment %}List of diffusions as a timetable{% endcomment %}
{% load i18n aircox humanize %}
@ -20,7 +20,7 @@
{% endwith %}
{% endblock %}
{% block main %}{{ block.super }}
{% block pages_list %}
{% with hide_schedule=True %}
<section role="list">
<div id="timetable-{{ date|date:"Y-m-d" }}">
@ -41,11 +41,5 @@
</div>
</section>
{% endwith %}
{% comment %}
<nav class="column menu is-one-third-desktop" role="menu">
</nav>
{% endcomment %}
{% endblock %}

View File

@ -1,4 +1,5 @@
{% extends "aircox/page_list.html" %}
{% comment %}Home page{% endcomment %}
{% load i18n %}
{% block head_title %}{{ station.name }}{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends "aircox/page.html" %}
{% extends "aircox/page_list.html" %}
{% comment %}List of logs for a specific date{% endcomment %}
{% load i18n humanize aircox %}
@ -21,7 +21,7 @@
{% endwith %}
{% endblock %}
{% block main %}{{ block.super }}
{% block pages_list %}
<section>
{# <h4 class="subtitle size-4">{{ date }}</h4> #}
{% include "aircox/widgets/log_list.html" %}

View File

@ -1,10 +1,9 @@
{% extends "aircox/page.html" %}
{% extends "aircox/basepage.html" %}
{% load static i18n humanize honeypot %}
{% comment %}
Base template used to display a page
Base template used to display a Page
Context:
- title: title
- page: page
{% endcomment %}

View File

@ -1,22 +1,7 @@
{% extends "aircox/page.html" %}
{% comment %}Display a list of pages{% endcomment %}
{% extends "aircox/basepage_list.html" %}
{% comment %}Display a list of Pages{% endcomment %}
{% load i18n aircox %}
{% block title %}
{% if not page or not page.title %}
{% if not parent %}{{ view.model|verbose_name:True|title }}
{% else %}
{% with parent.title as title %}
{% with model|default:"Publications"|verbose_name:True|capfirst as model %}
{% comment %}Translators: title when pages are filtered for a specific parent page, e.g.: Articles of My Incredible Show{% endcomment %}
{% blocktrans %}{{ model }} of {{ title }}{% endblocktrans %}
{% endwith %}
{% endwith %}
{% endif %}
{% else %}{{ block.super }}
{% endif %}
{% endblock %}
{% block filters %}
{# FIXME #}
{% if filter_categories %}
@ -63,56 +48,3 @@
{% endblock %}
{% block main %}{{ block.super }}
<section role="list">
{% block pages_list %}
{% with has_headline=True %}
{% for object in object_list %}
{% block list_object %}
{% include object.item_template_name|default:item_template_name %}
{% endblock %}
{% empty %}
{% blocktrans %}There is nothing published here...{% endblocktrans %}
{% endfor %}
{% endwith %}
{% endblock %}
</section>
{% if is_paginated %}
<hr/>
{% update_query request.GET.copy page=None as GET %}
{% with GET.urlencode as GET %}
<nav class="pagination is-centered" role="pagination" aria-label="{% trans "pagination" %}">
{% block pagination %}
{% if page_obj.has_previous %}
<a href="?{{ GET }}&page={{ page_obj.previous_page_number }}" class="pagination-previous">
{% else %}
<a class="pagination-previous" disabled>
{% endif %}
{% comment %}Translators: Bottom of the list, "previous page"{% endcomment %}
{% trans "Previous" %}</a>
{% if page_obj.has_next %}
<a href="?{{ GET }}&page={{ page_obj.next_page_number }}" class="pagination-next">
{% else %}
<a class="pagination-next" disabled>
{% endif %}
{% comment %}Translators: Bottom of the list, "Nextpage"{% endcomment %}
{% trans "Next" %}</a>
<ul class="pagination-list">
{% for i in paginator.page_range %}
<li>
<a class="pagination-link {% if page_obj.number == i %}is-current{% endif %}"
href="?{{ GET }}&page={{ i }}">{{ i }}</a>
</li>
{% endfor %}
</ul>
{% endblock %}
</nav>
{% endwith %}
{% endif %}
{% endblock %}

View File

@ -60,13 +60,13 @@ urls = [
path(_('publications/'),
views.PageListView.as_view(model=models.Page), name='page-list'),
path(_('pages/'), views.PageListView.as_view(
path(_('pages/'), views.BasePageListView.as_view(
model=models.StaticPage,
queryset=models.StaticPage.objects.filter(attach_to__isnull=True),
),
name='static-page-list'
),
path(_('pages/<slug:slug>/'), views.PageDetailView.as_view(
path(_('pages/<slug:slug>/'), views.BasePageDetailView.as_view(
model=models.StaticPage,
queryset=models.StaticPage.objects.filter(attach_to__isnull=True),
),

View File

@ -6,7 +6,7 @@ from .home import HomeView
from .article import ArticleDetailView, ArticleListView
from .episode import EpisodeDetailView, EpisodeListView, DiffusionListView
from .log import LogListView, LogListAPIView
from .page import PageDetailView, PageListView
from .page import BasePageListView, BasePageDetailView, PageListView, PageDetailView
from .program import ProgramDetailView, ProgramListView, \
ProgramPageDetailView, ProgramPageListView

View File

@ -12,62 +12,47 @@ from .base import BaseView
from .mixins import AttachedToMixin, ParentMixin
__all__ = ['PageDetailView', 'PageListView']
__all__ = ['BasePageListView', 'BasePageDetailView', 'PageDetailView', 'PageListView']
class PageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
template_name = 'aircox/page_list.html'
class BasePageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
""" Base view class for BasePage list. """
template_name = 'aircox/basepage_list.html'
item_template_name = 'aircox/widgets/page_item.html'
has_sidebar = True
has_filters = True
paginate_by = 20
paginate_by = 2
has_headline = True
categories = None
def get(self, *args, **kwargs):
self.categories = set(self.request.GET.getlist('categories'))
return super().get(*args, **kwargs)
def get_queryset(self):
qs = super().get_queryset().select_subclasses().published() \
.select_related('cover', 'category')
# category can be filtered based on request.GET['categories']
# (by id)
if self.categories:
qs = qs.filter(category__slug__in=self.categories)
return qs.order_by('-pub_date')
def get_categories_queryset(self):
# TODO: use generic reverse field lookup
categories = self.model.objects.published() \
.filter(category__isnull=False) \
.values_list('category', flat=True)
return Category.objects.filter(id__in=categories)
return super().get_queryset().select_subclasses().published() \
.select_related('cover')
def get_context_data(self, **kwargs):
kwargs.setdefault('item_template_name', self.item_template_name)
kwargs.setdefault('filter_categories', self.get_categories_queryset())
kwargs.setdefault('categories', self.categories)
kwargs.setdefault('has_headline', self.has_headline)
return super().get_context_data(**kwargs)
class PageDetailView(BaseView, DetailView):
""" Base view class for pages. """
class BasePageDetailView(BaseView, DetailView):
""" Base view class for BasePage. """
template_name = 'aircox/basepage_detail.html'
context_object_name = 'page'
has_filters = False
def get_queryset(self):
return super().get_queryset().select_related('cover', 'category')
return super().get_queryset().select_related('cover')
# This should not exists: it allows mapping not published pages
# or it should be only used for trashed pages.
def not_published_redirect(self, page):
"""
When a page is not published, redirect to the returned url instead
of an HTTP 404 code. """
When a page is not published, redirect to the returned url instead of an
HTTP 404 code.
"""
return None
def get_object(self):
@ -85,6 +70,55 @@ class PageDetailView(BaseView, DetailView):
def get_page(self):
return self.object
class PageListView(BasePageListView):
""" Page list view. """
template_name = None
has_filters = True
categories = None
def get(self, *args, **kwargs):
self.categories = set(self.request.GET.getlist('categories'))
return super().get(*args, **kwargs)
def get_template_names(self):
return super().get_template_names() + ['aircox/page_list.html']
def get_queryset(self):
qs = super().get_queryset().select_related('category') \
.order_by('-pub_date')
# category can be filtered based on request.GET['categories']
# (by id)
if self.categories:
qs = qs.filter(category__slug__in=self.categories)
return qs
def get_categories_queryset(self):
# TODO: use generic reverse field lookup
categories = self.model.objects.published() \
.filter(category__isnull=False) \
.values_list('category', flat=True)
return Category.objects.filter(id__in=categories)
def get_context_data(self, **kwargs):
kwargs.setdefault('filter_categories', self.get_categories_queryset())
kwargs.setdefault('categories', self.categories)
return super().get_context_data(**kwargs)
class PageDetailView(BaseView, DetailView):
""" Base view class for pages. """
template_name = None
context_object_name = 'page'
has_filters = False
def get_template_names(self):
return super().get_template_names() + ['aircox/page_detail.html']
def get_queryset(self):
return super().get_queryset().select_related('category')
def get_context_data(self, **kwargs):
if self.object.allow_comments and not 'comment_form' in kwargs:
kwargs['comment_form'] = CommentForm()
@ -109,5 +143,3 @@ class PageDetailView(BaseView, DetailView):
return self.get(request, *args, **kwargs)