class TextAndButtonsBlock(blocks.StructBlock):
    text = blocks.TextBlock()
    buttons = blocks.ListBlock(ButtonBlock())
    mainbutton = ButtonBlock()

    graphql_fields = [
        GraphQLString("text"),
        GraphQLImage("image"),
        GraphQLStreamfield("buttons"),
        GraphQLStreamfield(
            "mainbutton", is_list=False
        ),  # this is a direct StructBlock, not a list of sub-blocks
    ]
Exemple #2
0
class PrizePage(Page):
    introduction = models.TextField(help_text='Prize Home', blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')
    body = StreamField(BaseStreamBlock(),
                       verbose_name="Prize Page body",
                       blank=True)
    subtitle = models.CharField(blank=True, max_length=255)
    dict_word_count = models.PositiveIntegerField(null=True, editable=False)
    prize_tags = ClusterTaggableManager(through=TaggedPrize, blank=True)
    date_published = models.DateField("Updated on", blank=True, null=True)

    linked_products = models.ManyToManyField('product.ProductPage', )

    content_panels = Page.content_panels + [
        FieldPanel('subtitle', classname="full"),
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
        StreamFieldPanel('body'),
        FieldPanel('date_published'),
        FieldPanel('prize_tags'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('body'),
    ]

    api_fields = [
        APIField('introduction'),
        APIField('body'),
        APIField('image'),
        APIField('date_published'),
    ]

    graphql_fields = [
        GraphQLString("introduction"),
        GraphQLStreamfield("body"),
        GraphQLStreamfield("date_published"),
    ]

    parent_page_types = ['PrizeIndexPage']
    subpage_types = []
Exemple #3
0
class ContentPage(TranslatablePageMixin, Page):
    LAYOUT_VALUES = (('col1', '1 Col'), )
    layout = models.CharField(_('Layout'),
                              max_length=20,
                              choices=LAYOUT_VALUES,
                              default="col1")
    body = StreamField([('heading', blocks.CharBlock(classname="full title")),
                        ('text',
                         blocks.RichTextBlock(features=[
                             'h2', 'bold', 'italic', 'ul', 'ol', 'link',
                             'image', 'document-link'
                         ]))])

    content_panels = [
        MultiFieldPanel([
            FieldPanel('layout'),
        ], heading=_('Meta')),
    ] + Page.content_panels + [
        StreamFieldPanel('body'),
    ]

    parent_page_types = ['basecms.HomePage']
    subpage_types = ['basecms.ContentPage']

    graphql_fields = [
        GraphQLString('title'),
        GraphQLString('layout'),
        GraphQLStreamfield('body'),
    ]
class StandardPage(BasePage):
    template = 'patterns/pages/standardpages/information_page.html'

    subpage_types = ['standardpages.StandardPage']

    introduction = models.TextField(blank=True)
    body = StreamField(StoryBlock())
    featured_image = models.ForeignKey('images.CustomImage',
                                       null=True,
                                       blank=True,
                                       related_name='+',
                                       on_delete=models.SET_NULL)
    featured_image_caption = models.CharField(
        blank=True,
        max_length=250,
    )
    biography = models.CharField(
        help_text="Use this field to override the author's biography "
        "on this page.",
        max_length=255,
        blank=True)

    search_fields = BasePage.search_fields + [
        index.SearchField('introduction'),
        index.SearchField('body'),
    ]

    content_panels = BasePage.content_panels + [
        FieldPanel('introduction'),
        MultiFieldPanel(
            [
                ImageChooserPanel('featured_image'),
                FieldPanel('featured_image_caption'),
            ],
            heading="Featured Image",
        ),
        StreamFieldPanel('body'),
        InlinePanel('authors', label="Authors"),
    ]

    # Export fields over REST API
    api_fields = [
        APIField('introduction'),
        APIField('body'),
        APIField('featured_image',
                 serializer=ImageRenditionField('fill-1920x1080')),
        APIField('featured_image_caption'),
    ]

    # Export fields over GraphQL
    graphql_fields = [
        GraphQLString("introduction"),
        GraphQLStreamfield("body"),
        GraphQLImage("featured_image"),
        GraphQLString("featured_image_caption"),
    ]

    class Meta:
        verbose_name = "Standard Page"
Exemple #5
0
class TextAndButtonsBlock(blocks.StructBlock):
    text = blocks.TextBlock()
    buttons = blocks.ListBlock(ButtonBlock())

    graphql_fields = [
        GraphQLString("text"),
        GraphQLImage("image"),
        GraphQLStreamfield("buttons"),
    ]
class BlogPage(GrapplePageMixin, Page):
    author = models.CharField(max_length=255)
    date = models.DateField("Post date")
    advert = models.ForeignKey('home.Advert',
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL,
                               related_name='+')
    cover = models.ForeignKey('wagtailimages.Image',
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name='+')
    book_file = models.ForeignKey('wagtaildocs.Document',
                                  null=True,
                                  blank=True,
                                  on_delete=models.SET_NULL,
                                  related_name='+')
    featured_media = models.ForeignKey('wagtailmedia.Media',
                                       null=True,
                                       blank=True,
                                       on_delete=models.SET_NULL,
                                       related_name='+')
    body = StreamField([
        ("heading", blocks.CharBlock(classname="full title")),
        ("paraagraph", blocks.RichTextBlock()),
        ("image", ImageChooserBlock()),
        ("decimal", blocks.DecimalBlock()),
        ("date", blocks.DateBlock()),
        ("datetime", blocks.DateTimeBlock()),
    ])

    content_panels = Page.content_panels + [
        FieldPanel("author"),
        FieldPanel("date"),
        ImageChooserPanel('cover'),
        StreamFieldPanel("body"),
        InlinePanel('related_links', label="Related links"),
        SnippetChooserPanel('advert'),
        DocumentChooserPanel('book_file'),
        MediaChooserPanel('featured_media'),
    ]

    graphql_fields = [
        GraphQLString("heading"),
        GraphQLString("date"),
        GraphQLString("author"),
        GraphQLStreamfield("body"),
        GraphQLForeignKey("related_links", "home.blogpagerelatedlink", True),
        GraphQLSnippet('advert', 'home.Advert'),
        GraphQLImage('cover'),
        GraphQLDocument('book_file'),
        GraphQLMedia('featured_media'),
    ]
class BlogPage(Page):
    """
    A model to extend wagtail page for a BlogPost object
    """
    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)
    body = RichTextField(blank=True)
    extra = StreamField([
        ('heading', blocks.CharBlock(classname="full title")),
        ('paragraph', blocks.RichTextBlock()),
        ('image', CloudinaryImageBlock()),
    ],
                        null=True)

    graphql_fields = [
        GraphQLString("date"),
        GraphQLString("body"),
        GraphQLStreamfield("extra"),
    ]

    api_fields = [
        APIField('body'),
        APIField('extra'),
        APIField('restricted'),
        APIField('extra', serializer=SecureStreamField()),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('intro'),
        FieldPanel('body', classname="full"),
        InlinePanel('gallery_images', label="Gallery images"),
        StreamFieldPanel('extra'),
    ]

    @property
    def restricted(self):
        return [r.restriction_type for r in self.get_view_restrictions()]

    def main_image(self):
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None
Exemple #8
0
class DictPage(Page):
    introduction = models.TextField(help_text='Dictionary Home', blank=True)
    image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL,
        related_name='+', help_text='Landscape mode only; horizontal width between 1000px and 3000px.')
    body = StreamField(BaseStreamBlock(), verbose_name="Dictionary Page body", blank=True)
    subtitle = models.CharField(blank=True, max_length=255)
    date_published = models.DateField("Date of Publication", blank=True, null=True)
    dict_word_count = models.PositiveIntegerField(null=True, editable=False)

    content_panels = Page.content_panels + [
        FieldPanel('subtitle', classname="full"),
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
        StreamFieldPanel('body'),
        FieldPanel('date_published'),
        InlinePanel('dict_person_relationship', label="Author(s)", panels=None, min_num=1), ]

    search_fields = Page.search_fields + [
        index.SearchField('body'),
    ]

    api_fields = [
        APIField('introduction'),
        APIField('date_published'),
        APIField('body'),
        APIField('image'),
        # APIField('authors'),  # This will nest the relevant BlogPageAuthor objects in the API response
    ]

    graphql_fields = [
        GraphQLString("introduction"),
        GraphQLString("date_published"),
        GraphQLStreamfield("body"),
        # GraphQLString("author"),
    ]

    def authors(self):
        """
        Returns the DictPage's related People.
        """
        authors = [n.people for n in self.dict_person_relationship.all()]
        return authors

    def set_body_word_count(self):
        pass

    parent_page_types = ['DictIndexPage']
    subpage_types = []
