Example #1
0
class GlobalStreamBlock(StreamBlock):
    paragraph = RichTextBlock(icon="pilcrow", template="blocks/paragraph.html")
    header = StructBlock([
        ('header_text', CharBlock(blank=True, required=False, label='Header')),
        ('size',
         ChoiceBlock(choices=[('', 'Select a header size'), ('h2', 'H2'),
                              ('h3', 'H3'), ('h4', 'H4')],
                     blank=True,
                     required=False))
    ],
                         classname="title",
                         icon="title",
                         template="blocks/header.html")
    image = StructBlock([('image', ImageChooserBlock()),
                         ('caption', CharBlock(blank=True, required=False)),
                         ('style',
                          ChoiceBlock(choices=[('', 'Select an image size'),
                                               ('full', 'Full-width'),
                                               ('contain', 'Contained-width'),
                                               ('half', 'Half-width')],
                                      required=False))],
                        icon="image",
                        template="blocks/image.html")
    blockquote = StructBlock([
        ('text', TextBlock()),
        ('attribute_name',
         CharBlock(blank=True, required=False, label='e.g. Guy Picciotto')),
        ('attribute_group',
         CharBlock(blank=True, required=False, label='e.g. Fugazi')),
    ],
                             icon="openquote",
                             template="blocks/blockquote.html")
    embed = EmbedBlock(
        help_text=
        'Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks')
Example #2
0
class DefinitionListBlock(ContentBlock):
    definitions = ListBlock(
        StructBlock([('title', CharBlock()), ('definition', CharBlock())]))

    class Meta:
        icon = 'tag'
        template = 'blocks/definition_list.html'
Example #3
0
class NavigationSettings(BaseSetting, ClusterableModel):
    header_links = StreamField([
        ('item', OverrideablePageChooserBlock()),
    ],
                               blank=True)
    footer_links = StreamField([
        ('column',
         StructBlock([
             ('column_heading', TextBlock()),
             ('subitems',
              ListBlock(OverrideablePageChooserBlock(label="Sub-item"))),
         ])),
    ],
                               blank=True)
    footer_secondary_links = StreamField([
        ('item', OverrideablePageChooserBlock()),
    ],
                                         blank=True)

    panels = [
        StreamFieldPanel('header_links'),
        StreamFieldPanel('footer_links'),
        StreamFieldPanel('footer_secondary_links'),
    ]

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        purge_esi()

    def delete(self, *args, **kwargs):
        super().delete(*args, **kwargs)
        purge_esi()
Example #4
0
class SkillbarBlock(ContentBlock):

    skills = ListBlock(
        StructBlock([('skill_percentage', CharBlock()),
                     ('skill_name', CharBlock())]))

    class Meta:
        icon = 'form'
        template = 'blocks/skillbar.html'
Example #5
0
class OrderedListBlock(StructBlock):
    title = CharBlock(required=False)
    items = ListBlock(
        StructBlock([('title', CharBlock()), ('description', TextBlock())]))
    label = CharBlock(required=False)
    page = PageChooserBlock(required=False)

    class Meta:
        template = 'cms/blocks/ordered_list_block.html'
Example #6
0
class ImageListBlock(StructBlock):
    title = CharBlock(required=False)
    items = ListBlock(
        StructBlock([('title', CharBlock()), ('subtitle', CharBlock()),
                     ('description', RichTextBlock()),
                     ('image', ImageChooserBlock()),
                     ('page', PageChooserBlock(required=False))]))

    class Meta:
        template = 'cms/blocks/image_list_block.html'
Example #7
0
class Header(BaseSetting):
    links = StreamField([
        ('links', StructBlock([
            ('link', PageChooserBlock(required=True)),
            ('text', CharBlock(max_length=255)),
        ], blank=True, null=True))
    ], null=True)

    panels = [
        StreamFieldPanel('links')
    ]
Example #8
0
class ImageGridBlock(StructBlock):
    title = CharBlock(required=False)
    items = ListBlock(
        StructBlock([('image', ImageChooserBlock()),
                     ('url', URLBlock(required=False)),
                     ('page', PageChooserBlock(required=False))]))

    class Meta:
        help_text = '''
        Use either URL or page, if both are filled in URL takes precedence.'''
        template = 'cms/blocks/image_grid_block.html'
Example #9
0
class AccordionBlock(StructBlock):
    class Meta:
        icon = "arrow-down-big"
        template = "blocks/accordion_block.html"

    accordion_group_title = TextBlock(required=False, blank=True, default="")
    accordion_items = ListBlock(
        StructBlock([
            ('accordion_title', CharBlock(required=True)),
            ('accordion_content', RichTextBlock(required=True)),
        ]))
