forked from rc/aircox
add new sections
This commit is contained in:
parent
8906ba0919
commit
ac5db1ea84
|
@ -196,6 +196,10 @@ class Publication(Page):
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Publication')
|
||||||
|
verbose_name_plural = _('Publication')
|
||||||
|
|
||||||
content_panels = Page.content_panels + [
|
content_panels = Page.content_panels + [
|
||||||
FieldPanel('body', classname="full")
|
FieldPanel('body', classname="full")
|
||||||
]
|
]
|
||||||
|
@ -619,3 +623,5 @@ class TimetablePage(DatedListPage):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
162
cms/sections.py
162
cms/sections.py
|
@ -2,10 +2,12 @@ import datetime
|
||||||
import re
|
import re
|
||||||
from enum import Enum, IntEnum
|
from enum import Enum, IntEnum
|
||||||
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||||
from django.utils import timezone as tz
|
from django.utils import timezone as tz
|
||||||
|
from django.utils.text import slugify
|
||||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||||
|
|
||||||
from wagtail.wagtailcore.models import Page, Orderable
|
from wagtail.wagtailcore.models import Page, Orderable
|
||||||
|
@ -49,8 +51,17 @@ class ListItem:
|
||||||
class BaseRelatedLink(Orderable):
|
class BaseRelatedLink(Orderable):
|
||||||
url = models.URLField(
|
url = models.URLField(
|
||||||
_('url'),
|
_('url'),
|
||||||
|
null=True, blank=True,
|
||||||
help_text = _('URL of the link'),
|
help_text = _('URL of the link'),
|
||||||
)
|
)
|
||||||
|
page = models.ForeignKey(
|
||||||
|
'wagtailcore.Page',
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
related_name='+',
|
||||||
|
help_text = _('Use a page instead of a URL')
|
||||||
|
)
|
||||||
icon = models.ForeignKey(
|
icon = models.ForeignKey(
|
||||||
'wagtailimages.Image',
|
'wagtailimages.Image',
|
||||||
verbose_name = _('icon'),
|
verbose_name = _('icon'),
|
||||||
|
@ -59,8 +70,8 @@ class BaseRelatedLink(Orderable):
|
||||||
related_name='+',
|
related_name='+',
|
||||||
help_text = _('icon to display before the url'),
|
help_text = _('icon to display before the url'),
|
||||||
)
|
)
|
||||||
title = models.CharField(
|
text = models.CharField(
|
||||||
_('title'),
|
_('text'),
|
||||||
max_length = 64,
|
max_length = 64,
|
||||||
null = True, blank=True,
|
null = True, blank=True,
|
||||||
help_text = _('text to display of the link'),
|
help_text = _('text to display of the link'),
|
||||||
|
@ -70,11 +81,12 @@ class BaseRelatedLink(Orderable):
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
panels = [
|
panels = [
|
||||||
FieldPanel('url'),
|
MultiFieldPanel([
|
||||||
FieldRowPanel([
|
FieldPanel('text'),
|
||||||
FieldPanel('title'),
|
|
||||||
ImageChooserPanel('icon'),
|
ImageChooserPanel('icon'),
|
||||||
]),
|
FieldPanel('url'),
|
||||||
|
PageChooserPanel('page'),
|
||||||
|
], heading=_('link'))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +113,8 @@ class BaseList(models.Model):
|
||||||
blank = True, null = True,
|
blank = True, null = True,
|
||||||
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 = {
|
limit_choices_to = {
|
||||||
'publication__isnull': False,
|
'model__in': ('publication','programpage','diffusionpage',
|
||||||
|
'eventpage'),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
filter_related = models.ForeignKey(
|
filter_related = models.ForeignKey(
|
||||||
|
@ -122,6 +135,18 @@ class BaseList(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')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
panels = [
|
||||||
|
MultiFieldPanel([
|
||||||
|
FieldPanel('filter_model'),
|
||||||
|
FieldPanel('filter_related'),
|
||||||
|
FieldPanel('related_sibling'),
|
||||||
|
], heading=_('filters')),
|
||||||
|
MultiFieldPanel([
|
||||||
|
FieldPanel('filter_date'),
|
||||||
|
FieldPanel('sort_asc'),
|
||||||
|
], heading=_('sorting'))
|
||||||
|
]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
@ -138,7 +163,7 @@ class BaseList(models.Model):
|
||||||
qs = filter_model.objects.all()
|
qs = filter_model.objects.all()
|
||||||
else:
|
else:
|
||||||
qs = Publication.objects.all()
|
qs = Publication.objects.all()
|
||||||
qs = qs.live().not_in_menu()
|
qs = qs.live().not_in_section()
|
||||||
|
|
||||||
# related
|
# related
|
||||||
if filter_related:
|
if filter_related:
|
||||||
|
@ -232,7 +257,7 @@ class BaseList(models.Model):
|
||||||
|
|
||||||
class BaseDatedList(models.Model):
|
class BaseDatedList(models.Model):
|
||||||
"""
|
"""
|
||||||
List that display items per days. Renders a navigation menu on the
|
List that display items per days. Renders a navigation section on the
|
||||||
top.
|
top.
|
||||||
"""
|
"""
|
||||||
nav_days = models.SmallIntegerField(
|
nav_days = models.SmallIntegerField(
|
||||||
|
@ -316,29 +341,32 @@ class BaseDatedList(models.Model):
|
||||||
# Sections
|
# Sections
|
||||||
#
|
#
|
||||||
@register_snippet
|
@register_snippet
|
||||||
class Menu(ClusterableModel):
|
class Section(ClusterableModel):
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
_('name'),
|
_('name'),
|
||||||
max_length=32,
|
max_length=32,
|
||||||
blank = True, null = True,
|
blank = True, null = True,
|
||||||
help_text=_('name of this menu (not displayed)'),
|
help_text=_('name of this section (not displayed)'),
|
||||||
)
|
)
|
||||||
css_class = models.CharField(
|
css_class = models.CharField(
|
||||||
_('CSS class'),
|
_('CSS class'),
|
||||||
max_length=64,
|
max_length=64,
|
||||||
blank = True, null = True,
|
blank = True, null = True,
|
||||||
help_text=_('menu container\'s "class" attribute')
|
help_text=_('section container\'s "class" attribute')
|
||||||
)
|
)
|
||||||
related = models.ForeignKey(
|
related = models.ForeignKey(
|
||||||
ContentType,
|
ContentType,
|
||||||
blank = True, null = True,
|
blank = True, null = True,
|
||||||
help_text=_('this menu is displayed only for this model')
|
help_text=_('this section is displayed only for this model'),
|
||||||
|
#limit_choices_to = {
|
||||||
|
# 'page__isnull': False
|
||||||
|
#}
|
||||||
)
|
)
|
||||||
position = models.CharField(
|
position = models.CharField(
|
||||||
_('position'),
|
_('position'),
|
||||||
max_length=16,
|
max_length=16,
|
||||||
blank = True, null = True,
|
blank = True, null = True,
|
||||||
help_text = _('name of the template block in which the menu must '
|
help_text = _('name of the template block in which the section must '
|
||||||
'be set'),
|
'be set'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -351,34 +379,22 @@ class Menu(ClusterableModel):
|
||||||
FieldPanel('related'),
|
FieldPanel('related'),
|
||||||
FieldPanel('position'),
|
FieldPanel('position'),
|
||||||
], heading=_('Position')),
|
], heading=_('Position')),
|
||||||
InlinePanel('menu_items', label=_('menu items')),
|
InlinePanel('section_items', label=_('section items')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{}: {}'.format(self.__class__.__name__, self.name or self.pk)
|
||||||
|
|
||||||
@register_snippet
|
|
||||||
class MenuItem(models.Model):
|
|
||||||
menu = ParentalKey(Menu, related_name='menu_items')
|
|
||||||
real_type = models.CharField(
|
|
||||||
max_length=32,
|
|
||||||
blank = True, null = True,
|
|
||||||
)
|
|
||||||
title = models.CharField(
|
|
||||||
_('title'),
|
|
||||||
max_length=32,
|
|
||||||
blank = True, null = True,
|
|
||||||
)
|
|
||||||
css_class = models.CharField(
|
|
||||||
_('CSS class'),
|
|
||||||
max_length=64,
|
|
||||||
blank = True, null = True,
|
|
||||||
help_text=_('menu container\'s "class" attribute')
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
class SectionItemItem(Orderable):
|
||||||
|
section = ParentalKey(Section, related_name='section_items')
|
||||||
|
item = models.ForeignKey(
|
||||||
|
'SectionItem',
|
||||||
|
verbose_name=_('item')
|
||||||
|
)
|
||||||
panels = [
|
panels = [
|
||||||
MultiFieldPanel([
|
SnippetChooserPanel('item'),
|
||||||
FieldPanel('name'),
|
|
||||||
FieldPanel('css_class'),
|
|
||||||
], heading=_('General')),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def specific(self):
|
def specific(self):
|
||||||
|
@ -390,11 +406,77 @@ class MenuItem(models.Model):
|
||||||
return self
|
return self
|
||||||
return getattr(self, self.real_type)
|
return getattr(self, self.real_type)
|
||||||
|
|
||||||
def save(self, make_safe = True, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if type(self) != MenuItem and not self.real_type:
|
#if type(self) != SectionItem and not self.real_type:
|
||||||
self.real_type = type(self).__name__.lower()
|
# self.real_type = type(self).__name__.lower()
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{}: {}'.format(self.__class__.__name__, self.title or self.pk)
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionItem(models.Model):
|
||||||
|
real_type = models.CharField(
|
||||||
|
max_length=32,
|
||||||
|
blank = True, null = True,
|
||||||
|
)
|
||||||
|
title = models.CharField(
|
||||||
|
_('title'),
|
||||||
|
max_length=32,
|
||||||
|
blank = True, null = True,
|
||||||
|
)
|
||||||
|
show_title = models.BooleanField(
|
||||||
|
_('show title'),
|
||||||
|
default = False,
|
||||||
|
help_text=_('if set show a title at the head of the section'),
|
||||||
|
)
|
||||||
|
css_class = models.CharField(
|
||||||
|
_('CSS class'),
|
||||||
|
max_length=64,
|
||||||
|
blank = True, null = True,
|
||||||
|
help_text=_('section container\'s "class" attribute')
|
||||||
|
)
|
||||||
|
panels = [
|
||||||
|
MultiFieldPanel([
|
||||||
|
FieldPanel('title'),
|
||||||
|
FieldPanel('show_title'),
|
||||||
|
FieldPanel('css_class'),
|
||||||
|
], heading=_('General')),
|
||||||
|
]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{}: {}'.format(self.__class__.__name__, self.title or self.pk)
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionText(SectionItem):
|
||||||
|
body = RichTextField()
|
||||||
|
panels = SectionItem.panels + [
|
||||||
|
FieldPanel('body'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionImage(SectionItem):
|
||||||
|
image = models.ForeignKey(
|
||||||
|
'wagtailimages.Image',
|
||||||
|
verbose_name = _('image'),
|
||||||
|
related_name='+',
|
||||||
|
)
|
||||||
|
panels = SectionItem.panels + [
|
||||||
|
ImageChooserPanel('image'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionLink(BaseRelatedLink,SectionItem):
|
||||||
|
panels = SectionItem.panels + BaseRelatedLink.panels
|
||||||
|
|
||||||
|
|
||||||
|
@register_snippet
|
||||||
|
class SectionPublicationList(BaseList,SectionItem):
|
||||||
|
panels = SectionItem.panels + BaseList.panels
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user