Exemple #9
0
class FlexPage(Page):
    """A flexible page class."""

    # template = "cms/pages/home_page.html"
    subpage_types = ['pages.FlexPage']

    headline = models.TextField(
        max_length=140, blank=True, null=True,
        help_text="An optional subtitle"
    )
    banner_image = models.ForeignKey(
        "wagtailimages.Image",
        null=True, blank=False,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text="An optional banner image",
    )
    body = RichTextField(
        null=True, blank=True,
        help_text='Article body'
    )
    content = StreamField([
        ('ContentBlock', ContentBlock()),
        ('ImageGalleryBlock', ImageGalleryBlock()),
        ('CallToActionBlock', CallToActionBlock()),
    ], null=True, blank=True)

    content_panels = [
        FieldPanel('title', classname="full title"),
        FieldPanel('headline'),
        FieldPanel('body'),
        ImageChooserPanel('banner_image'),
        StreamFieldPanel('content'),
    ]

    graphql_fields = [
        GraphQLString("headline"),
        GraphQLString("body"),
        GraphQLImage("banner_image"),
        GraphQLImage("banner_image_thumbnail", serializer=ImageRenditionField("fill-100x100", source="banner_image")),
        GraphQLStreamfield("content"),
    ]

    class Meta:
        """Meta information."""

        verbose_name = "Page"
        verbose_name_plural = "Pages"
