class CommonEditingBlock(blocks.StreamBlock): image_block = ImageBlock() paragraph_block = ParagraphBlock() blockquote_block = BlockquoteBlock() html = blocks.RawHTMLBlock() embed = EmbedBlock(icon='media') table_block = TableBlock()
class StandardPage(Page): TEMPLATE_CHOICES = [ ('pages/standard_page.html', 'Default Template'), ('pages/standard_page_full.html', 'Standard Page Full'), ] subtitle = models.CharField(max_length=255, blank=True) intro = RichTextField(blank=True) body = StreamField([ ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('markdown', MarkdownBlock(icon="code")), ('html', blocks.RawHTMLBlock()), ]) template_string = models.CharField( max_length=255, choices=TEMPLATE_CHOICES, default='pages/standard_page.html' ) feed_image = models.ForeignKey( Image, null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), ] @property def template(self): return self.template_string
class ResourceBlock(blocks.StructBlock): """A section of a ResourcePage""" title = blocks.CharBlock(required=True) hide_title = blocks.BooleanBlock(required=False, help_text='Should the section title be displayed?') content = blocks.StreamBlock([ ('text', blocks.RichTextBlock(blank=False, null=False, required=False, icon='pilcrow')), ('documents', blocks.ListBlock(ThumbnailBlock(), template='blocks/section-documents.html', icon='doc-empty')), ('contact_info', ContactInfoBlock()), ('internal_button', InternalButtonBlock()), ('external_button', ExternalButtonBlock()), ('page', blocks.PageChooserBlock(template='blocks/page-links.html')), ('disabled_page', blocks.CharBlock(blank=False, null=False, required=False, template='blocks/disabled-page-links.html', icon='placeholder', help_text='Name of a disabled link')), ('document_list', blocks.ListBlock(FeedDocumentBlock(), template='blocks/document-list.html', icon='doc-empty')), ('current_commissioners', CurrentCommissionersBlock()), ('fec_jobs', CareersBlock()), ('mur_search', MURSearchBlock()), ('table', TableBlock()), ('html', blocks.RawHTMLBlock()), ('reporting_example_cards', ReportingExampleCards()), ('contribution_limits_table', SnippetChooserBlock('home.EmbedTableSnippet', template = 'blocks/embed-table.html', icon='table')), ]) aside = blocks.StreamBlock([ ('title', blocks.CharBlock(required=False, icon='title')), ('document', ThumbnailBlock()), ('link', AsideLinkBlock()), ], template='blocks/section-aside.html', icon='placeholder') class Meta: template = 'blocks/section.html'
class AbstractContentPage(Page): class Meta: abstract = True intro = models.CharField(max_length=250) body = StreamField([ ("rich_text", blocks.RichTextBlock(required=False)), ("raw_html", blocks.RawHTMLBlock(required=False)), ("floating_image", FloatingImageBlock()), ("anchor", AnchorBlock( help_text="Add a named anchor to this point in the page")), ("colophon_image_list", ColophonImageListBlock()), ]) background_image = models.ForeignKey('CustomImage', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), ] content_panels = Page.content_panels + [ ImageChooserPanel('background_image'), FieldPanel('intro'), StreamFieldPanel('body') ]
class Content(Page): body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('rich_text', blocks.RichTextBlock()), ('raw', blocks.RawHTMLBlock()), ('include_content', blocks.CharBlock()), ('content_list', blocks.CharBlock()), ], null=True, blank=True) date = models.DateField("Content updated date", default=timezone.now) promote_panels = Page.promote_panels + [ FieldPanel('date'), ] content_panels = Page.content_panels + [ StreamFieldPanel('body'), ] search_fields = Page.search_fields + ( index.SearchField('body'), index.FilterField('url_path'), ) def serve(self, request): if "draft" in request.GET: return HttpResponseRedirect("/admin/pages/{}/view_draft/".format( self.pk)) return super(Content, self).serve(request) class Meta: ordering = ("date", )
class PortfolioPage(Page): main_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') date = models.DateField(("Post date"), default=datetime.date.today) intro = models.CharField(max_length=250) body = StreamField([ ('rich_text', blocks.RichTextBlock(icon='doc-full', label='Rich Text')), ('html', blocks.RawHTMLBlock(icon='site', label='Raw HTML')) ]) search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body') ] @property def portfolio_index(self): return self._get_ancestors().type(PortfolioIndexPage).last() content_panels = Page.content_panels + [ ImageChooserPanel('main_image'), FieldPanel('date'), FieldPanel('intro', classname="full"), StreamFieldPanel('body'), ]
class FormBuilder(blocks.StreamBlock): text_field = TextFieldBlock() textarea = TextAreaBlock() text = blocks.RichTextBlock() image = ImageChooserBlock() html = blocks.RawHTMLBlock() embed = EmbedBlock()
class ServicesPage(Page): body = StreamField([ ('rich_text', blocks.RichTextBlock(icon='doc-full', label='Rich Text')), ('code', CodeBlock(icon='code')), ('quote', QuoteBlock(icon='openquote')), ('markdown', MarkdownBlock()), ('html', blocks.RawHTMLBlock(icon='site', label='HTML')), ('image', CaptionedImageBlock()), ]) banner_image = models.ForeignKey("wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL) content_panels = Page.content_panels + [ StreamFieldPanel('body'), ImageChooserPanel('banner_image'), InlinePanel('services', label="Services"), InlinePanel('technologies', label="Technologies"), ] def get_context(self, request): context = super(ServicesPage, self).get_context(request) context['technologies'] = Technology.objects.filter( technologysection__page=self) return context
class ContentBlock(blocks.StreamBlock): heading = blocks.CharBlock(classname="full title", icon="title") paragraph = blocks.RichTextBlock() email = blocks.EmailBlock( classname="email", label="Email", help_text="Add an email", template="biz_content/content_blocks/email_block.html") phone_number = PhoneBlock( classname="phone_number", label="Phone Number", ) link = blocks.StructBlock( [('link_text', blocks.CharBlock()), ('link_url', blocks.URLBlock())], classname="text", label="Link", help_text="Add resource link", icon="fa-link", template="biz_content/content_blocks/url_block.html") alert_text = blocks.CharBlock( max_length=2000, classname="alert_text", label="Alert Text", help_text="Add Alert Text", icon="fa-exclamation", template="biz_content/content_blocks/alert_text.html") embed_block = blocks.RawHTMLBlock( icon="fa-code", help_text="Copy and paste a map or video embed directly here.")
class PayingForCollegeContent(blocks.StreamBlock): """A base content block for PFC pages.""" full_width_text = organisms.FullWidthText() info_unit_group = organisms.InfoUnitGroup() expandable_group = organisms.ExpandableGroup() expandable = organisms.Expandable() well = organisms.Well() raw_html_block = blocks.RawHTMLBlock(label='Raw HTML block')
class BlogPage(RoutablePageMixin, Page): intro = RichTextField() body = StreamField([ ('paragraph', blocks.RichTextBlock()), ('markdown', MarkdownBlock(icon="code")), ('image', ImageChooserBlock()), ('html', blocks.RawHTMLBlock()), ]) tags = ClusterTaggableManager(through=BlogPageTag, blank=True) date = models.DateField("Post date") feed_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') search_fields = Page.search_fields + [ index.SearchField('body'), ] parent_page_types = ['blog.BlogIndexPage'] @property def blog_index(self): # Find closest ancestor which is a blog index return self.get_ancestors().type(BlogIndexPage).last() @route(r'^$') def normal_page(self, request): return Page.serve(self, request) @route(r'^amp/$') def amp(self, request): context = self.get_context(request) body_html = self.body.__html__() soup = BeautifulSoup(body_html, 'html.parser') # Remove style attribute to remove large bottom padding for div in soup.find_all("div", {'class': 'responsive-object'}): del div['style'] # Change img tags to amp-img for img_tag in soup.findAll('img'): img_tag.name = 'amp-img' img_tag.append(BeautifulSoup('</amp-img>', 'html.parser')) img_tag['layout'] = 'responsive' # Change iframe tags to amp-iframe for iframe in soup.findAll('iframe'): iframe.name = 'amp-iframe' iframe['sandbox'] = 'allow-scripts allow-same-origin' iframe['layout'] = 'responsive' context['body_html'] = mark_safe(soup.prettify(formatter="html")) context['is_amp'] = True context['base_template'] = 'amp_base.html' response = TemplateResponse(request, 'blog/blog_page_amp.html', context) return response
class LegacyBlogPage(AbstractFilterPage): content = StreamField([ ('content', blocks.RawHTMLBlock(help_text='Content from WordPress unescaped.')), ]) objects = CFGOVPageManager() edit_handler = AbstractFilterPage.generate_edit_handler( content_panel=StreamFieldPanel('content')) template = 'blog/blog_page.html'
class HomePageWithHtml(Page): body = StreamField([ ('rich_text', blocks.RichTextBlock(icon='doc-full', label='Rich Text')), ('html', blocks.RawHTMLBlock(icon='site', label='HTML')) ]) content_panels = Page.content_panels + [ StreamFieldPanel('body') ]
class ResumePage(Page): body = StreamField([ ('rich_text', blocks.RichTextBlock()), ('html', blocks.RawHTMLBlock()), ('header', HeaderBlock()), ('sub_header', SubHeaderBlock()), ]) content_panels = Page.content_panels + [ StreamFieldPanel('body'), ]
class Content(Page): body = StreamField([ ('heading', blocks.CharBlock(classname='full title')), ('rich_text', blocks.RichTextBlock()), ('raw', blocks.RawHTMLBlock()), ('include_content', blocks.CharBlock()), ('content_list', blocks.CharBlock()), ], null=True, blank=True) date = models.DateField('Content updated date', default=timezone.now) template_filename = models.CharField(max_length=64, choices=( ('content.html', 'content.html'), ('f6-content.html', 'f6-content.html'), ('f6-vue.html', 'f6-vue.html'), ), default='f6-content.html') tags = ClusterTaggableManager(through=ContentTag, blank=True) def get_template(self, request, *args, **kwargs): template_name = request.GET.get('template', self.template_filename) return '{}/{}'.format(self.__class__._meta.app_label, template_name) promote_panels = Page.promote_panels + [ FieldPanel('date'), FieldPanel('tags') ] content_panels = Page.content_panels + [ StreamFieldPanel('body'), ] settings_panels = Page.settings_panels + [FieldPanel('template_filename')] search_fields = Page.search_fields + [ index.SearchField('body'), index.FilterField('url_path'), ] def serve(self, request): if 'draft' in request.GET: return HttpResponseRedirect('/admin/pages/{}/view_draft/'.format( self.pk)) response = super(Content, self).serve(request) if 'embed' in request.GET: with open( os.path.join(settings.MEDIA_ROOT, 'images', self.slug + '.html')) as output: output.write(response.content) return response class Meta: ordering = ('date', )
class WidthBlock(blocks.StructBlock): width = blocks.IntegerBlock( min_value=1, max_value=5, help_text="How many grid columns to occupy in rendered template") content = blocks.StreamBlock([ ('rich_text', blocks.RichTextBlock()), ('raw_html', blocks.RawHTMLBlock()), ('image', image_blocks.ImageChooserBlock()), ], min_num=1, max_num=1)
class HeroBlock(StructBlockWithStyle): image = ImageChooserBlock(required=True) description = blocks.RawHTMLBlock(required=True) image_display_setting = blocks.ChoiceBlock( choices=[('background', 'Cover the whole Hero as a background'), ('icon', 'Center the image in the middle of the hero block')]) text_color = blocks.CharBlock(help_text='Enter a color for the text.') class Meta: template = 'common/blocks/hero_block.html' icon = 'fa-star' label = 'Hero Block'
class ContactPage(AbstractEmailForm): intro = RichTextField(blank=True) thank_you_text = RichTextField(blank=True) body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('blockquote', blocks.BlockQuoteBlock()), ('raw_html', blocks.RawHTMLBlock()), ], blank=True) content_panels = AbstractEmailForm.content_panels + [ FormSubmissionsPanel(), FieldPanel('intro', classname="full"), InlinePanel('contact_fields', label="Form fields"), StreamFieldPanel('body'), FieldPanel('thank_you_text', classname="full"), MultiFieldPanel([ FieldRowPanel([ FieldPanel('from_address', classname="col6"), FieldPanel('to_address', classname="col6"), ]), FieldPanel('subject'), ], "Email"), ] def get_form_fields(self): return self.contact_fields.all() def send_mail(self, form): # Overwrite the send_mail method from AbstractEmailForm # to use inquiry as email subject. addresses = [x.strip() for x in self.to_address.split(',')] content = [] subj = None send_from = self.from_address for field in form: if 'inquiry' in field.name: subj = field.value() elif 'email' in field.name.lower(): send_from = field.value() value = field.value() if isinstance(value, list): value = ', '.join(value) content.append('{}: {}'.format(field.label, value)) content = '\n'.join(content) if subj: send_mail(subj, content, addresses, send_from,) else: send_mail(self.subject, content, addresses, send_from,)
class VideoItem(models.Model): title = models.CharField(verbose_name=u'视频名称', max_length=255) code = RichTextField(verbose_name=u'视频代码', max_length=255) code = StreamField([ ('code', blocks.RawHTMLBlock()), ]) panels = [ FieldPanel('title'), StreamFieldPanel('code'), ] class Meta: abstract = True
class Content(Page): body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('rich_text', blocks.RichTextBlock()), ('raw', blocks.RawHTMLBlock()), ('include_content', blocks.CharBlock()), ('content_list', blocks.CharBlock()), ], null=True, blank=True) date = models.DateField("Content updated date", default=timezone.now) template_filename = models.CharField(max_length=64, choices=( ("content.html", "content.html"), ("f6-content.html", "f6-content.html"), ), default="content.html") tags = ClusterTaggableManager(through=ContentTag, blank=True) def get_template(self, request, *args, **kwargs): template_name = request.GET.get("template", self.template_filename) return "{}/{}".format(self.__class__._meta.app_label, template_name) promote_panels = Page.promote_panels + [ FieldPanel('date'), FieldPanel('tags') ] content_panels = Page.content_panels + [ StreamFieldPanel('body'), ] settings_panels = Page.settings_panels + [FieldPanel("template_filename")] search_fields = Page.search_fields + ( index.SearchField('body'), index.FilterField('url_path'), ) def serve(self, request): if "draft" in request.GET: return HttpResponseRedirect("/admin/pages/{}/view_draft/".format( self.pk)) return super(Content, self).serve(request) class Meta: ordering = ("date", )
def __init__(self, local_blocks=None, **kwargs): default_blocks = [ ('appeal', blocks.StructBlock([ ('icon', blocks.ChoiceBlock(required=True, choices=[ ('none', 'none'), ('flask', 'flask'), ('group', 'group'), ('laptop', 'laptop'), ('sitemap', 'sitemap'), ('user', 'user'), ('book', 'book'), ('download', 'download'), ])), ('topic', blocks.CharBlock(required=True, max_length=35)), ('content', blocks.RichTextBlock(required=True)), ], classname='appeal', icon='tick', template='common/blocks/appeal.html')), ('heading', blocks.CharBlock(classname="full title")), ('statement', blocks.CharBlock()), ('twitter', TwitterBlock()), ('photo_stream', COSPhotoStreamBlock()), ('rich_text', blocks.RichTextBlock()), ('paragraph', blocks.TextBlock()), ('map', GoogleMapBlock()), ('image', ImageBlock()), ('customImage', CustomImageBlock()), ('raw_html', blocks.RawHTMLBlock( help_text='With great power comes great responsibility. ' 'This HTML is unescaped. Be careful!')), ('centered_text', CenteredTextBlock()), ('embed_block', EmbedBlock()), ('code_block', CodeBlock()), ('table_block', CustomTableBlock()), ('journal_tab_block', JournalsTabBlock()), ('calender_block', GoogleCalendarBlock()), ('job_whole_block', JobsWholeBlock()), ('people_block', PeopleBlock()), ('collapse_block', CollapseBoxBlock()), ('button', ButtonBlock()), ] if local_blocks: default_blocks = default_blocks + local_blocks super(GenericContentStreamBlock, self).__init__( local_blocks=default_blocks, **kwargs)
class NavPage(Page): # Database fields nav_title=RichTextField(default='') body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RawHTMLBlock()) ]) date = models.DateField("Post date") feed_image = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) # Search index configuraiton search_fields = Page.search_fields + ( index.SearchField('body'), index.FilterField('date'), ) # Editor panels configuration content_panels = Page.content_panels + [ FieldPanel('nav_title'), FieldPanel('date'), StreamFieldPanel('body'), ] promote_panels = [ MultiFieldPanel(Page.promote_panels, "Common page configuration"), ImageChooserPanel('feed_image'), ] # Parent page / subpage type rules parent_page_types = ['SectionPage']
class PomahejPage(Page): body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embed', EmbedBlock()), ('rawHtml', blocks.RawHTMLBlock()), ('medailon', blocks.StructBlock([ ('title', blocks.CharBlock(required=True)), ('pic', ImageChooserBlock(required=True)), ('description', blocks.RichTextBlock(required=True)), ], template='blocks/medailon.html', icon='user')) ]) content_panels = Page.content_panels + [ StreamFieldPanel('body'), ]
class ContentPage(Page): abstract = RichTextField() body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('raw_html', blocks.RawHTMLBlock()) ]) social_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') content_panels = Page.content_panels + [ FieldPanel('abstract', classname="full"), StreamFieldPanel('body') ] promote_panels = Page.promote_panels + [ ImageChooserPanel('social_image') ]
class BankingPage(Page): intro_text = RichTextField() embed_js = StreamField([ ('embed_js', blocks.RawHTMLBlock()), ]) closing_text = RichTextField() parent_page_types = ['banking.BankingIndexPage'] content_panels = Page.content_panels + [ FieldPanel('intro_text', classname='full'), StreamFieldPanel('embed_js'), InlinePanel('comparison_links', label="Comparison links"), FieldPanel('closing_text', classname='full'), ] class Meta: verbose_name = 'Banking and Savings page'
class SimplePage(Page): body = StreamField([ ('rich_text', blocks.RichTextBlock(icon='doc-full', label='Rich Text')), ('code', CodeBlock(icon='code')), ('quote', QuoteBlock(icon='openquote')), ('markdown', MarkdownBlock()), ('html', blocks.RawHTMLBlock(icon='site', label='HTML')), ('image', ImageChooserBlock()), ]) banner_image = models.ForeignKey("wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL) content_panels = Page.content_panels + [ ImageChooserPanel('banner_image'), StreamFieldPanel('body'), ]
class ThesisSearch(Page): parent_page_types = ['theses.ThesisIndexPage'] body = StreamField([ ('rawHtml', blocks.RawHTMLBlock()), ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embed', EmbedBlock()), ]) def get_context(self, request): context = super(ThesisSearch, self).get_context(request) # this randomization is costly - we may recompute order as we wish # when adding a new thesis and then just using that order precomputed context['theses'] = ThesisPage.objects.child_of( ThesisIndexPage.objects.first()).live().order_by('?') context["tags"] = ThesisPage.tags.order_by('name') return context
class ThesisIndexPage(Page): header = StreamField([ ('rawHtml', blocks.RawHTMLBlock()), ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embed', EmbedBlock()), ]) background_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+') content_panels = Page.content_panels + [ StreamFieldPanel('header'), ImageChooserPanel('background_image'), ]
class LegacyBlogPage(AbstractFilterPage): content = StreamField([ ('content', blocks.RawHTMLBlock(help_text='Content from WordPress unescaped.')), ]) objects = CFGOVPageManager() content_panels = AbstractFilterPage.content_panels + [ StreamFieldPanel('header'), StreamFieldPanel('content'), ] edit_handler = TabbedInterface([ ObjectList(content_panels, heading='General Content'), ObjectList(AbstractFilterPage.sidefoot_panels, heading='Sidebar'), ObjectList(AbstractFilterPage.settings_panels, heading='Configuration'), ]) template = 'blog/blog_page.html'
class BlogPage(Page): date = models.DateField("Post date") intro = models.CharField(max_length=250) body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('html', blocks.RawHTMLBlock()), # ('person', blocks.StructBlock([ # ('first_name', blocks.CharBlock(required=True)), # ('surname', blocks.CharBlock(required=True)), # ('photo', ImageChooserBlock()), # ('biography', blocks.RichTextBlock()), # ])), ('person', PersonBlock()), ]) tags = ClusterTaggableManager(through=BlogPageTag, blank=True) categories = ParentalManyToManyField('BlogCategory', blank=True) def main_image(self): gallery_item = self.gallery_images.first() if gallery_item: return gallery_item.image else: return None search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), ] content_panels = Page.content_panels + [ MultiFieldPanel([ FieldPanel('date'), FieldPanel('tags'), FieldPanel('categories', widget=forms.CheckboxSelectMultiple), ], heading="Blog information"), FieldPanel('intro'), StreamFieldPanel('body'), InlinePanel('gallery_images', label="Gallery images"), ]