Example #10
0
class SimplifiedBlock(StreamBlock):
    paragraph = RichTextBlock(icon="pilcrow", template="blocks/paragraph.html")
    header = CharBlock(classname="title",
                       icon="fa-header",
                       template="blocks/h3.html")
    image = StructBlock([('image', ImageChooserBlock()),
                         ('caption', CharBlock(blank=True, required=False)),
                         ('style',
                          ChoiceBlock(choices=[('', 'Select an image size'),
                                               ('full', 'Full-width'),
                                               ('half', 'Half-width')],
                                      required=False))],
                        icon="image",
                        template="blocks/image.html")
    blockquote = StructBlock([
        ('text', TextBlock()),
        ('attribute_name',
         CharBlock(blank=True, required=False, label='e.g. Guy Picciotto')),
        ('attribute_group',
         CharBlock(blank=True, required=False, label='e.g. Fugazi')),
    ],
                             icon="openquote",
                             template="blocks/blockquote.html")
Example #11
0
class HeadingWithTextBlock(StructBlock):
    block_heading = CharBlock(required=True)
    style = ChoiceBlock(choices=[('white', 'White background'),
                                 ('community', 'Community background')],
                        required=True)

    items = ListBlock(
        StructBlock([
            ('heading', CharBlock(required=True)),
            ('text', RichTextBlock(required=True)),
        ]))

    read_more_button = ReadMoreButtonBlock(required=False)

    class Meta:
        image = 'pages/images/streamfield_blocks/heading_with_text.jpg'
        template = 'pages/streamfield_blocks/heading_with_text.html'
Example #12
0
class Stakeholders(StructBlock):
    block_heading = CharBlock(required=True)

    personas = ListBlock(
        StructBlock([
            ('image', ImageChooserBlock(required=True)),
            ('name', CharBlock(required=True)),
            ('position', CharBlock(required=True)),
            ('excerpt', TextBlock(required=True)),
        ]))

    file = DocumentChooserBlock(required=False)
    label = CharBlock(default="Find out more",
                      required=False,
                      label="Download button label")

    class Meta:
        image = 'pages/images/streamfield_blocks/team.jpg'
        template = 'pages/streamfield_blocks/stakeholders.html'