Exemple #10
0
class HomePage(TranslatablePageRoutingMixin, TranslatablePageMixin, Page):
    body = StreamField([
        ('text',
         blocks.RichTextBlock(features=['h2', 'bold', 'italic', 'link'])),
    ])

    content_panels = Page.content_panels + [
        StreamFieldPanel('body'),
    ]

    subpage_types = ['basecms.ContentPage']

    graphql_fields = [
        GraphQLString('title'),
        GraphQLStreamfield('body'),
    ]
Exemple #11
0
class BlogPage(HeadlessPreviewMixin, Page):
    intro = models.CharField(max_length=250)
    body = fields.StreamField(DEFAULT_BLOCK_TYPES)

    api_fields = [APIField('intro'), APIField('body')]

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('intro'),
        StreamFieldPanel('body'),
    ]
    graphql_fields = [GraphQLString("intro"), GraphQLStreamfield("body")]
Exemple #12
0
class PersonPage(BasePage):
    template = 'patterns/pages/people/person_page.html'

    subpage_types = []
    parent_page_types = ['people.PersonIndex']

    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    photo = models.ForeignKey('images.CustomImage',
                              null=True,
                              blank=True,
                              related_name='+',
                              on_delete=models.SET_NULL)
    job_title = models.CharField(max_length=255)
    introduction = models.TextField(blank=True)
    biography = StreamField(StoryBlock(), blank=True)
    email = models.EmailField(blank=True)

    content_panels = BasePage.content_panels + [
        MultiFieldPanel([
            FieldPanel('first_name'),
            FieldPanel('last_name'),
        ],
                        heading="Name"),
        ImageChooserPanel('photo'),
        FieldPanel('job_title'),
        InlinePanel('social_media_profile', label='Social accounts'),
        MultiFieldPanel([
            FieldPanel('email'),
        ], heading='Contact information'),
        FieldPanel('introduction'),
        StreamFieldPanel('biography')
    ]

    graphql_fields = [
        GraphQLString("name"),
        GraphQLString("job_title"),
        GraphQLString("introduction"),
        GraphQLImage("photo"),
        GraphQLStreamfield("biography"),
    ]
