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,
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
accept_comments = models.BooleanField(
default = True,
@ -108,12 +114,12 @@ class WebsiteSettings(BaseSetting):
},
)
panels = [
MultiFieldPanel([
FieldPanel('favicon'),
FieldPanel('tags'),
FieldPanel('description'),
FieldPanel('list_page'),
], heading=_('promotion')),
MultiFieldPanel([
FieldPanel('allow_comments'),
@ -250,13 +256,16 @@ class Publication(Page):
verbose_name = _('Publication')
verbose_name_plural = _('Publication')
content_panels = Page.content_panels + [
FieldPanel('body', classname="full")
content_panels = [
MultiFieldPanel([
FieldPanel('title'),
FieldPanel('body', classname='full'),
FieldPanel('summary'),
], heading=_('Content'))
]
promote_panels = [
MultiFieldPanel([
ImageChooserPanel('cover'),
FieldPanel('summary'),
FieldPanel('tags'),
FieldPanel('focus'),
], heading=_('Content')),
@ -273,6 +282,12 @@ class Publication(Page):
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
def icon(self):
@ -482,6 +497,7 @@ class DiffusionPage(Publication):
item.live = True
item.info = []
# Translators: informations about a diffusion
if diff.initial:
item.info.append(_('Rerun of %(date)s') % {
'date': diff.initial.start.strftime('%A %d')
@ -541,62 +557,10 @@ class DiffusionPage(Publication):
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.
Look at get_queryset for more information.
@ -606,13 +570,32 @@ class ListPage(Page):
blank = True, null = True,
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:
verbose_name = _('List')
verbose_name_plural = _('List')
verbose_name = _('Generic Page')
verbose_name_plural = _('Generic Page')
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
if self.list_from_request:
qs = ListBase.from_request(request, context=context)
context['object_list'] = qs
return context

View File

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

View File

@ -336,4 +336,12 @@ main .body ~ section:not(.comments) {
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 **/
time {
time, .tags {
font-size: 0.9em;
color: #616161;
}
@ -54,6 +54,7 @@ time {
color: #007EDF;
}
a {
cursor: pointer;
text-decoration: none;
@ -64,6 +65,10 @@ a:hover {
color: #007EDF;
}
a:hover > .small_icon {
box-shadow: 0em 0em 0.1em #007EDF;
}
.error { color: red; }
.warning { color: orange; }
@ -79,29 +84,52 @@ a:hover {
main {
background-color: rgba(255,255,255,0.9);
padding: 1em;
margin: 0em 2em;
box-shadow: 0em 0em 0.2em black;
width: 60%;
}
main h1:not(.detail_title) {
main:not(.detail) h1 {
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;
padding: 0.2em;
}
main.detail > header h1.title {
position: relative;
left: -0.7em;
width: 80%;
width: calc(70% - 0.8em);
margin: 0em;
margin-bottom: -2em;
padding: 0.4em;
background-color: rgba(255,255,255,0.8);
}
main img.detail_cover {
width: calc(100% + 2em);
margin-top: -3.3em;
margin-left: -1em;
main.detail > header img.cover {
width: 70%;
display: inline-block;
}
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 **/

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

View File

@ -44,7 +44,7 @@
{% render_sections position="page_left" %}
</nav>
<main class="flex_item">
<main class="flex_item {% if not object_list %}detail{% endif %}">
{% if messages %}
<ul class="messages">
{% for message in messages %}
@ -55,9 +55,12 @@
</ul>
{% endif %}
<header>
{% block title %}
<h1>{{ page.title }}</h1>
{% endblock %}
</header>
{% block content %}
{% endblock %}
</main>
@ -70,7 +73,7 @@
{% block footer %}
<footer class="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>
</div>
</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 %}
{% 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 %}
{% endif %}
{% block content %}
{% if object_list %}
{# list view #}
@ -25,10 +38,6 @@
{% endwith %}
{% else %}
{# detail view #}
{% if page.cover %}
{% image page.cover max-600x480 class="detail_cover cover" height="" width="" %}
{% endif %}
<div class="content">
<section class="body">
{{ page.body|richtext}}

View File

@ -1,11 +1,13 @@
{% extends "cms/sections/section_item.html" %}
{% load i18n %}
{% load static %}
{% load wagtailsettings_tags %}
{% block content %}
<div class="meta">
<div class="author">
{% if page.publish_as %}
{% trans "Published by" %}
{% with item=page.publish_as item_date_format='' %}
{% include "cms/snippets/list_item.html" %}
{% endwith %}
@ -14,16 +16,45 @@
{{ page.owner }}
{% endif %}
</div>
<time datetime="{{ page.specific.date }}">
{% trans "Published on " %}
{{ page.specific.date|date:'l d F, H:i' }}
{% with page_date=page.specific.date %}
{% if page_date %}
<time datetime="{{ page_date }}">
<b>{% trans "Published on " %}</b>
{{ page_date|date:'l d F, H:i' }}
</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 %}
{# <a href="{% pageurl page.blog_index %}?tag={{ tag }}">{{ tag }}</a> #}
{{ tag }}
<a href="{{ list_page }}?tag={{ tag }}">{{ tag }}</a>
{% endfor %}
</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>
{% endblock %}

View File

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

View File

@ -29,7 +29,7 @@ Options:
{% if item.summary %}<div class="summary">{{ item.summary }}</div>{% endif %}
{% 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 }}">
{{ item.date|date:date_format }}
</time>

View File

@ -21,7 +21,9 @@ def render_sections(context, position = None):
request = context.get('request')
page = context.get('page')
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)
))