ListPage as GenericPage; setting list_page; remove EventPage; pass context data in sections (to be able to retrieve settings; share buttons; tags with url

This commit is contained in:
bkfox 2016-08-10 15:55:40 +02:00
parent 021b2a116a
commit 1a6765b9b7
14 changed files with 267 additions and 175 deletions

View File

@ -58,7 +58,13 @@ class WebsiteSettings(BaseSetting):
null=True, blank=True, null=True, blank=True,
help_text = _('public description of the website; used for referencing'), help_text = _('public description of the website; used for referencing'),
) )
list_page = models.ForeignKey(
'cms.GenericPage',
verbose_name = _('page for lists'),
help_text=_('page used to display the results of a search and other '
'lists'),
related_name= 'list_page'
)
# comments # comments
accept_comments = models.BooleanField( accept_comments = models.BooleanField(
default = True, default = True,
@ -108,12 +114,12 @@ class WebsiteSettings(BaseSetting):
}, },
) )
panels = [ panels = [
MultiFieldPanel([ MultiFieldPanel([
FieldPanel('favicon'), FieldPanel('favicon'),
FieldPanel('tags'), FieldPanel('tags'),
FieldPanel('description'), FieldPanel('description'),
FieldPanel('list_page'),
], heading=_('promotion')), ], heading=_('promotion')),
MultiFieldPanel([ MultiFieldPanel([
FieldPanel('allow_comments'), FieldPanel('allow_comments'),
@ -250,13 +256,16 @@ class Publication(Page):
verbose_name = _('Publication') verbose_name = _('Publication')
verbose_name_plural = _('Publication') verbose_name_plural = _('Publication')
content_panels = Page.content_panels + [ content_panels = [
FieldPanel('body', classname="full") MultiFieldPanel([
FieldPanel('title'),
FieldPanel('body', classname='full'),
FieldPanel('summary'),
], heading=_('Content'))
] ]
promote_panels = [ promote_panels = [
MultiFieldPanel([ MultiFieldPanel([
ImageChooserPanel('cover'), ImageChooserPanel('cover'),
FieldPanel('summary'),
FieldPanel('tags'), FieldPanel('tags'),
FieldPanel('focus'), FieldPanel('focus'),
], heading=_('Content')), ], heading=_('Content')),
@ -273,6 +282,12 @@ class Publication(Page):
index.FilterField('show_in_menus'), index.FilterField('show_in_menus'),
] ]
@property
def url(self):
if not self.live:
parent = self.get_parent().specific
return parent and parent.url
return super().url
@property @property
def icon(self): def icon(self):
@ -482,6 +497,7 @@ class DiffusionPage(Publication):
item.live = True item.live = True
item.info = [] item.info = []
# Translators: informations about a diffusion
if diff.initial: if diff.initial:
item.info.append(_('Rerun of %(date)s') % { item.info.append(_('Rerun of %(date)s') % {
'date': diff.initial.start.strftime('%A %d') 'date': diff.initial.start.strftime('%A %d')
@ -541,62 +557,10 @@ class DiffusionPage(Publication):
super().save(*args, **kwargs) super().save(*args, **kwargs)
class EventPageQuerySet(PageQuerySet):
def upcoming(self):
now = tz.now().date()
return self.filter(start_date__gte=now)
class EventPage(Publication):
order_field = 'start'
start = models.DateTimeField(
_('start'),
help_text = _('when it happens'),
)
end = models.DateTimeField(
_('end'),
blank = True, null = True,
)
place = models.TextField(
_('place'),
help_text = _('address where the event takes place'),
)
price = models.CharField(
_('price'),
max_length=64,
blank = True, null = True,
help_text = _('price of the event'),
)
info = models.TextField(
_('info'),
blank = True, null = True,
help_text = _('additional information'),
)
objects = PageManager.from_queryset(EventPageQuerySet)
class Meta:
verbose_name = _('Event')
verbose_name_plural = _('Events')
content_panels = Publication.content_panels + [
FieldRowPanel([
FieldPanel('start'),
FieldPanel('end'),
]),
FieldPanel('place'),
]
def save(self, *args, **kwargs):
self.date = self.start
super().save(*args, **kwargs)
# #
# Lists # Other type of pages
# #
class ListPage(Page): class GenericPage(Page):
""" """
Page for simple lists, query is done though request' GET fields. Page for simple lists, query is done though request' GET fields.
Look at get_queryset for more information. Look at get_queryset for more information.
@ -606,13 +570,32 @@ class ListPage(Page):
blank = True, null = True, blank = True, null = True,
help_text = _('add an extra description for this list') help_text = _('add an extra description for this list')
) )
list_from_request = models.BooleanField(
_('list from the request'),
default = False,
help_text = _(
'if set, the page print a list based on the request made by '
'the website visitor, and its title will be adapted to this '
'request. Can be usefull for search pages, etc. and should '
'only be set on one page.'
)
)
content_panels = [
MultiFieldPanel([
FieldPanel('title'),
FieldPanel('body'),
FieldPanel('list_from_request'),
], heading=_('Content'))
]
class Meta: class Meta:
verbose_name = _('List') verbose_name = _('Generic Page')
verbose_name_plural = _('List') verbose_name_plural = _('Generic Page')
def get_context(self, request, *args, **kwargs): def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs) context = super().get_context(request, *args, **kwargs)
if self.list_from_request:
qs = ListBase.from_request(request, context=context) qs = ListBase.from_request(request, context=context)
context['object_list'] = qs context['object_list'] = qs
return context return context

View File

@ -163,13 +163,15 @@ class ListBase(models.Model):
ContentType, ContentType,
verbose_name = _('filter by type'), verbose_name = _('filter by type'),
blank = True, null = True, blank = True, null = True,
on_delete=models.SET_NULL,
help_text = _('if set, select only elements that are of this type'), help_text = _('if set, select only elements that are of this type'),
limit_choices_to = related_pages_filter, limit_choices_to = related_pages_filter,
) )
related = models.ForeignKey( related = models.ForeignKey(
Page, Page,
verbose_name = _('filter by a related publication'), verbose_name = _('filter by a related page'),
blank = True, null = True, blank = True, null = True,
on_delete=models.SET_NULL,
help_text = _('if set, select children or siblings related to this page'), help_text = _('if set, select children or siblings related to this page'),
) )
siblings = models.BooleanField( siblings = models.BooleanField(
@ -184,6 +186,9 @@ class ListBase(models.Model):
help_text = _('if selected sort list in the ascending order by date') help_text = _('if selected sort list in the ascending order by date')
) )
class Meta:
abstract = True
panels = [ panels = [
MultiFieldPanel([ MultiFieldPanel([
FieldPanel('model'), FieldPanel('model'),
@ -196,8 +201,6 @@ class ListBase(models.Model):
], heading=_('sorting')) ], heading=_('sorting'))
] ]
class Meta:
abstract = True
def get_queryset(self): def get_queryset(self):
""" """
@ -245,7 +248,7 @@ class ListBase(models.Model):
to override values of self or add some to the parameters. to override values of self or add some to the parameters.
If there is related field use it to get the page, otherwise use the If there is related field use it to get the page, otherwise use the
given list_page or the first ListPage it finds. given list_page or the first GenericPage it finds.
""" """
import aircox.cms.models as models import aircox.cms.models as models
@ -259,7 +262,7 @@ class ListBase(models.Model):
params.update(kwargs) params.update(kwargs)
page = params.get('related') or list_page or \ page = params.get('related') or list_page or \
models.ListPage.objects.all().first() models.GenericPage.objects.all().first()
if params.get('related'): if params.get('related'):
params['related'] = True params['related'] = True
@ -465,6 +468,12 @@ class Section(ClusterableModel):
'page or publication is of this type'), 'page or publication is of this type'),
limit_choices_to = related_pages_filter, limit_choices_to = related_pages_filter,
) )
page = models.ForeignKey(
Page,
verbose_name = _('page'),
blank = True, null = True,
help_text=_('this section is displayed only on this page'),
)
panels = [ panels = [
MultiFieldPanel([ MultiFieldPanel([
@ -494,9 +503,9 @@ class Section(ClusterableModel):
) )
return qs return qs
def render(self, request, page = None, *args, **kwargs): def render(self, request, page = None, context = None, *args, **kwargs):
return ''.join([ return ''.join([
place.item.specific.render(request, page, *args, **kwargs) place.item.specific.render(request, page, context, *args, **kwargs)
for place in self.places.all() for place in self.places.all()
]) ])
@ -596,6 +605,7 @@ class SectionItem(models.Model,metaclass=SectionItemMeta):
Other context attributes usable in the default template: Other context attributes usable in the default template:
* content: **safe string** set as content of the section * content: **safe string** set as content of the section
* hide: DO NOT render the section, render only an empty string
""" """
return { return {
'self': self, 'self': self,
@ -603,7 +613,7 @@ class SectionItem(models.Model,metaclass=SectionItemMeta):
'request': request, 'request': request,
} }
def render(self, request, page, *args, **kwargs): def render(self, request, page, context, *args, **kwargs):
""" """
Render the section. Page is the current publication being rendered. Render the section. Page is the current publication being rendered.
@ -614,10 +624,13 @@ class SectionItem(models.Model,metaclass=SectionItemMeta):
that can have a context attribute 'content' that is used to render that can have a context attribute 'content' that is used to render
content. content.
""" """
return render_to_string( context_ = self.get_context(request, *args, page=page, **kwargs)
self.template, if context:
self.get_context(request, *args, page=page, **kwargs) context_.update(context)
)
if context.get('hide'):
return ''
return render_to_string(self.template, context_)
def __str__(self): def __str__(self):
return '{}: {}'.format( return '{}: {}'.format(
@ -824,6 +837,10 @@ class SectionList(ListBase, SectionRelativeItem):
qs = qs.exclude(pk = focus.pk) qs = qs.exclude(pk = focus.pk)
else: else:
focus = None focus = None
if not qs.count():
return { 'hide': True }
pages = qs[:self.count - (focus != None)] pages = qs[:self.count - (focus != None)]
context['focus'] = focus context['focus'] = focus
@ -920,12 +937,6 @@ class SectionPublicationInfo(SectionItem):
@register_snippet @register_snippet
class SectionSearchField(SectionItem): class SectionSearchField(SectionItem):
page = models.ForeignKey(
'cms.ListPage',
verbose_name = _('search page'),
blank = True, null = True,
help_text=_('page used to display the results'),
)
default_text = models.CharField( default_text = models.CharField(
_('default text'), _('default text'),
max_length=32, max_length=32,
@ -938,15 +949,12 @@ class SectionSearchField(SectionItem):
verbose_name_plural = _('Sections: search field') verbose_name_plural = _('Sections: search field')
panels = SectionItem.panels + [ panels = SectionItem.panels + [
PageChooserPanel('page'),
FieldPanel('default_text'), FieldPanel('default_text'),
] ]
def get_context(self, request, page): def get_context(self, request, page):
from aircox.cms.models import ListPage from aircox.cms.models import GenericPage
context = super().get_context(request, page) context = super().get_context(request, page)
list_page = self.page or ListPage.objects.live().first()
context['list_page'] = list_page
return context return context

View File

@ -336,4 +336,12 @@ main .body ~ section:not(.comments) {
display: inline-block; display: inline-block;
} }
.meta > .share {
margin-top: 0.8em;
}
.meta .author .summary {
display: none;
}

View File

@ -43,7 +43,7 @@ h2 * { vertical-align: middle; }
/** info **/ /** info **/
time { time, .tags {
font-size: 0.9em; font-size: 0.9em;
color: #616161; color: #616161;
} }
@ -54,6 +54,7 @@ time {
color: #007EDF; color: #007EDF;
} }
a { a {
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
@ -64,6 +65,10 @@ a:hover {
color: #007EDF; color: #007EDF;
} }
a:hover > .small_icon {
box-shadow: 0em 0em 0.1em #007EDF;
}
.error { color: red; } .error { color: red; }
.warning { color: orange; } .warning { color: orange; }
@ -79,29 +84,52 @@ a:hover {
main { main {
background-color: rgba(255,255,255,0.9); background-color: rgba(255,255,255,0.9);
padding: 1em; padding: 1em;
margin: 0em 2em;
box-shadow: 0em 0em 0.2em black; box-shadow: 0em 0em 0.2em black;
width: 60%;
} }
main h1:not(.detail_title) {
main:not(.detail) h1 {
margin: 0em 0em 0.4em 0em; margin: 0em 0em 0.4em 0em;
} }
main.detail {
padding: 0em;
}
main h1.detail_title { main.detail > .content {
padding: 1em;
}
main.detail > header {
padding: 0em;
margin: 0em; margin: 0em;
padding: 0.2em; }
main.detail > header h1.title {
position: relative; position: relative;
left: -0.7em; width: calc(70% - 0.8em);
width: 80%; margin: 0em;
margin-bottom: -2em;
padding: 0.4em;
background-color: rgba(255,255,255,0.8); background-color: rgba(255,255,255,0.8);
} }
main img.detail_cover { main.detail > header img.cover {
width: calc(100% + 2em); width: 70%;
margin-top: -3.3em; display: inline-block;
margin-left: -1em;
} }
main.detail header .summary {
display: inline-block;
padding: 1em;
width: calc(20% - 2em);
vertical-align: top;
font-size: 1.2em;
font-weight: bold;
background-color: white;
}
/** player **/ /** player **/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -220,7 +220,6 @@ function Player(id, on_air_url, show_cover) {
bar: this.player.querySelector('.controls .progress progress'), bar: this.player.querySelector('.controls .progress progress'),
duration: this.player.querySelector('.controls .progress .duration') duration: this.player.querySelector('.controls .progress .duration')
} }
console.log(this.progress)
this.controls = { this.controls = {
single: this.player.querySelector('input.single'), single: this.player.querySelector('input.single'),
@ -361,6 +360,11 @@ Player.prototype = {
this.audio.pause(); this.audio.pause();
}, },
stop: function() {
this.audio.pause();
this.player.removeAttribute('state');
},
__mime_type: function(path) { __mime_type: function(path) {
ext = path.substr(path.lastIndexOf('.')+1); ext = path.substr(path.lastIndexOf('.')+1);
return 'audio/' + ext; return 'audio/' + ext;

View File

@ -44,7 +44,7 @@
{% render_sections position="page_left" %} {% render_sections position="page_left" %}
</nav> </nav>
<main class="flex_item"> <main class="flex_item {% if not object_list %}detail{% endif %}">
{% if messages %} {% if messages %}
<ul class="messages"> <ul class="messages">
{% for message in messages %} {% for message in messages %}
@ -55,9 +55,12 @@
</ul> </ul>
{% endif %} {% endif %}
<header>
{% block title %} {% block title %}
<h1>{{ page.title }}</h1> <h1>{{ page.title }}</h1>
{% endblock %} {% endblock %}
</header>
{% block content %} {% block content %}
{% endblock %} {% endblock %}
</main> </main>
@ -70,7 +73,7 @@
{% block footer %} {% block footer %}
<footer class="footer"> <footer class="footer">
{% render_sections position="footer" %} {% render_sections position="footer" %}
<div class="small">Propulsed by <div class="small float_right">Propulsed by
<a href="https://github.com/bkfox/aircox">Aircox</a> <a href="https://github.com/bkfox/aircox">Aircox</a>
</div> </div>
</footer> </footer>

View File

@ -0,0 +1,61 @@
{% extends "cms/base_site.html" %}
{# generic page to display list of articles #}
{% load i18n %}
{% load wagtailcore_tags %}
{% load wagtailimages_tags %}
{% block title %}
<h1>
{# Translators: titles for the page that shows a list of elements. #}
{# Translators: terms are search terms, or tag tarms. url: url to the page #}
{% if page.list_from_request %}
{% with terms=list_selector.terms %}
{% if terms %}
{% blocktrans %}Search in publications for <i>{{ terms }}</i>{% endblocktrans %}
{% elif list_selector.filter_related %}
{# should never happen #}
{% with title=list_selector.filter_related.title url=list_selector.filter_related.url %}
{% blocktrans %}
Related to <a href="{{ url }}">{{ title }}</a>{% endblocktrans %}
{% endwith %}
{% else %}
{% blocktrans %}All the publications{% endblocktrans %}
{% endif %}
{% endwith %}
{% else %}
{{ page.title }}
{% endif %}
</h1>
{% endblock %}
{% block content %}
{% if page.list_from_request %}
{% with related=list_selector.filter_related %}
{% if related %}
<div class="body summary">
{% image related.cover fill-128x128 class="cover item_cover" %}
{{ related.summary }}
<a href="{{ related.url }}">{% trans "More about it" %}</a>
</div>
{% elif page.body %}
<div class="body">
{{ page.body|richtext }}
</div>
{% endif %}
{% endwith %}
{% with list_paginator=paginator %}
{% include "cms/snippets/list.html" %}
{% endwith %}
{% else %}
<div class="body">
{{ page.body|richtext }}
</div>
{% endif %}
{% endblock %}

View File

@ -1,49 +0,0 @@
{% extends "cms/base_site.html" %}
{# generic page to display list of articles #}
{% load i18n %}
{% load wagtailcore_tags %}
{% load wagtailimages_tags %}
{% block title %}
<h1>
{% with terms=list_selector.terms %}
{% if terms %}
{% blocktrans %}Search in publications for <i>{{ terms }}</i>{% endblocktrans %}
{% elif list_selector.filter_related %}
{# should never happen #}
{% with title=list_selector.filter_related.title url=list_selector.filter_related.url %}
{% blocktrans %}
Related to <a href="{{ url }}">{{ title }}</a>{% endblocktrans %}
{% endwith %}
{% else %}
{% blocktrans %}All the publications{% endblocktrans %}
{% endif %}
{% endwith %}
</h1>
{% endblock %}
{% block content %}
{% with related=list_selector.filter_related %}
{% if related %}
<div class="body summary">
{% image related.cover fill-128x128 class="cover item_cover" %}
{{ related.summary }}
<a href="{{ related.url }}">{% trans "More about it" %}</a>
</div>
{% elif page.body %}
<div class="body">
{{ page.body|richtext }}
</div>
{% endif %}
{% endwith %}
{% with list_paginator=paginator %}
{% include "cms/snippets/list.html" %}
{% endwith %}
{% endblock %}

View File

@ -8,10 +8,23 @@
{% if not object_list %} {% if not object_list %}
{% block title %} {% block title %}
<h1 class="detail_title">{{ page.title }}</h1> <h1 class="title">{{ page.title }}</h1>
{% if page.cover %}
{% image page.cover max-600x480 class="cover" height="" width="" %}
{% endif %}
<section class="summary">
{% if page.summary %}
{{ page.summary }}
{% else %}
{{ page.body|richtext|truncatewords:32 }}
{% endif %}
</section>
{% endblock %} {% endblock %}
{% endif %} {% endif %}
{% block content %} {% block content %}
{% if object_list %} {% if object_list %}
{# list view #} {# list view #}
@ -25,10 +38,6 @@
{% endwith %} {% endwith %}
{% else %} {% else %}
{# detail view #} {# detail view #}
{% if page.cover %}
{% image page.cover max-600x480 class="detail_cover cover" height="" width="" %}
{% endif %}
<div class="content"> <div class="content">
<section class="body"> <section class="body">
{{ page.body|richtext}} {{ page.body|richtext}}

View File

@ -1,11 +1,13 @@
{% extends "cms/sections/section_item.html" %} {% extends "cms/sections/section_item.html" %}
{% load i18n %} {% load i18n %}
{% load static %}
{% load wagtailsettings_tags %}
{% block content %} {% block content %}
<div class="meta"> <div class="meta">
<div class="author"> <div class="author">
{% if page.publish_as %} {% if page.publish_as %}
{% trans "Published by" %}
{% with item=page.publish_as item_date_format='' %} {% with item=page.publish_as item_date_format='' %}
{% include "cms/snippets/list_item.html" %} {% include "cms/snippets/list_item.html" %}
{% endwith %} {% endwith %}
@ -14,16 +16,45 @@
{{ page.owner }} {{ page.owner }}
{% endif %} {% endif %}
</div> </div>
<time datetime="{{ page.specific.date }}"> {% with page_date=page.specific.date %}
{% trans "Published on " %} {% if page_date %}
{{ page.specific.date|date:'l d F, H:i' }} <time datetime="{{ page_date }}">
<b>{% trans "Published on " %}</b>
{{ page_date|date:'l d F, H:i' }}
</time> </time>
<div class="tags"> {% endif %}
{% endwith %}
{% with list_page=settings.cms.WebsiteSettings.list_page %}
{% if list_page %}
<div class="tags"><b>{% trans "Tags" %}</b>
{% for tag in page.tags.all %} {% for tag in page.tags.all %}
{# <a href="{% pageurl page.blog_index %}?tag={{ tag }}">{{ tag }}</a> #} <a href="{{ list_page }}?tag={{ tag }}">{{ tag }}</a>
{{ tag }}
{% endfor %} {% endfor %}
</div> </div>
{% endif %}
{% endwith %}
<div class="share">
<img src="{% static "cms/images/share.png" %}" alt="{% trans "Share" %}"
class="small_icon">
<a href="mailto:?&body={{ page.full_url|urlencode }}"
target="new">
<img src="{% static "cms/images/mail.png" %}" alt="Mail" class="small_icon">
</a>
<a href="https://www.facebook.com/sharer/sharer.php?u={{ page.full_url|urlencode }}"
target="new">
<img src="{% static "cms/images/facebook.png" %}" alt="Facebook" class="small_icon">
</a>
<a href="https://twitter.com/intent/tweet?text={{ page.full_url|urlencode }}"
target="new">
<img src="{% static "cms/images/twitter.png" %}" alt="Twitter" class="small_icon">
</a>
<a href="https://plus.google.com/share?url={{ page.full_url|urlencode }}"
target="new">
<img src="{% static "cms/images/gplus.png" %}" alt="Google Plus" class="small_icon">
</a>
</div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -2,11 +2,15 @@
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load wagtailsettings_tags %}
{% block content %} {% block content %}
{% with list_page=settings.cms.WebsiteSettings.list_page %}
<form action="{{ list_page.url }}" method="GET"> <form action="{{ list_page.url }}" method="GET">
<img src="{% static "cms/images/search.png" %}" class="icon"/> <img src="{% static "cms/images/search.png" %}" class="icon"/>
<input type="text" name="search" placeholder="{{ self.default_text }}"> <input type="text" name="search" placeholder="{{ self.default_text }}">
<input type="submit" style="display: none;"> <input type="submit" style="display: none;">
</form> </form>
{% endwith %}
{% endblock %} {% endblock %}

View File

@ -29,7 +29,7 @@ Options:
{% if item.summary %}<div class="summary">{{ item.summary }}</div>{% endif %} {% if item.summary %}<div class="summary">{{ item.summary }}</div>{% endif %}
{% if not item.show_in_menus and item.date and item_date_format != '' %} {% if not item.show_in_menus and item.date and item_date_format != '' %}
{% with date_format=item_date_format|default_if_none:'l d F, H:i' %} {% with date_format=item_date_format|default:'l d F, H:i' %}
<time datetime="{{ item.date }}"> <time datetime="{{ item.date }}">
{{ item.date|date:date_format }} {{ item.date|date:date_format }}
</time> </time>

View File

@ -21,7 +21,9 @@ def render_sections(context, position = None):
request = context.get('request') request = context.get('request')
page = context.get('page') page = context.get('page')
return mark_safe(''.join( return mark_safe(''.join(
section.render(request, page=page) section.render(request, page=page, context = {
'settings': context.get('settings')
})
for section in Section.get_sections_at(position, page) for section in Section.get_sections_at(position, page)
)) ))