class BlogPage(HeadlessPreviewMixin, Page):
    author = models.CharField(max_length=255)
    date = models.DateField("Post date")
    body = StreamField([
        ("heading", blocks.CharBlock(classname="full title")),
        ("paragraph", blocks.RichTextBlock()),
        ("image", ImageChooserBlock()),
    ])

    content_panels = Page.content_panels + [
        FieldPanel("author"),
        FieldPanel("date"),
        StreamFieldPanel("body"),
    ]

    # Note these fields below:
    graphql_fields = [
        GraphQLString("heading"),
        GraphQLString("date"),
        GraphQLString("author"),
        GraphQLStreamfield("body"),
    ]
Exemple #14
0
class PrizeIndexPage(Page):
    """
    Index page for Br Dictionaries.
    We need to alter the page model's context to return the child page objects,
    the DictPage objects, so that it works as an index page
    """
    introduction = models.TextField(help_text='List of Prizes', blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')
    description = StreamField(BaseStreamBlock(),
                              verbose_name="Description",
                              blank=True)
    date_published = models.DateField("Updated on", blank=True, null=True)

    content_panels = Page.content_panels + [
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
        StreamFieldPanel('description'),
        FieldPanel('date_published'),
    ]
    subpage_types = [
        'PrizePage',
    ]

    search_fields = Page.search_fields + [
        index.SearchField('description'),
    ]

    api_fields = [
        APIField('introduction'),
        APIField('date_published'),
        APIField('description'),
        APIField('image'),
        # APIField('authors'),  # This will nest the relevant BlogPageAuthor objects in the API response
    ]

    graphql_fields = [
        GraphQLString("introduction"),
        GraphQLString("date_published"),
        GraphQLStreamfield("description"),
        # GraphQLString("author"),
    ]

    def children(self):
        return self.get_children().specific().live()

    def get_context(self, request):
        context = super(PrizeIndexPage, self).get_context(request)
        context['prizes'] = PrizePage.objects.descendant_of(
            self).live().order_by('-date_published')
        return context

    def serve_preview(self, request, mode_name):
        # Needed for previews to work
        return self.serve(request)

    def get_prizes(self):
        return PrizePage.objects.live().descendant_of(self)
Exemple #15
0
class BlogPage(HeadlessPreviewMixin, Page):
    date = models.DateField("Post date")
    advert = models.ForeignKey(
        "home.Advert",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    hero_image = models.ForeignKey(
        "images.CustomImage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    book_file = models.ForeignKey(
        "wagtaildocs.Document",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    featured_media = models.ForeignKey(
        "wagtailmedia.Media",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    author = models.ForeignKey(AuthorPage,
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL,
                               related_name="+")
    body = StreamField(StreamFieldBlock())
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("date"),
        ImageChooserPanel("hero_image"),
        StreamFieldPanel("body"),
        FieldPanel("tags"),
        InlinePanel("related_links", label="Related links"),
        InlinePanel("authors", label="Authors"),
        FieldPanel("author"),
        SnippetChooserPanel("advert"),
        DocumentChooserPanel("book_file"),
        MediaChooserPanel("featured_media"),
    ]

    @property
    def copy(self):
        return self

    def paginated_authors(self, info, **kwargs):
        return resolve_paginated_queryset(self.authors, info, **kwargs)

    graphql_fields = [
        GraphQLString("date", required=True),
        GraphQLStreamfield("body"),
        GraphQLTag("tags"),
        GraphQLCollection(
            GraphQLForeignKey,
            "related_links",
            "home.blogpagerelatedlink",
            required=True,
            item_required=True,
        ),
        GraphQLCollection(GraphQLString,
                          "related_urls",
                          source="related_links.url"),
        GraphQLCollection(GraphQLString,
                          "authors",
                          source="authors.person.name"),
        GraphQLCollection(
            GraphQLForeignKey,
            "paginated_authors",
            "home.Author",
            is_paginated_queryset=True,
        ),
        GraphQLSnippet("advert", "home.Advert"),
        GraphQLImage("hero_image"),
        GraphQLDocument("book_file"),
        GraphQLMedia("featured_media"),
        GraphQLForeignKey("copy", "home.BlogPage"),
        GraphQLPage("author"),
    ]
class ProductPage(Page):
    uid_or_isbn = models.CharField(
        'UID or ISBN',
        max_length=13,
    )
    subtitle = models.CharField('Sub title', blank=True, max_length=255)
    introduction = models.TextField('Introduction',
                                    help_text='Product Intro',
                                    blank=True,
                                    null=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')
    body = StreamField(BaseStreamBlock(),
                       verbose_name="Product Page body",
                       blank=True,
                       null=True)
    date_published = models.DateField("Date of Publication",
                                      blank=True,
                                      null=True)
    product_tags = ClusterTaggableManager(through=TaggedProduct, blank=True)
    curr = models.ForeignKey('currency.Currency',
                             on_delete=models.PROTECT,
                             default=1)
    list_price = models.DecimalField('List Price',
                                     max_digits=10,
                                     decimal_places=2,
                                     default='0.00')
    discount = models.DecimalField('Discount',
                                   max_digits=4,
                                   decimal_places=2,
                                   default='0.00')
    qty_in_stock = models.DecimalField('Qty in Stock',
                                       max_digits=8,
                                       decimal_places=2,
                                       default='0.00')
    remarks = models.CharField('Remarks',
                               null=True,
                               blank=True,
                               max_length=255)
    #     linked_products = models.ManyToManyField('product.ProductPage', null=True, blank=True, related_name='other_linked_products')

    content_panels = Page.content_panels + [
        FieldPanel('uid_or_isbn', classname="full"),
        FieldPanel('subtitle', classname="full"),
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
        StreamFieldPanel('body'),
        FieldPanel('date_published'),
        FieldPanel('product_tags'),
        FieldPanel('list_price'),
        FieldPanel('discount'),
        FieldPanel('qty_in_stock'),
        FieldPanel('remarks'),
        #         PageChooserPanel('linked_products'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('uid_or_isbn'),
        index.SearchField('subtitle'),
        index.SearchField('introduction'),
        index.SearchField('body'),
    ]

    api_fields = [
        APIField('uid_or_isbn'),
        APIField('subtitle'),
        APIField('introduction'),
        APIField('date_published'),
        APIField('body'),
        APIField('image'),
        APIField('product_tags'),
        APIField('list_price'),
        APIField('discount'),
        APIField('qty_in_stock'),
        APIField('remarks'),
        #        APIField('linked_products'),
    ]

    graphql_fields = [
        GraphQLString("subtitle"),
        GraphQLString("introduction"),
        GraphQLString("date_published"),
        GraphQLStreamfield("body"),
        # GraphQLString("author"),
    ]

    parent_page_types = ['ProductIndexPage']
    subpage_types = []
Exemple #17
0
class BlogPage(GrapplePageMixin, Page):
    author = models.CharField(max_length=255)
    date = models.DateField("Post date")
    advert = models.ForeignKey('home.Advert',
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL,
                               related_name='+')
    body = StreamField([
        ("heading", blocks.CharBlock(classname="full title")),
        ("paraagraph", blocks.RichTextBlock()),
        ("image", ImageChooserBlock()),
        ("decimal", blocks.DecimalBlock()),
        ("date", blocks.DateBlock()),
        ("datetime", blocks.DateTimeBlock()),
        ("quote", blocks.BlockQuoteBlock()),
        (
            "drink",
            blocks.ChoiceBlock(choices=[("tea", "Tea"), ("coffee", "Coffee")],
                               icon="time"),
        ),
        ("somepage", blocks.PageChooserBlock()),
        (
            "static",
            blocks.StaticBlock(
                admin_text="Latest posts: no configuration needed."),
        ),
        (
            "person",
            blocks.StructBlock(
                [
                    ("first_name", blocks.CharBlock()),
                    ("surname", blocks.CharBlock()),
                    ("photo", ImageChooserBlock(required=False)),
                    ("biography", blocks.RichTextBlock()),
                ],
                icon="user",
            ),
        ),
        ("video", EmbedBlock()),
        (
            "carousel",
            blocks.StreamBlock(
                [
                    ("image", ImageChooserBlock()),
                    (
                        "quotation",
                        blocks.StructBlock([
                            ("text", blocks.TextBlock()),
                            ("author", blocks.CharBlock()),
                        ]),
                    ),
                ],
                icon="cogs",
            ),
        ),
        ("doc", DocumentChooserBlock()),
        (
            "ingredients_list",
            blocks.ListBlock(
                blocks.StructBlock([
                    ("ingredient", blocks.CharBlock()),
                    ("amount", blocks.CharBlock(required=False)),
                ])),
        ),
    ])

    content_panels = Page.content_panels + [
        FieldPanel("author"),
        FieldPanel("date"),
        StreamFieldPanel("body"),
        InlinePanel('related_links', label="Related links"),
        SnippetChooserPanel('advert')
    ]

    graphql_fields = [
        GraphQLString("heading"),
        GraphQLString("date"),
        GraphQLString("author"),
        GraphQLStreamfield("body"),
        GraphQLForeignKey("related_links", "home.blogpagerelatedlink", True),
        GraphQLSnippet('advert', 'home.Advert'),
    ]
Exemple #18
0
class BlogPage(Page):
    """
    We access the People object with an inline panel that references the
    ParentalKey's related_name in BlogPeopleRelationship. More docs:
    http://docs.wagtail.io/en/latest/topics/pages.html#inline-models
    """
    introduction = models.TextField(help_text='Text to describe the page',
                                    blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')
    body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
    subtitle = models.CharField(blank=True, max_length=255)
    blog_tags = ClusterTaggableManager(through=TaggedBlog, blank=True)
    date_published = models.DateField("Date article published",
                                      blank=True,
                                      null=True)
    body_word_count = models.PositiveIntegerField(null=True, editable=False)
    canonical_url = models.URLField(
        blank=True,
        max_length=255,
        null=True,
    )

    linked_products = models.ManyToManyField('product.ProductPage', )

    content_panels = Page.content_panels + [
        FieldPanel('subtitle', classname="full"),
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
        StreamFieldPanel('body'),
        FieldPanel('date_published'),
        InlinePanel('blog_authors', label="Author(s)", panels=None, min_num=1),
        FieldPanel('blog_tags'),
    ]

    promote_panels = Page.promote_panels + [
        FieldPanel('canonical_url'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('body'),
    ]

    api_fields = [
        APIField('introduction'),
        APIField('date_published'),
        APIField('body'),
        APIField('image'),
        # APIField('authors'),  # This will nest the relevant BlogPageAuthor objects in the API response
    ]

    graphql_fields = [
        GraphQLString("introduction"),
        GraphQLString("date_published"),
        GraphQLStreamfield("body"),
        # GraphQLString("author"),
    ]

    def authors(self):
        authors = [n.people for n in self.blog_authors.all()]
        return authors

    def set_body_word_count(self):
        body_basic_html = self.body.stream_block.render_basic(self.body)
        body_text = BeautifulSoup(body_basic_html, 'html.parser').get_text()
        remove_chars = string.punctuation + '“”’'
        body_words = body_text.translate(
            body_text.maketrans(dict.fromkeys(remove_chars))).split()
        self.body_word_count = len(body_words)

    @property
    def get_tags(self):
        """
        Similar to the authors function above we're returning all the tags that
        are related to the blog post into a list we can access on the template.
        We're additionally adding a URL to access BlogPage objects with that tag
        """
        tags = self.blog_tags.all()
        for tag in tags:
            tag.url = '/' + '/'.join(
                s.strip('/')
                for s in [self.get_parent().url, 'blog-tags', tag.slug])
        return tags

    # Specifies parent to BlogPage as being BlogIndexPages
    parent_page_types = ['BlogIndexPage']

    # Specifies what content types can exist as children of BlogPage.
    # Empty list means that no child content types are allowed.
    subpage_types = []
Exemple #19
0
class BlogPage(HeadlessPreviewMixin, Page):
    date = models.DateField("Post date")
    advert = models.ForeignKey(
        "home.Advert",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    cover = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    book_file = models.ForeignKey(
        "wagtaildocs.Document",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    featured_media = models.ForeignKey(
        "wagtailmedia.Media",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    author = models.ForeignKey(AuthorPage,
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL,
                               related_name="+")
    body = StreamField(StreamFieldBlock())

    content_panels = Page.content_panels + [
        FieldPanel("date"),
        ImageChooserPanel("cover"),
        StreamFieldPanel("body"),
        InlinePanel("related_links", label="Related links"),
        InlinePanel("authors", label="Authors"),
        FieldPanel("author"),
        SnippetChooserPanel("advert"),
        DocumentChooserPanel("book_file"),
        MediaChooserPanel("featured_media"),
    ]

    @property
    def copy(self):
        return self

    graphql_fields = [
        GraphQLString("heading"),
        GraphQLString("date", required=True),
        GraphQLStreamfield("body"),
        GraphQLCollection(GraphQLForeignKey,
                          "related_links",
                          "home.blogpagerelatedlink",
                          required=True,
                          item_required=True),
        GraphQLCollection(GraphQLString,
                          "related_urls",
                          source="related_links.url"),
        GraphQLCollection(GraphQLString,
                          "authors",
                          source="authors.person.name"),
        GraphQLSnippet("advert", "home.Advert"),
        GraphQLImage("cover"),
        GraphQLDocument("book_file"),
        GraphQLMedia("featured_media"),
        GraphQLForeignKey("copy", "home.BlogPage"),
        GraphQLPage("author"),
    ]
Exemple #20
0
class ArticlePage(BasePage):
    template = 'patterns/pages/articles/article_page.html'

    subpage_types = []
    parent_page_types = ['ArticleIndex']

    introduction = models.TextField(
        blank=True,
        max_length=165,
    )
    featured_image = models.ForeignKey('images.CustomImage',
                                       null=True,
                                       blank=True,
                                       related_name='+',
                                       on_delete=models.SET_NULL)
    featured_image_caption = models.CharField(
        blank=True,
        max_length=250,
    )
    body = StreamField(StoryBlock())
    license = models.ForeignKey('utils.LicenseSnippet',
                                null=True,
                                blank=True,
                                on_delete=models.SET_NULL,
                                related_name='+')
    tags = ClusterTaggableManager(through=ArticlePageTag, blank=True)
    categories = ParentalManyToManyField('articles.ArticlePageCategory',
                                         blank=True)

    # It's datetime for easy comparison with first_published_at
    publication_date = models.DateTimeField(
        null=True,
        blank=True,
        help_text="Use this field to override the date that the "
        "articles item appears to have been published.")

    search_fields = BasePage.search_fields + [
        index.SearchField('introduction'),
        index.SearchField('body')
    ]

    content_panels = BasePage.content_panels + [
        FieldPanel('introduction'),
        MultiFieldPanel(
            [
                ImageChooserPanel('featured_image'),
                FieldPanel('featured_image_caption'),
            ],
            heading="Featured Image",
        ),
        StreamFieldPanel('body'),
        InlinePanel('authors', label="Authors"),
        SnippetChooserPanel('license'),
        FieldPanel('tags'),
        FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
        FieldPanel('publication_date'),
        # TODO: comment related_pages back in if we have time with the front-end work for articles
        # InlinePanel('related_pages', label="Related pages"),
    ]

    # Export fields over REST API
    api_fields = [
        APIField('introduction'),
        APIField('body'),
        APIField('authors'),
        APIField('tags'),
        APIField('categories'),
        APIField('featured_image',
                 serializer=ImageRenditionField('fill-1920x1080')),
        APIField('featured_image_caption'),
    ]

    # Export fields to GraphQL

    graphql_fields = [
        GraphQLString("heading"),
        GraphQLString("publication_date"),
        GraphQLStreamfield("body"),
        GraphQLString("categories"),
        GraphQLImage("featured_image"),
        GraphQLString("featured_image_caption")
    ]

    class Meta:
        verbose_name = "Article"

    @property
    def display_date(self):
        if self.publication_date:
            return self.publication_date
        else:
            return self.first_published_at