Example #13
0
class CustomPage(Page, index.Indexed):
    footer = ForeignKey('common.Footer',
                        default=DEFAULT_FOOTER_ID,
                        null=True,
                        blank=True,
                        on_delete=SET_NULL,
                        related_name='+')

    content = StreamField([
        ('appeal',
         StructBlock([
             ('icon',
              ChoiceBlock(required=True,
                          choices=[
                              ('none', 'none'),
                              ('flask', 'flask'),
                              ('group', 'group'),
                              ('laptop', 'laptop'),
                              ('sitemap', 'sitemap'),
                              ('user', 'user'),
                              ('book', 'book'),
                              ('download', 'download'),
                          ])),
             ('topic', CharBlock(required=True, max_length=35)),
             ('content', RichTextBlock(required=True)),
         ],
                     classname='appeal',
                     icon='tick',
                     template='common/blocks/appeal.html')),
        ('heading', CharBlock(classname="full title")),
        ('statement', CharBlock()),
        ('paragraph', RichTextBlock()),
        ('imagechooser', ImageChooserBlock()),
        ('column', RowBlock()),
        ('tabs', TabsBlock()),
        ('image', ImageBlock()),
        ('customImage', CustomImageBlock()),
        ('rich_text', RichTextBlock()),
        ('raw_html',
         RawHTMLBlock(
             help_text=
             'With great power comes great responsibility. This HTML is unescaped. Be careful!'
         )),
        ('people_block', PeopleBlock()),
        ('centered_text', CenteredTextBlock()),
        ('hero_block', HeroBlock()),
        ('spotlight_block', SpotlightBlock()),
        ('job_whole_block', JobsWholeBlock()),
        ('embed_block', EmbedBlock()),
        ('whitespaceblock', WhitespaceBlock()),
        ('clear_fixblock', ClearfixBlock()),
        ('code_block', CodeBlock()),
        ('table_block', CustomTableBlock()),
        ('calender_block', GoogleCalendarBlock()),
        ('journal_block', JournalsTabBlock()),
        ('render_file', MfrBlock()),
        ('sponsor_partner_block', SponsorPartnerBlock()),
        ('collapse_block', CollapseBoxBlock()),
        ('button', ButtonBlock()),
    ],
                          null=True,
                          blank=True)

    custom_url = CharField(max_length=256, default='', null=True, blank=True)

    menu_order = IntegerField(
        blank=True,
        default=1,
        help_text=(
            'The order this page should appear in the menu. '
            'The lower the number, the more left the page will appear. '
            'This is required for all pages where "Show in menus" is checked.'
        ))

    search_fields = [
        index.SearchField('content', partial_match=True),
    ]

    content_panels = Page.content_panels + [
        StreamFieldPanel('content'),
        SnippetChooserPanel('footer'),
    ]

    promote_panels = Page.promote_panels + [
        FieldPanel('custom_url'),
        FieldPanel('menu_order'),
        InlinePanel('versioned_redirects', label='URL Versioning'),
    ]

    def serve(self, request):
        return render(
            request, self.template, {
                'page': self,
                'people': Person.objects.all(),
                'jobs': Job.objects.all(),
                'journals': Journal.objects.all(),
                'organizations': Organization.objects.all(),
                'donations': Donation.objects.all(),
                'inkinddonations': InkindDonation.objects.all(),
            })

    @transaction.atomic  # only commit when all descendants are properly updated
    def move(self, target, pos=None):
        """
        Extension to the treebeard 'move' method to ensure that url_path is updated too.
        """
        old_url_path = Page.objects.get(id=self.id).url_path
        super(Page, self).move(target, pos=pos)
        # treebeard's move method doesn't actually update the in-memory instance, so we need to work
        # with a freshly loaded one now
        new_self = Page.objects.get(id=self.id)
        new_url_path = new_self.set_url_path(new_self.get_parent())
        new_self.save()
        new_self._update_descendant_url_paths(old_url_path, new_url_path)
        new_redirect = new_self.versioned_redirects.create()
        redirect_url = ('/' + '/'.join(old_url_path.split('/')[2:]))[:-1]
        new_redirect.old_path = redirect_url
        new_redirect.redirect_page = new_self
        new_redirect.site = new_self.get_site()
        new_redirect.save()
        new_self.redirect_set.add(new_redirect)

        # Log
        logger.info("Page moved: \"%s\" id=%d path=%s", self.title, self.id,
                    new_url_path)

    @transaction.atomic
    # ensure that changes are only committed when we have updated all descendant URL paths, to preserve consistency
    def save(self, *args, **kwargs):
        self.full_clean()

        update_descendant_url_paths = False
        is_new = self.id is None

        if is_new:
            # we are creating a record. If we're doing things properly, this should happen
            # through a treebeard method like add_child, in which case the 'path' field
            # has been set and so we can safely call get_parent
            self.set_url_path(self.get_parent())
        else:
            # Check that we are committing the slug to the database
            # Basically: If update_fields has been specified, and slug is not included, skip this step
            if not ('update_fields' in kwargs
                    and 'slug' not in kwargs['update_fields']):
                # see if the slug has changed from the record in the db, in which case we need to
                # update url_path of self and all descendants
                old_record = Page.objects.get(id=self.id)
                if old_record.slug != self.slug:
                    self.set_url_path(self.get_parent())
                    update_descendant_url_paths = True
                    old_url_path = old_record.url_path
                    new_url_path = self.url_path
                    new_redirect = self.versioned_redirects.create()
                    redirect_url = ('/' +
                                    '/'.join(old_url_path.split('/')[2:]))[:-1]
                    new_redirect.old_path = redirect_url
                    new_redirect.redirect_page = self
                    new_redirect.site = self.get_site()
                    new_redirect.save()
                    self.redirect_set.add(new_redirect)

        for redirect in self.versioned_redirects.all():
            redirect.versioned_redirect_page = self
            redirect.redirect_page = self
            redirect.save()

        result = super(Page, self).save(*args, **kwargs)

        if update_descendant_url_paths:
            self._update_descendant_url_paths(old_url_path, new_url_path)

        # Check if this is a root page of any sites and clear the 'wagtail_site_root_paths' key if so
        if Site.objects.filter(root_page=self).exists():
            cache.delete('wagtail_site_root_paths')

        # Log
        if is_new:
            cls = type(self)
            logger.info(
                "Page created: \"%s\" id=%d content_type=%s.%s path=%s",
                self.title, self.id, cls._meta.app_label, cls.__name__,
                self.url_path)

        return result