static pages
This commit is contained in:
		@ -91,16 +91,12 @@ class PageAdmin(BasePageAdmin):
 | 
			
		||||
 | 
			
		||||
@admin.register(StaticPage)
 | 
			
		||||
class StaticPageAdmin(BasePageAdmin):
 | 
			
		||||
    list_display = BasePageAdmin.list_display + ('view','menu_title')
 | 
			
		||||
    list_editable = BasePageAdmin.list_editable + ('menu_title',)
 | 
			
		||||
    list_display = BasePageAdmin.list_display + ('attach_to',)
 | 
			
		||||
    fieldsets = deepcopy(BasePageAdmin.fieldsets)
 | 
			
		||||
 | 
			
		||||
    fieldsets[0][1]['fields'].insert(fieldsets[0][1]['fields'].index('slug') + 1, 'menu_title')
 | 
			
		||||
    fieldsets[1][1]['fields'] += ('view',)
 | 
			
		||||
    fieldsets[1][1]['fields'] += ('attach_to',)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NavItemInline(SortableInlineAdminMixin, admin.TabularInline):
 | 
			
		||||
    model = NavItem
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -152,6 +152,10 @@ class Page(BasePage):
 | 
			
		||||
        _('allow comments'), default=True,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = _('Publication')
 | 
			
		||||
        verbose_name_plural = _('Publications')
 | 
			
		||||
 | 
			
		||||
    def save(self, *args, **kwargs):
 | 
			
		||||
        if self.is_published and self.pub_date is None:
 | 
			
		||||
            self.pub_date = tz.now()
 | 
			
		||||
