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"
class ButtonBlock(blocks.StructBlock): button_text = blocks.CharBlock(required=True, max_length=50, label="Text") button_link = blocks.CharBlock(required=True, max_length=255, label="Link") graphql_fields = [ GraphQLString("button_text"), GraphQLString("button_link") ]
class BlogPageRelatedLink(Orderable): page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name="related_links") name = models.CharField(max_length=255) url = models.URLField() panels = [FieldPanel("name"), FieldPanel("url")] graphql_fields = [GraphQLString("name"), GraphQLString("url")]
class Advert(models.Model): url = models.URLField(null=True, blank=True) text = models.CharField(max_length=255) panels = [FieldPanel("url"), FieldPanel("text")] graphql_fields = [GraphQLString("url"), GraphQLString("text")] def __str__(self): return self.text
class Person(models.Model): name = models.CharField(max_length=255) job = models.CharField(max_length=255) def __str__(self): return self.name panels = [FieldPanel("name"), FieldPanel("job")] graphql_fields = [GraphQLString("name"), GraphQLString("job")]
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 SocialMediaSettings(BaseSetting): facebook = models.URLField(help_text='Your Facebook page URL') instagram = models.CharField( max_length=255, help_text='Your Instagram username, without the @') trip_advisor = models.URLField(help_text='Your Trip Advisor page URL') youtube = models.URLField( help_text='Your YouTube channel or user account URL') graphql_fields = [ GraphQLString('facebook'), GraphQLString('instagram'), GraphQLString('trip_advisor'), GraphQLString('youtube'), ]
class SocialMediaSettings(BaseSetting): facebook = models.URLField(help_text="Your Facebook page URL") instagram = models.CharField( max_length=255, help_text="Your Instagram username, without the @") trip_advisor = models.URLField(help_text="Your Trip Advisor page URL") youtube = models.URLField( help_text="Your YouTube channel or user account URL") graphql_fields = [ GraphQLString("facebook"), GraphQLString("instagram"), GraphQLString("trip_advisor"), GraphQLString("youtube"), ]
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
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 = []
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"
class CustomImage(AbstractImage): admin_form_fields = Image.admin_form_fields def custom_image_property(self): return "Image Model!" graphql_fields = (GraphQLString("custom_image_property"), )
class CustomImage(AbstractImage): admin_form_fields = Image.admin_form_fields def custom_image_property(self, info, **kwargs): return "Image Model!" graphql_fields = (GraphQLString("custom_image_property", required=True),)
class CustomDocument(AbstractDocument): admin_form_fields = Document.admin_form_fields def custom_document_property(self, info, **kwargs): return "Document Model!" graphql_fields = (GraphQLString("custom_document_property", required=True), )
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) try: from grapple.models import GraphQLString self.graphql_fields = GraphQLString("traced_SVG") except: # noqa pass
class GatsbyImageRendition(AbstractRendition): image = models.ForeignKey( GatsbyImage, on_delete=models.CASCADE, related_name="renditions" ) class Meta(AbstractRendition.Meta): abstract = True unique_together = ("image", "filter_spec", "focal_point_key") graphql_fields = ( GraphQLString("id"), GraphQLString("file"), GraphQLString("url"), GraphQLString("width"), GraphQLString("height"), GraphQLImage("image"), )
class ImageGalleryImage(blocks.StructBlock): caption = blocks.CharBlock(classname="full title") image = ImageChooserBlock() graphql_fields = [ GraphQLString("caption"), GraphQLImage("image") ]
class ImageGalleryBlock(blocks.StructBlock): title = blocks.CharBlock(classname="full title") images = ImageGalleryImages() graphql_fields = [ GraphQLString("title"), GraphQLCollection(GraphQLForeignKey, "images", ImageGalleryImage), ]
class TextAndButtonsBlock(blocks.StructBlock): text = blocks.TextBlock() buttons = blocks.ListBlock(ButtonBlock()) graphql_fields = [ GraphQLString("text"), GraphQLImage("image"), GraphQLStreamfield("buttons"), ]
class BlogLandingPage(HeadlessPreviewMixin, Page): intro = RichTextField(blank=True) content_panels = Page.content_panels + [ FieldPanel('intro', classname="full") ] graphql_fields = [ GraphQLString("intro"), ]
class AuthorPage(Page): name = models.CharField(max_length=255) content_panels = Page.content_panels + [ FieldPanel("name"), ] graphql_fields = [ GraphQLString("name"), ]
class Author(Orderable): page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name="authors") role = models.CharField(max_length=255) person = models.ForeignKey( Person, null=True, blank=True, on_delete=models.SET_NULL, related_name="+" ) panels = [FieldPanel("role"), SnippetChooserPanel("person")] graphql_fields = [GraphQLString("role"), GraphQLForeignKey("person", Person)]
class CustomImageRendition(AbstractRendition): image = models.ForeignKey( "CustomImage", related_name="renditions", on_delete=models.CASCADE ) class Meta: unique_together = (("image", "filter_spec", "focal_point_key"),) def custom_rendition_property(self, info, **kwargs): return "Rendition Model!" graphql_fields = ( GraphQLString("custom_rendition_property", required=True), GraphQLInt("id", required=True), GraphQLString("url", required=True), GraphQLString("width", required=True), GraphQLString("height", required=True), GraphQLImage("image", required=True), GraphQLString("file", required=True), )
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"), ]
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 ]
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 = []
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'), ]
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")]