class BlogPage(Page): subtitle = models.CharField(blank=True, max_length=255) description = models.TextField( help_text='Text to describe the page', blank=True) cover_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="Content block", blank=True ) tags = ClusterTaggableManager(through=BlogPageTag, blank=True) date_published = models.DateField( "Date article published", blank=True, null=True ) content_panels = Page.content_panels + [ FieldPanel('subtitle', classname="full"), FieldPanel('description', classname="full"), ImageChooserPanel('cover_image'), StreamFieldPanel('body'), FieldPanel('date_published'), InlinePanel( 'blog_person_relationship', label="Author(s)", panels=None), FieldPanel('tags'), ] def authors(self): return [ n.person for n in self.blog_person_relationship.all() ] @property def get_tags(self): tags = self.tags.all() for tag in tags: tag.url = '/' + '/'.join(s.strip('/') for s in [ self.get_parent().url, 'tags', tag.slug ]) return tags parent_page_types = ['BlogIndexPage'] subpage_types = []
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 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 StandardEventPage(Page): description = models.TextField(help_text='Text to describe the page', blank=True) cover_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="Content block", blank=True, null=True) start = models.DateTimeField() end = models.DateTimeField() is_allday = models.BooleanField() location = models.CharField(max_length=250) related_link = models.URLField(blank=True) abstract_deadline = models.DateTimeField(blank=True, null=True) our_speakers = models.TextField(blank=True, null=True) content_panels = Page.content_panels + [ FieldPanel('description', classname="full"), ImageChooserPanel('cover_image'), StreamFieldPanel('body'), FieldPanel('start'), FieldPanel('end'), FieldPanel('is_allday'), FieldPanel('location'), FieldPanel('related_link'), FieldPanel('abstract_deadline'), FieldPanel('our_speakers'), ] parent_page_types = ['EventsIndexPage'] subpage_types = [] api_fields = [ APIField('start'), APIField('end'), APIField('is_allday'), APIField('location'), APIField('related_link'), ]
class WorkImagePage(Page): """ This is a page describing work. This page will contain images along with text. """ preview_image = models.ForeignKey('wagtailimages.Image', on_delete=models.PROTECT, related_name='+', help_text='Image for the preview.', verbose_name='Preview Image') preview_heading = models.CharField( max_length=50, verbose_name='Preview Title', help_text='One liner for this work that will be displayed ' 'as a heading with preview image. ' 'Max 50 characters.') work_summary = TextField( max_length=800, verbose_name='Work Summary', help_text='A short summary of the work. Max 800 chars.') work_date = models.DateField(verbose_name='Date', help_text='Date/Start date of the work.', blank=True, null=True) work_video_title = models.CharField(null=True, blank=True, max_length=50, help_text='Max 50 chars.') work_video_subtitle = models.CharField(null=True, blank=True, max_length=100, help_text='Max 100 chars.') work_video_image = models.ForeignKey( 'wagtailimages.Image', on_delete=models.PROTECT, null=True, blank=True, related_name='+', help_text='Screenshot image of the video', verbose_name='Video screenshot/image.') work_video_url = models.URLField( verbose_name='Video URL', null=True, blank=True, help_text='Paste the video url from youtube.') work_desc = StreamField(BaseStreamBlock(), verbose_name='Work Description', help_text='A complete description of the work.') content_panels = Page.content_panels + [ MultiFieldPanel([ ImageChooserPanel("preview_image"), FieldPanel("preview_heading"), ], heading="Preview Section", help_text=''), InlinePanel('carousel_items', label="Work Images"), FieldPanel("work_summary", classname="full"), FieldPanel("work_date"), MultiFieldPanel([ FieldPanel("work_video_title"), FieldPanel("work_video_subtitle"), ImageChooserPanel('work_video_image'), FieldPanel('work_video_url'), ], heading="Work Video", classname="collapsible"), StreamFieldPanel('work_desc'), ] # Specifies parent to WorkImagePage as being BlogIndexPages parent_page_types = ['PortfolioIndexPage']
class BlogPage(Page): """ A Blog 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) tags = ClusterTaggableManager(through=BlogPageTag, blank=True) date_published = models.DateField("Date article published", blank=True, null=True) content_panels = Page.content_panels + [ FieldPanel('subtitle', classname="full"), FieldPanel('introduction', classname="full"), ImageChooserPanel('image'), StreamFieldPanel('body'), FieldPanel('date_published'), InlinePanel('blog_person_relationship', label="Author(s)", panels=None, min_num=1), FieldPanel('tags'), ] search_fields = Page.search_fields + [ index.SearchField('body'), ] def authors(self): """ Returns the BlogPage's related People. Again note that we are using the ParentalKey's related_name from the BlogPeopleRelationship model to access these objects. This allows us to access the People objects with a loop on the template. If we tried to access the blog_person_ relationship directly we'd print `blog.BlogPeopleRelationship.None` """ authors = [n.people for n in self.blog_person_relationship.all()] return authors @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.tags.all() for tag in tags: tag.url = '/' + '/'.join( s.strip('/') for s in [self.get_parent().url, '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 = []
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 = []
class BlogPage(Page): """ Blog Details Page """ banner_image = models.ForeignKey( 'wagtailimages.Image', blank=True, null=True, on_delete=models.SET_NULL, related_name='+', help_text='Banner Image' ) banner_intro = models.CharField(max_length=50, blank=True) introduction = models.TextField(blank=True, help_text='Text to Describe the Page' ) blog_introduction = models.CharField(max_length=500, blank=True) blog_title = models.CharField(blank=True, max_length=255 ) blog_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+', ) body = StreamField( BaseStreamBlock(), verbose_name='Page Body', blank=True ) date_published = models.DateField("Date Article Published", blank=True, null=True) content_panels = Page.content_panels + [ ImageChooserPanel('banner_image'), FieldPanel('banner_intro'), FieldPanel('introduction', classname='full'), FieldPanel('blog_introduction'), FieldPanel('blog_title', classname='full'), ImageChooserPanel('blog_image'), StreamFieldPanel('body'), FieldPanel('date_published'), # InlinePanel('blog_person_relationship', # label='Author', # panels=None, # min_num=1) ] search_fields = Page.search_fields + [ index.SearchField('body'), ] # def author(self): # authors = [ # n.people for n in self.blog_person_relationship # ] # return authors # Specifies parent to BlogPage as being BlogIndexPages parent_page_types = ['BlogIndex']
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 = []
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)