@ -160,43 +164,30 @@ class Page(BasePage):
 | 
			
		||||
        super().save(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StaticPage(Page):
 | 
			
		||||
class StaticPage(BasePage):
 | 
			
		||||
    """ Static page that eventually can be attached to a specific view. """
 | 
			
		||||
    VIEW_HOME = 0x00
 | 
			
		||||
    VIEW_SCHEDULE = 0x01
 | 
			
		||||
    VIEW_LOG = 0x02
 | 
			
		||||
    VIEW_PROGRAMS = 0x03
 | 
			
		||||
    VIEW_EPISODES = 0x04
 | 
			
		||||
    VIEW_ARTICLES = 0x05
 | 
			
		||||
    detail_url_name = 'static-page-detail'
 | 
			
		||||
 | 
			
		||||
    VIEW_CHOICES = (
 | 
			
		||||
        (VIEW_HOME, _('Home Page')),
 | 
			
		||||
        (VIEW_SCHEDULE, _('Schedule Page')),
 | 
			
		||||
        (VIEW_LOG, _('Log Page')),
 | 
			
		||||
        (VIEW_PROGRAMS, _('Programs list')),
 | 
			
		||||
        (VIEW_EPISODES, _('Episodes list')),
 | 
			
		||||
        (VIEW_ARTICLES, _('Articles list')),
 | 
			
		||||
    ATTACH_TO_HOME = 0x00
 | 
			
		||||
    ATTACH_TO_DIFFUSIONS = 0x01
 | 
			
		||||
    ATTACH_TO_LOGS = 0x02
 | 
			
		||||
    ATTACH_TO_PROGRAMS = 0x03
 | 
			
		||||
    ATTACH_TO_EPISODES = 0x04
 | 
			
		||||
    ATTACH_TO_ARTICLES = 0x05
 | 
			
		||||
 | 
			
		||||
    ATTACH_TO_CHOICES = (
 | 
			
		||||
        (ATTACH_TO_HOME, _('Home page')),
 | 
			
		||||
        (ATTACH_TO_DIFFUSIONS, _('Diffusions page')),
 | 
			
		||||
        (ATTACH_TO_LOGS, _('Logs page')),
 | 
			
		||||
        (ATTACH_TO_PROGRAMS, _('Programs list')),
 | 
			
		||||
        (ATTACH_TO_EPISODES, _('Episodes list')),
 | 
			
		||||
        (ATTACH_TO_ARTICLES, _('Articles list')),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    view = models.SmallIntegerField(
 | 
			
		||||
        _('attach to'), choices=VIEW_CHOICES, blank=True, null=True,
 | 
			
		||||
    attach_to = models.SmallIntegerField(
 | 
			
		||||
        _('attach to'), choices=ATTACH_TO_CHOICES, blank=True, null=True,
 | 
			
		||||
        help_text=_('display this page content to related element'),
 | 
			
		||||
    )
 | 
			
		||||
    menu_title = models.CharField(_('menu title'), max_length=64, blank=True, null=True)
 | 
			
		||||
 | 
			
		||||
    is_active = False
 | 
			
		||||
 | 
			
		||||
    def render_menu_item(self, request, css_class='', active_class=''):
 | 
			
		||||
        if active_class and request.path.startswith(self.url):
 | 
			
		||||
            css_class += ' ' + active_class
 | 
			
		||||
 | 
			
		||||
        if not self.url:
 | 
			
		||||
            return self.text
 | 
			
		||||
        elif not css_class:
 | 
			
		||||
            return format_html('<a href="{}">{}</a>', self.url, self.text)
 | 
			
		||||
        else:
 | 
			
		||||
            return format_html('<a href="{}" class="{}">{}</a>', self.url,
 | 
			
		||||
                               css_class, self.text)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Comment(models.Model):
 | 
			
		||||
@ -218,6 +209,9 @@ class NavItem(models.Model):
 | 
			
		||||
    order = models.PositiveSmallIntegerField(_('order'))
 | 
			
		||||
    text = models.CharField(_('title'), max_length=64)
 | 
			
		||||
    url = models.CharField(_('url'), max_length=256, blank=True, null=True)
 | 
			
		||||
    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)
 | 
			
		||||
@ -227,12 +221,6 @@ class NavItem(models.Model):
 | 
			
		||||
        verbose_name = _('Menu item')
 | 
			
		||||
        ordering = ('order', 'pk')
 | 
			
		||||
 | 
			
		||||
    is_active = False
 | 
			
		||||
 | 
			
		||||
    def get_is_active(self, url):
 | 
			
		||||
        """ Return True if navigation item is active for this url. """
 | 
			
		||||
        return self.url and url.startswith(self.url)
 | 
			
		||||
 | 
			
		||||
    def render(self, request, css_class='', active_class=''):
 | 
			
		||||
        if active_class and request.path.startswith(self.url):
 | 
			
		||||
            css_class += ' ' + active_class
 | 
			
		||||
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
{% extends "aircox/page_list.html" %}
 | 
			
		||||
{% comment %}List of articles{% endcomment %}
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,11 @@ Blocks:
 | 
			
		||||
        {% endblock %}
 | 
			
		||||
 | 
			
		||||
        <title>
 | 
			
		||||
            {% block head_title %}{{ station.name }}{% endblock %}
 | 
			
		||||
            {% block head_title %}
 | 
			
		||||
            {% if page and page.title %}{{ page.title }} — {{ station.name }}
 | 
			
		||||
            {% else %}{{ station.name }}
 | 
			
		||||
            {% endif %}
 | 
			
		||||
            {% endblock %}
 | 
			
		||||
        </title>
 | 
			
		||||
 | 
			
		||||
        {% block head_extra %}{% endblock %}
 | 
			
		||||
@ -77,7 +81,13 @@ Blocks:
 | 
			
		||||
                    <main class="column page">
 | 
			
		||||
                        <header class="header">
 | 
			
		||||
                            {% block header %}
 | 
			
		||||
                            <h1 class="title is-1">{% block title %}{% endblock %}</h1>
 | 
			
		||||
                            <h1 class="title is-1">
 | 
			
		||||
                                {% block title %}
 | 
			
		||||
                                {% if page and page.title %}
 | 
			
		||||
                                {{ page.title }}
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                                {% endblock %}
 | 
			
		||||
                            </h1>
 | 
			
		||||
 | 
			
		||||
                            <h3 class="subtitle is-3">
 | 
			
		||||
                                {% block subtitle %}{% endblock %}
 | 
			
		||||
@ -96,6 +106,12 @@ Blocks:
 | 
			
		||||
                        </header>
 | 
			
		||||
 | 
			
		||||
                        {% block main %}
 | 
			
		||||
                            {% block content %}
 | 
			
		||||
                            {% if page and page.content %}
 | 
			
		||||
                            {{ page.content|safe }}
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                            {% endblock %}
 | 
			
		||||
 | 
			
		||||
                            {% if has_filters %}
 | 
			
		||||
                            {% comment %}Translators: extra toolbar displayed on the top of page lists {% endcomment %}
 | 
			
		||||
                            <nav class="navbar toolbar"
 | 
			
		||||
@ -103,6 +119,8 @@ Blocks:
 | 
			
		||||
                            {% block filters %}{% endblock %}
 | 
			
		||||
                            </nav>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                        {% endblock main %}
 | 
			
		||||
                    </main>
 | 
			
		||||
 | 
			
		||||
@ -111,8 +129,8 @@ Blocks:
 | 
			
		||||
                    <aside class="column is-one-third-desktop">
 | 
			
		||||
                        {# FIXME: block cover into sidebar one #}
 | 
			
		||||
                        {% block cover %}
 | 
			
		||||
                        {% if cover is not None %}
 | 
			
		||||
                        <img class="cover" src="{{ cover.url }}" class="cover"/>
 | 
			
		||||
                        {% if page and page.cover %}
 | 
			
		||||
                        <img class="cover" src="{{ page.cover.url }}" class="cover"/>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                        {% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,13 @@
 | 
			
		||||
{% load i18n aircox humanize %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{% if not page or not page.title %}
 | 
			
		||||
{% with station.name as station %}
 | 
			
		||||
{% blocktrans %}Today on {{ station }}{% endblocktrans %}
 | 
			
		||||
{% blocktrans %}This week on {{ station }}{% endblocktrans %}
 | 
			
		||||
{% endwith %}
 | 
			
		||||
{% else %}
 | 
			
		||||
{{ block.super }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -1,3 +0,0 @@
 | 
			
		||||
{% extends "aircox/page_list.html" %}
 | 
			
		||||
{% comment %}List of episodes pages{% endcomment %}
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
{% extends "aircox/page_list.html" %}
 | 
			
		||||
{% comment %}
 | 
			
		||||
Context:
 | 
			
		||||
- 
 | 
			
		||||
- main:
 | 
			
		||||
    - focused
 | 
			
		||||
    - nav to 'publications' view
 | 
			
		||||
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
{% load i18n %}
 | 
			
		||||
 | 
			
		||||
{% block head_title %}{% block title %}{{ station.name }}{% endblock %}{% endblock %}
 | 
			
		||||
{% block head_title %}{{ station.name }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block main %}
 | 
			
		||||
{% block title %}
 | 
			
		||||
{% if not page or not page.title %}{{ station.name }}
 | 
			
		||||
{% else %}{{ block.super }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block pages_list %}
 | 
			
		||||
{% if page and page.content %}<hr/>{% endif %}
 | 
			
		||||
<div class="columns">
 | 
			
		||||
    {% with render_card=True %}
 | 
			
		||||
    {% for object in top_diffs %}
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,13 @@
 | 
			
		||||
{% load i18n humanize aircox %}
 | 
			
		||||
 | 
			
		||||
{% block title %}
 | 
			
		||||
{% if not page or not page.title %}
 | 
			
		||||
{% with station.name as station %}
 | 
			
		||||
{% blocktrans %}That happened on {{ station }}{% endblocktrans %}
 | 
			
		||||
{% endwith %}
 | 
			
		||||
{% else %}
 | 
			
		||||
{{ block.super }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,12 @@
 | 
			
		||||
{% extends "aircox/base.html" %}
 | 
			
		||||
{% load static i18n thumbnail %}
 | 
			
		||||
{% comment %}
 | 
			
		||||
Base template to display pages (list, detail, whatever). By default extend to
 | 
			
		||||
this one instead of "base.html"
 | 
			
		||||
 | 
			
		||||
Context:
 | 
			
		||||
- cover: cover image
 | 
			
		||||
- title: title
 | 
			
		||||
- page: page
 | 
			
		||||
This template is only used in order to have correct page <title></title>,
 | 
			
		||||
otherwise use base.html
 | 
			
		||||
{% endcomment %}
 | 
			
		||||
 | 
			
		||||
{% block head_title %}
 | 
			
		||||
    {% comment %}Hack to include the page title into the <title> tag.{% endcomment %}
 | 
			
		||||
    {% block title %}{{ title }}{% endblock %}
 | 
			
		||||
    {% block title %}{{ page.title }}{% endblock %}
 | 
			
		||||
    —
 | 
			
		||||
    {{ station.name }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,9 +18,7 @@ Context:
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block main %}
 | 
			
		||||
{% block content %}
 | 
			
		||||
{{ object.content|default_if_none:''|safe }}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
{{ block.super }}
 | 
			
		||||
 | 
			
		||||
{% block comments %}
 | 
			
		||||
{% if comments or comment_form %}
 | 
			
		||||
 | 
			
		||||
@ -3,14 +3,17 @@
 | 
			
		||||
{% load i18n aircox %}
 | 
			
		||||
 | 
			
		||||
{% block 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 %}
 | 
			
		||||
{% 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 %}
 | 
			
		||||
 | 
			
		||||
@ -61,14 +64,19 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% 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 %}
 | 
			
		||||
 | 
			
		||||
@ -60,13 +60,20 @@ urls = [
 | 
			
		||||
    path(_('publications/'),
 | 
			
		||||
         views.PageListView.as_view(model=models.Page), name='page-list'),
 | 
			
		||||
 | 
			
		||||
    path(_('pages/'),
 | 
			
		||||
         views.PageListView.as_view(model=models.StaticPage), name='static-page-list'),
 | 
			
		||||
    path(_('pages/'), views.PageListView.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(
 | 
			
		||||
            model=models.StaticPage,
 | 
			
		||||
            queryset=models.StaticPage.objects.filter(attach_to__isnull=True),
 | 
			
		||||
        ),
 | 
			
		||||
        name='static-page-detail'
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
    path(_('pages/<slug:slug>/'),
 | 
			
		||||
         views.PageDetailView.as_view(), name='page-detail'),
 | 
			
		||||
 | 
			
		||||
    path(_('programs/'), views.ProgramListView.as_view(model=models.Program),
 | 
			
		||||
    path(_('programs/'), views.ProgramListView.as_view(),
 | 
			
		||||
         name='program-list'),
 | 
			
		||||
    path(_('programs/<slug:slug>/'),
 | 
			
		||||
         views.ProgramDetailView.as_view(), name='program-detail'),
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
from ..models import Article, Program
 | 
			
		||||
from .mixins import ParentMixin
 | 
			
		||||
from ..models import Article, Program, StaticPage
 | 
			
		||||
from .page import PageDetailView, PageListView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -17,12 +16,12 @@ class ArticleDetailView(PageDetailView):
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ArticleListView(ParentMixin, PageListView):
 | 
			
		||||
class ArticleListView(PageListView):
 | 
			
		||||
    model = Article
 | 
			
		||||
    template_name = 'aircox/article_list.html'
 | 
			
		||||
    has_headline = True
 | 
			
		||||
    is_static = False
 | 
			
		||||
    parent_model = Program
 | 
			
		||||
    attach_to_value = StaticPage.ATTACH_TO_ARTICLES
 | 
			
		||||
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
        return super().get_queryset().filter(is_static=self.is_static)
 | 
			
		||||
 | 
			
		||||
@ -12,11 +12,6 @@ __all__ = ['BaseView']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseView(TemplateResponseMixin, ContextMixin):
 | 
			
		||||
    title = None
 | 
			
		||||
    """ Page title """
 | 
			
		||||
    cover = None
 | 
			
		||||
    """ Page cover """
 | 
			
		||||
 | 
			
		||||
    has_sidebar = True
 | 
			
		||||
    """ Show side navigation """
 | 
			
		||||
    has_filters = False
 | 
			
		||||
@ -39,9 +34,12 @@ class BaseView(TemplateResponseMixin, ContextMixin):
 | 
			
		||||
    def get_sidebar_url(self):
 | 
			
		||||
        return reverse('page-list')
 | 
			
		||||
 | 
			
		||||
    def get_page(self):
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        kwargs.setdefault('station', self.station)
 | 
			
		||||
        kwargs.setdefault('cover', self.cover)
 | 
			
		||||
        kwargs.setdefault('page', self.get_page())
 | 
			
		||||
        kwargs.setdefault('has_filters', self.has_filters)
 | 
			
		||||
 | 
			
		||||
        has_sidebar = kwargs.setdefault('has_sidebar', self.has_sidebar)
 | 
			
		||||
@ -61,7 +59,6 @@ class BaseView(TemplateResponseMixin, ContextMixin):
 | 
			
		||||
                        type(self.object)
 | 
			
		||||
            kwargs['model'] = model
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,11 +4,11 @@ import datetime
 | 
			
		||||
from django.views.generic import ListView
 | 
			
		||||
from django.utils.translation import gettext as _
 | 
			
		||||
 | 
			
		||||
from ..models import Diffusion, Episode, Program, Sound
 | 
			
		||||
from ..models import Diffusion, Episode, Program, StaticPage, Sound
 | 
			
		||||
from .base import BaseView
 | 
			
		||||
from .program import ProgramPageDetailView
 | 
			
		||||
from .page import PageListView
 | 
			
		||||
from .mixins import GetDateMixin, ParentMixin
 | 
			
		||||
from .mixins import AttachedToMixin, GetDateMixin, ParentMixin
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ['EpisodeDetailView', 'EpisodeListView', 'DiffusionListView']
 | 
			
		||||
@ -28,18 +28,20 @@ class EpisodeDetailView(ProgramPageDetailView):
 | 
			
		||||
        return super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class EpisodeListView(ParentMixin, PageListView):
 | 
			
		||||
class EpisodeListView(PageListView):
 | 
			
		||||
    model = Episode
 | 
			
		||||
    item_template_name = 'aircox/widgets/episode_item.html'
 | 
			
		||||
    has_headline = True
 | 
			
		||||
    parent_model = Program
 | 
			
		||||
    attach_to_value = StaticPage.ATTACH_TO_EPISODES
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DiffusionListView(GetDateMixin, BaseView, ListView):
 | 
			
		||||
class DiffusionListView(GetDateMixin, AttachedToMixin, BaseView, ListView):
 | 
			
		||||
    """ View for timetables """
 | 
			
		||||
    model = Diffusion
 | 
			
		||||
    has_filters = True
 | 
			
		||||
    redirect_date_url = 'diffusion-list'
 | 
			
		||||
    attach_to_value = StaticPage.ATTACH_TO_DIFFUSIONS
 | 
			
		||||
 | 
			
		||||
    def get_date(self):
 | 
			
		||||
        date = super().get_date()
 | 
			
		||||
 | 
			
		||||
@ -3,9 +3,10 @@ import datetime
 | 
			
		||||
from django.utils.translation import gettext as _
 | 
			
		||||
from django.utils import timezone as tz
 | 
			
		||||
 | 
			
		||||
from ..models import Diffusion, Log, Page
 | 
			
		||||
from ..models import Diffusion, Log, Page, StaticPage
 | 
			
		||||
from .page import PageListView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HomeView(PageListView):
 | 
			
		||||
    template_name = 'aircox/home.html'
 | 
			
		||||
    model = Page
 | 
			
		||||
@ -14,6 +15,7 @@ class HomeView(PageListView):
 | 
			
		||||
    list_count = 40
 | 
			
		||||
    logs_count = 5
 | 
			
		||||
    has_filters = False
 | 
			
		||||
    attach_to_value = StaticPage.ATTACH_TO_HOME
 | 
			
		||||
 | 
			
		||||
    def get_logs(self):
 | 
			
		||||
        today = datetime.date.today()
 | 
			
		||||
 | 
			
		||||
@ -8,10 +8,10 @@ from rest_framework.generics import ListAPIView
 | 
			
		||||
from rest_framework import viewsets
 | 
			
		||||
from rest_framework.decorators import action
 | 
			
		||||
 | 
			
		||||
from ..models import Diffusion, Log
 | 
			
		||||
from ..models import Diffusion, Log, StaticPage
 | 
			
		||||
from ..serializers import LogInfo, LogInfoSerializer
 | 
			
		||||
from .base import BaseView, BaseAPIView
 | 
			
		||||
from .mixins import GetDateMixin
 | 
			
		||||
from .mixins import GetDateMixin, AttachedToMixin
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ['LogListMixin', 'LogListView']
 | 
			
		||||
@ -52,13 +52,14 @@ class LogListMixin(GetDateMixin):
 | 
			
		||||
        return Log.merge_diffusions(logs, diffs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LogListView(BaseView, LogListMixin, ListView):
 | 
			
		||||
class LogListView(AttachedToMixin, BaseView, LogListMixin, ListView):
 | 
			
		||||
    """
 | 
			
		||||
    Return list of logs for the provided date (from `kwargs` or
 | 
			
		||||
    `request.GET`, defaults to today).
 | 
			
		||||
    """
 | 
			
		||||
    redirect_date_url = 'log-list'
 | 
			
		||||
    has_filters = True
 | 
			
		||||
    attach_to_value = StaticPage.ATTACH_TO_LOGS
 | 
			
		||||
 | 
			
		||||
    def get_date(self):
 | 
			
		||||
        date = super().get_date()
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,10 @@ from django.shortcuts import get_object_or_404, redirect
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from ..utils import str_to_date
 | 
			
		||||
from ..models import StaticPage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ['GetDateMixin', 'ParentMixin']
 | 
			
		||||
__all__ = ['GetDateMixin', 'ParentMixin', 'AttachedToMixin']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GetDateMixin:
 | 
			
		||||
@ -68,3 +69,14 @@ class ParentMixin:
 | 
			
		||||
        return super().get_context_data(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AttachedToMixin:
 | 
			
		||||
    """ Mixin for views that can have a static page attached to it. """
 | 
			
		||||
    attach_to_value = None
 | 
			
		||||
    """ Value of StaticPage.attach_to """
 | 
			
		||||
 | 
			
		||||
    def get_page(self):
 | 
			
		||||
        if self.attach_to_value is not None:
 | 
			
		||||
            return StaticPage.objects.filter(attach_to=self.attach_to_value) \
 | 
			
		||||
                             .published().first()
 | 
			
		||||
        return super().get_page()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,15 +6,16 @@ from django.views.generic import DetailView, ListView
 | 
			
		||||
from honeypot.decorators import check_honeypot
 | 
			
		||||
 | 
			
		||||
from ..forms import CommentForm
 | 
			
		||||
from ..models import Category, Comment, Page
 | 
			
		||||
from ..models import Category, Comment
 | 
			
		||||
from ..utils import Redirect
 | 
			
		||||
from .base import BaseView
 | 
			
		||||
from .mixins import AttachedToMixin, ParentMixin
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ['PageDetailView', 'PageListView']
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PageListView(BaseView, ListView):
 | 
			
		||||
class PageListView(AttachedToMixin, ParentMixin, BaseView, ListView):
 | 
			
		||||
    template_name = 'aircox/page_list.html'
 | 
			
		||||
    item_template_name = 'aircox/widgets/page_item.html'
 | 
			
		||||
    has_sidebar = True
 | 
			
		||||
@ -81,14 +82,12 @@ class PageDetailView(BaseView, DetailView):
 | 
			
		||||
            raise Http404('%s not found' % self.model._meta.verbose_name)
 | 
			
		||||
        return obj
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        page = kwargs.setdefault('page', self.object)
 | 
			
		||||
        kwargs.setdefault('title', page.title)
 | 
			
		||||
        kwargs.setdefault('cover', page.cover)
 | 
			
		||||
    def get_page(self):
 | 
			
		||||
        return self.object
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
        if self.object.allow_comments and not 'comment_form' in kwargs:
 | 
			
		||||
            kwargs['comment_form'] = CommentForm()
 | 
			
		||||
 | 
			
		||||
        kwargs['comments'] = Comment.objects.filter(page=self.object) \
 | 
			
		||||
                                            .order_by('-date')
 | 
			
		||||
        return super().get_context_data(**kwargs)
 | 
			
		||||
@ -112,5 +111,3 @@ class PageDetailView(BaseView, DetailView):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,8 @@ from django.core.exceptions import ObjectDoesNotExist
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
 | 
			
		||||
from ..models import Episode, Program, Page
 | 
			
		||||
from .mixins import ParentMixin
 | 
			
		||||
from ..models import Episode, Program, Page, StaticPage
 | 
			
		||||
from .mixins import ParentMixin, AttachedToMixin
 | 
			
		||||
from .page import PageDetailView, PageListView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -34,8 +34,10 @@ class ProgramDetailView(BaseProgramMixin, PageDetailView):
 | 
			
		||||
 | 
			
		||||
class ProgramListView(PageListView):
 | 
			
		||||
    model = Program
 | 
			
		||||
    attach_to_value = StaticPage.ATTACH_TO_PROGRAMS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# FIXME: not used
 | 
			
		||||
class ProgramPageDetailView(BaseProgramMixin, ParentMixin, PageDetailView):
 | 
			
		||||
    """
 | 
			
		||||
    Base view class for a page that is displayed as a program's child page.
 | 
			
		||||
@ -50,7 +52,7 @@ class ProgramPageDetailView(BaseProgramMixin, ParentMixin, PageDetailView):
 | 
			
		||||
        return super().get_sidebar_queryset().filter(parent=self.program)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ProgramPageListView(BaseProgramMixin, ParentMixin, PageListView):
 | 
			
		||||
class ProgramPageListView(BaseProgramMixin, PageListView):
 | 
			
		||||
    model = Page
 | 
			
		||||
    parent_model = Program
 | 
			
		||||
    queryset = Page.objects.select_subclasses()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user