issue#1: synchronise automatically station and programs from db. For station generate a set of usual desired pages.
This commit is contained in:
		@ -82,7 +82,7 @@ class ProgramAdmin(NameableAdmin):
 | 
			
		||||
    schedule.short_description = _("Schedule")
 | 
			
		||||
 | 
			
		||||
    list_display = ('id', 'name', 'active', 'schedule')
 | 
			
		||||
    fields = NameableAdmin.fields + [ 'active' ]
 | 
			
		||||
    fields = NameableAdmin.fields + [ 'active', 'station' ]
 | 
			
		||||
    # TODO list_display
 | 
			
		||||
    inlines = [ ScheduleInline, StreamInline ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -292,7 +292,7 @@ class Program(Nameable):
 | 
			
		||||
    active = models.BooleanField(
 | 
			
		||||
        _('active'),
 | 
			
		||||
        default = True,
 | 
			
		||||
        help_text = _('if not set this program is no longer active')
 | 
			
		||||
        help_text = _('if not checked this program is no longer active')
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ from django.core.exceptions import ValidationError
 | 
			
		||||
 | 
			
		||||
from honeypot.decorators import verify_honeypot_value
 | 
			
		||||
 | 
			
		||||
import aircox.cms.models as models
 | 
			
		||||
import aircox_cms.models as models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CommentForm(forms.ModelForm):
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ class Command (BaseCommand):
 | 
			
		||||
 | 
			
		||||
            # programs
 | 
			
		||||
            logger.info('Programs...')
 | 
			
		||||
            parent = settings.default_program_parent_page
 | 
			
		||||
            parent = settings.default_programs_page
 | 
			
		||||
            qs = Program.objects.filter(
 | 
			
		||||
                active = True,
 | 
			
		||||
                stream__isnull = True,
 | 
			
		||||
 | 
			
		||||
@ -33,11 +33,22 @@ import aircox_cms.settings as settings
 | 
			
		||||
from aircox_cms.utils import image_url
 | 
			
		||||
from aircox_cms.sections import *
 | 
			
		||||
 | 
			
		||||
import aircox_cms.signals
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@register_setting
 | 
			
		||||
class WebsiteSettings(BaseSetting):
 | 
			
		||||
    # TODO: #Station assign a website to a aircox.models.model.station when it will
 | 
			
		||||
    #   exist. Update all dependent code such as signal handling
 | 
			
		||||
    station = models.OneToOneField(
 | 
			
		||||
        aircox.models.Station,
 | 
			
		||||
        verbose_name = _('aircox station'),
 | 
			
		||||
        related_name = 'website_settings',
 | 
			
		||||
        unique = True,
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'refers to an Aircox\'s station; it is used to make the link '
 | 
			
		||||
            'between the website and Aircox'
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # general website information
 | 
			
		||||
    favicon = models.ImageField(
 | 
			
		||||
@ -58,11 +69,12 @@ class WebsiteSettings(BaseSetting):
 | 
			
		||||
        help_text = _('public description of the website; used for referencing'),
 | 
			
		||||
    )
 | 
			
		||||
    list_page = models.ForeignKey(
 | 
			
		||||
        'aircox_cms.GenericPage',
 | 
			
		||||
        'aircox_cms.DynamicListPage',
 | 
			
		||||
        verbose_name = _('page for lists'),
 | 
			
		||||
        help_text=_('page used to display the results of a search and other '
 | 
			
		||||
                    'lists'),
 | 
			
		||||
        related_name= 'list_page'
 | 
			
		||||
        related_name= 'list_page',
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
    )
 | 
			
		||||
    # comments
 | 
			
		||||
    accept_comments = models.BooleanField(
 | 
			
		||||
@ -76,36 +88,50 @@ class WebsiteSettings(BaseSetting):
 | 
			
		||||
    comment_success_message = models.TextField(
 | 
			
		||||
        _('success message'),
 | 
			
		||||
        default = _('Your comment has been successfully posted!'),
 | 
			
		||||
        help_text = _('message to display when a post has been posted'),
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'message displayed when a comment has been successfully posted'
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
    comment_wait_message = models.TextField(
 | 
			
		||||
        _('waiting message'),
 | 
			
		||||
        default = _('Your comment is awaiting for approval.'),
 | 
			
		||||
        help_text = _('message to display when a post waits to be reviewed'),
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'message displayed when a comment has been sent, but waits for '
 | 
			
		||||
            ' website administrators\' approval.'
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
    comment_error_message = models.TextField(
 | 
			
		||||
        _('error message'),
 | 
			
		||||
        default = _('We could not save your message. Please correct the error(s) below.'),
 | 
			
		||||
        help_text = _('message to display there is an error an incomplete form.'),
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'message displayed when the form of the comment has been '
 | 
			
		||||
            ' submitted but there is an error, such as an incomplete field'
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    auto_create = models.BooleanField(
 | 
			
		||||
        _('automatic publications'),
 | 
			
		||||
    sync = models.BooleanField(
 | 
			
		||||
        _('synchronize with Aircox'),
 | 
			
		||||
        default = False,
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'Create automatically new publications for new programs and '
 | 
			
		||||
            'diffusions in the timetable. If set, please complete other '
 | 
			
		||||
            'options of this panel'
 | 
			
		||||
            'create publication for each object added to an Aircox\'s '
 | 
			
		||||
            'station; for example when there is a new program, or '
 | 
			
		||||
            'when a diffusion has been added to the timetable. Note: '
 | 
			
		||||
            'it does not concern the Station themselves.'
 | 
			
		||||
            # /doc/ the page is saved but not pubished -- this must be
 | 
			
		||||
            # done manually, when the user edit it.
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    default_program_parent_page = ParentalKey(
 | 
			
		||||
    default_programs_page = ParentalKey(
 | 
			
		||||
        Page,
 | 
			
		||||
        verbose_name = _('default program parent page'),
 | 
			
		||||
        verbose_name = _('default programs page'),
 | 
			
		||||
        blank = True, null = True,
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'Default parent page for program\'s pages. It is used to assign '
 | 
			
		||||
            'a page to the publication of a newly created program and can '
 | 
			
		||||
            'be changed later'
 | 
			
		||||
            'when a new program is saved and a publication is created, '
 | 
			
		||||
            'put this publication as a child of this page. If no page '
 | 
			
		||||
            'has been specified, try to put it as the child of the '
 | 
			
		||||
            'website\'s root page (otherwise, do not create the page).'
 | 
			
		||||
            # /doc/ (technicians, admin): if the page has not been created,
 | 
			
		||||
            # it still can be created using the `programs_to_cms` command.
 | 
			
		||||
        ),
 | 
			
		||||
        limit_choices_to = lambda: {
 | 
			
		||||
            'show_in_menus': True,
 | 
			
		||||
@ -119,7 +145,7 @@ class WebsiteSettings(BaseSetting):
 | 
			
		||||
            FieldPanel('tags'),
 | 
			
		||||
            FieldPanel('description'),
 | 
			
		||||
            FieldPanel('list_page'),
 | 
			
		||||
        ], heading=_('promotion')),
 | 
			
		||||
        ], heading=_('Promotion')),
 | 
			
		||||
        MultiFieldPanel([
 | 
			
		||||
            FieldPanel('allow_comments'),
 | 
			
		||||
            FieldPanel('accept_comments'),
 | 
			
		||||
@ -128,8 +154,8 @@ class WebsiteSettings(BaseSetting):
 | 
			
		||||
            FieldPanel('comment_error_message'),
 | 
			
		||||
        ], heading = _('Comments')),
 | 
			
		||||
        MultiFieldPanel([
 | 
			
		||||
            FieldPanel('auto_create'),
 | 
			
		||||
            FieldPanel('default_program_parent_page'),
 | 
			
		||||
            FieldPanel('sync'),
 | 
			
		||||
            FieldPanel('default_programs_page'),
 | 
			
		||||
        ], heading = _('Programs and controls')),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -559,46 +585,38 @@ class DiffusionPage(Publication):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Other type of pages
 | 
			
		||||
# Others types of pages
 | 
			
		||||
#
 | 
			
		||||
class GenericPage(Page):
 | 
			
		||||
class DynamicListPage(Page):
 | 
			
		||||
    """
 | 
			
		||||
    Page for simple lists, query is done though request' GET fields.
 | 
			
		||||
    Look at get_queryset for more information.
 | 
			
		||||
    Displays a list of publications using query passed by the url.
 | 
			
		||||
    This can be used for search/tags page, and generally only one
 | 
			
		||||
    page is used per website.
 | 
			
		||||
 | 
			
		||||
    If a title is given, use it instead of the generated one.
 | 
			
		||||
    """
 | 
			
		||||
    # FIXME/TODO: title in template <title></title>
 | 
			
		||||
    body = RichTextField(
 | 
			
		||||
        _('body'),
 | 
			
		||||
        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 = _('Generic Page')
 | 
			
		||||
        verbose_name_plural = _('Generic Page')
 | 
			
		||||
        verbose_name = _('Dynamic List Page')
 | 
			
		||||
        verbose_name_plural = _('Dynamic List Pages')
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
        qs = ListBase.from_request(request, context=context)
 | 
			
		||||
        context['object_list'] = qs
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -647,6 +665,7 @@ class DatedListPage(DatedListBase,Page):
 | 
			
		||||
class LogsPage(DatedListPage):
 | 
			
		||||
    template = 'aircox_cms/dated_list_page.html'
 | 
			
		||||
 | 
			
		||||
    # TODO: make it a property that automatically select the station
 | 
			
		||||
    station = models.ForeignKey(
 | 
			
		||||
        aircox.models.Station,
 | 
			
		||||
        verbose_name = _('station'),
 | 
			
		||||
 | 
			
		||||
@ -176,8 +176,10 @@ class ListBase(models.Model):
 | 
			
		||||
    siblings = models.BooleanField(
 | 
			
		||||
        verbose_name = _('select siblings of related'),
 | 
			
		||||
        default = False,
 | 
			
		||||
        help_text = _('if selected select related publications that are '
 | 
			
		||||
                      'siblings of this one'),
 | 
			
		||||
        help_text = _(
 | 
			
		||||
            'if checked, related publications are siblings instead of '
 | 
			
		||||
            'the children.'
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
    asc = models.BooleanField(
 | 
			
		||||
        verbose_name = _('ascending order'),
 | 
			
		||||
@ -200,7 +202,6 @@ class ListBase(models.Model):
 | 
			
		||||
        ], heading=_('sorting'))
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
        """
 | 
			
		||||
        Get queryset based on the arguments. This class is intended to be
 | 
			
		||||
@ -223,8 +224,8 @@ class ListBase(models.Model):
 | 
			
		||||
            else:
 | 
			
		||||
                qs = qs.descendant_of(related)
 | 
			
		||||
 | 
			
		||||
            date = self.related.date if hasattr(related, 'date') else \
 | 
			
		||||
                    self.related.first_published_at
 | 
			
		||||
            date = related.date if hasattr(related, 'date') else \
 | 
			
		||||
                    related.first_published_at
 | 
			
		||||
            if self.date_filter == self.DateFilter.before_related:
 | 
			
		||||
                qs = qs.filter(date__lt = date)
 | 
			
		||||
            elif self.date_filter == self.DateFilter.after_related:
 | 
			
		||||
@ -247,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 GenericPage it finds.
 | 
			
		||||
        given list_page or the first DynamicListPage it finds.
 | 
			
		||||
        """
 | 
			
		||||
        import aircox_cms.models as models
 | 
			
		||||
 | 
			
		||||
@ -261,7 +262,7 @@ class ListBase(models.Model):
 | 
			
		||||
        params.update(kwargs)
 | 
			
		||||
 | 
			
		||||
        page = params.get('related') or list_page or \
 | 
			
		||||
                models.GenericPage.objects.all().first()
 | 
			
		||||
                models.DynamicListPage.objects.all().first()
 | 
			
		||||
 | 
			
		||||
        if params.get('related'):
 | 
			
		||||
            params['related'] = True
 | 
			
		||||
@ -483,9 +484,6 @@ class Section(ClusterableModel):
 | 
			
		||||
        InlinePanel('places', label=_('Section Items')),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return '{}: {}'.format(self.__class__.__name__, self.name or self.pk)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_sections_at (cl, position, page = None):
 | 
			
		||||
        """
 | 
			
		||||
@ -503,22 +501,40 @@ class Section(ClusterableModel):
 | 
			
		||||
            )
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
    def add_item(self, item):
 | 
			
		||||
        """
 | 
			
		||||
        Add an item to the section. Automatically save the item and
 | 
			
		||||
        create the corresponding SectionPlace.
 | 
			
		||||
        """
 | 
			
		||||
        # TODO: arbitrary position; Orderable.sort_order?
 | 
			
		||||
        item.save()
 | 
			
		||||
        place, created = SectionPlace.objects.get_or_create(
 | 
			
		||||
            section = self,
 | 
			
		||||
            item = item,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def render(self, request, page = None, context = None, *args, **kwargs):
 | 
			
		||||
        return ''.join([
 | 
			
		||||
            place.item.specific.render(request, page, context, *args, **kwargs)
 | 
			
		||||
            for place in self.places.all()
 | 
			
		||||
        ])
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return '{}: {}'.format(self.__class__.__name__, self.name or self.pk)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SectionPlace(Orderable):
 | 
			
		||||
    section = ParentalKey(Section, related_name='places')
 | 
			
		||||
    item = models.ForeignKey(
 | 
			
		||||
        'SectionItem',
 | 
			
		||||
        verbose_name=_('item')
 | 
			
		||||
        verbose_name=_('item'),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    panels = [ SnippetChooserPanel('item'), ]
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        unique_together = ('section', 'item')
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return '{}: {}'.format(self.__class__.__name__, self.title or self.pk)
 | 
			
		||||
 | 
			
		||||
@ -954,7 +970,8 @@ class SectionSearchField(SectionItem):
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def get_context(self, request, page):
 | 
			
		||||
        from aircox_cms.models import GenericPage
 | 
			
		||||
        # FIXME ?????
 | 
			
		||||
        from aircox_cms.models import DynamicListPage
 | 
			
		||||
        context = super().get_context(request, page)
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,134 @@
 | 
			
		||||
from django.db.models.signals import post_save
 | 
			
		||||
from django.dispatch import receiver
 | 
			
		||||
from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
from django.contrib.contenttypes.models import ContentType
 | 
			
		||||
 | 
			
		||||
import aircox.models
 | 
			
		||||
from wagtail.wagtailcore.models import Page, Site
 | 
			
		||||
 | 
			
		||||
import aircox.models as aircox
 | 
			
		||||
import aircox_cms.utils as utils
 | 
			
		||||
 | 
			
		||||
# on a new diffusion
 | 
			
		||||
 | 
			
		||||
@receiver(post_save, sender=aircox.Station)
 | 
			
		||||
def station_post_saved(sender, instance, created, *args, **kwargs):
 | 
			
		||||
    """
 | 
			
		||||
    Create the basis for the website: set up settings and pages
 | 
			
		||||
    that are common.
 | 
			
		||||
    """
 | 
			
		||||
    from aircox_cms.models import \
 | 
			
		||||
            WebsiteSettings, Publication, ProgramPage, \
 | 
			
		||||
            TimetablePage, DynamicListPage, LogsPage
 | 
			
		||||
    import aircox_cms.sections as sections
 | 
			
		||||
    if not created:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    root_page = Page.objects.get(id=1)
 | 
			
		||||
 | 
			
		||||
    homepage = Publication(
 | 
			
		||||
        title = instance.name,
 | 
			
		||||
        slug = instance.slug,
 | 
			
		||||
        body = _(
 | 
			
		||||
            'If you see this page, then Aircox is running for the station '
 | 
			
		||||
            '{station.name}. You might want to change it to a better one. '
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
    root_page.add_child(instance=homepage)
 | 
			
		||||
 | 
			
		||||
    site = Site(
 | 
			
		||||
        # /doc/ when a Station is created, a wagtail Site is generated with
 | 
			
		||||
        #       default options. User must set the correct localhost afterwards
 | 
			
		||||
        hostname = instance.slug + ".local",
 | 
			
		||||
        port = 80,
 | 
			
		||||
        site_name = instance.name.capitalize(),
 | 
			
		||||
        root_page = homepage,
 | 
			
		||||
    )
 | 
			
		||||
    site.save()
 | 
			
		||||
 | 
			
		||||
    # settings
 | 
			
		||||
    website_settings = WebsiteSettings(
 | 
			
		||||
        site = site,
 | 
			
		||||
        station = instance,
 | 
			
		||||
        description = _("The website of the {name} radio").format(
 | 
			
		||||
            name = instance.name
 | 
			
		||||
        ),
 | 
			
		||||
        # Translators: tags set by default in <meta> description of the website
 | 
			
		||||
        tags = _('radio,{station.name}').format(station = instance)
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # timetable
 | 
			
		||||
    timetable = TimetablePage(
 | 
			
		||||
        title = _('Timetable'),
 | 
			
		||||
    )
 | 
			
		||||
    homepage.add_child(instance = timetable)
 | 
			
		||||
 | 
			
		||||
    # list page (search, terms)
 | 
			
		||||
    list_page = DynamicListPage(
 | 
			
		||||
        # title is dynamic: no need to specify
 | 
			
		||||
        title = _('Search'),
 | 
			
		||||
    )
 | 
			
		||||
    homepage.add_child(instance = list_page)
 | 
			
		||||
    website_settings.list_page = list_page
 | 
			
		||||
 | 
			
		||||
    # programs' page: list of programs in a section
 | 
			
		||||
    programs = Publication(
 | 
			
		||||
        title = _('Programs'),
 | 
			
		||||
    )
 | 
			
		||||
    homepage.add_child(instance = programs)
 | 
			
		||||
 | 
			
		||||
    section = sections.Section(
 | 
			
		||||
        name = _('Programs List'),
 | 
			
		||||
        position = 'post_content',
 | 
			
		||||
        page = programs,
 | 
			
		||||
    )
 | 
			
		||||
    section.save();
 | 
			
		||||
    section.add_item(sections.SectionList(
 | 
			
		||||
        count = 15,
 | 
			
		||||
        url_text = _('All programs'),
 | 
			
		||||
        model = ContentType.objects.get_for_model(ProgramPage),
 | 
			
		||||
        related = programs,
 | 
			
		||||
    ))
 | 
			
		||||
 | 
			
		||||
    website_settings.default_programs_page = programs
 | 
			
		||||
    website_settings.sync = True
 | 
			
		||||
 | 
			
		||||
    # logs (because it is a cool feature)
 | 
			
		||||
    logs = LogsPage(
 | 
			
		||||
        title = _('Previously on air'),
 | 
			
		||||
        station = instance,
 | 
			
		||||
    )
 | 
			
		||||
    homepage.add_child(instance = logs)
 | 
			
		||||
 | 
			
		||||
    # save
 | 
			
		||||
    site.save()
 | 
			
		||||
    website_settings.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@receiver(post_save, sender=programs.Program)
 | 
			
		||||
def on_new_program(sender, instance, created, *args):
 | 
			
		||||
@receiver(post_save, sender=aircox.Program)
 | 
			
		||||
def program_post_saved(sender, instance, created, *args, **kwargs):
 | 
			
		||||
    import aircox_cms.models as models
 | 
			
		||||
    if not created or instance.page.count():
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    settings = utils.get_station_settings(instance.station)
 | 
			
		||||
    if not settings or not settings.sync:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    parent = settings.default_programs_page or \
 | 
			
		||||
             settings.site.root_page
 | 
			
		||||
    if not parent:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    page = models.ProgramPage(
 | 
			
		||||
        program = instance,
 | 
			
		||||
        title = instance.name,
 | 
			
		||||
        live = False,
 | 
			
		||||
        # Translators: default content of a page for program
 | 
			
		||||
        body = _('{program.name} is a program on {station.name}.').format(
 | 
			
		||||
            program = instance,
 | 
			
		||||
            station = instance.station
 | 
			
		||||
        )
 | 
			
		||||
    )
 | 
			
		||||
    parent.add_child(instance = page)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,8 +12,8 @@
 | 
			
		||||
    <head>
 | 
			
		||||
        <meta charset="utf-8">
 | 
			
		||||
        <meta name="application-name" content="aircox-cms">
 | 
			
		||||
        <meta name="description" content="{{ settings.cms.WebsiteSettings.description }}">
 | 
			
		||||
        <meta name="keywords" content="{{ page.tags.all|default:settings.cms.WebsiteSettings.tags }}">
 | 
			
		||||
        <meta name="description" content="{{ settings.aircox_cms.WebsiteSettings.description }}">
 | 
			
		||||
        <meta name="keywords" content="{{ page.tags.all|default:settings.aircox_cms.WebsiteSettings.tags }}">
 | 
			
		||||
 | 
			
		||||
        {% with favicon=settings.cms.WebsiteSettings.favicon %}
 | 
			
		||||
            <link rel="icon" href="{{ favicon.url }}" />
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										54
									
								
								aircox_cms/templates/aircox_cms/dynamic_list_page.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								aircox_cms/templates/aircox_cms/dynamic_list_page.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
{% extends "aircox_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 #}
 | 
			
		||||
{% 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 %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
</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 "aircox_cms/snippets/list.html" %}
 | 
			
		||||
        {% endwith %}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
{% endwith %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,61 +0,0 @@
 | 
			
		||||
{% extends "aircox_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 "aircox_cms/snippets/list.html" %}
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
{% else %}
 | 
			
		||||
    <div class="body">
 | 
			
		||||
    {{ page.body|richtext }}
 | 
			
		||||
    </div>
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -57,4 +57,3 @@
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,9 +2,20 @@
 | 
			
		||||
from django.core.urlresolvers import reverse
 | 
			
		||||
from wagtail.wagtailimages.utils import generate_signature
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def image_url(image, filter_spec):
 | 
			
		||||
    signature = generate_signature(image.id, filter_spec)
 | 
			
		||||
    url = reverse('wagtailimages_serve', args=(signature, image.id, filter_spec))
 | 
			
		||||
    url += image.file.name[len('original_images/'):]
 | 
			
		||||
    return url
 | 
			
		||||
 | 
			
		||||
def get_station_settings(station):
 | 
			
		||||
    import aircox_cms.models as models
 | 
			
		||||
    return models.WebsiteSettings.objects \
 | 
			
		||||
                 .filter(station = station).first()
 | 
			
		||||
 | 
			
		||||
def get_station_site(station):
 | 
			
		||||
    settings = get_station_settings(station)
 | 
			
		||||
    return settings and settings.site
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								notes.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								notes.md
									
									
									
									
									
								
							@ -18,13 +18,16 @@ This file is used as a reminder, can be used as crappy documentation too.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Long term TODO
 | 
			
		||||
- debug/prod configuration
 | 
			
		||||
# To discuss / To think
 | 
			
		||||
- aircox_cms.signals: handle renaming of the program if the article's title has
 | 
			
		||||
    not been changed -> need to cache of the title at __init__
 | 
			
		||||
- ensure per station website for all generated publications
 | 
			
		||||
- aircox_cms: remove "station" fields when it is possible in the pages & sections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Long term TODO
 | 
			
		||||
programs:
 | 
			
		||||
    - sounds monitor: max_size of path, take in account
 | 
			
		||||
 | 
			
		||||
controllers:
 | 
			
		||||
    - archives can be set afterwards for rerun, so check must be done
 | 
			
		||||
        at the same time we monitor
 | 
			
		||||
    - logs: archive functionnality
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user