class HomePage(Page, MeetupMixin, SponsorMixin): subpage_types = [ 'HomePage', 'SimplePage', 'speakers.SpeakersPage', 'speakers.TalksPage' ] body = StreamField([('heading', blocks.CharBlock(icon="home", classname="full title")), ('paragraph', blocks.RichTextBlock(icon="edit")), ('video', EmbedBlock(icon="media")), ('image', ImageChooserBlock(icon="image")), ('slide', EmbedBlock(icon="media")), ('html', RawHTMLBlock(icon="code"))]) sponsors = models.ManyToManyField(Sponsor, through=HomePageSponsorRelationship, null=True, blank=True) def __str__(self): return self.title content_panels = Page.content_panels + [ StreamFieldPanel('body'), ] settings_panels = Page.settings_panels + MeetupMixin.settings_panels + SponsorMixin.settings_panels + [ InlinePanel('homepage_segments', label='Homepage Segment'), ]
class ThreeColumnBlock(blocks.StructBlock): background = blocks.ChoiceBlock(choices=COLOUR_CHOICES, default="white") left_column = blocks.StreamBlock([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embedded_video', EmbedBlock()), ('google_map', GoogleMapBlock()), ], icon='arrow-left', label='Left column content') center_column = blocks.StreamBlock([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embedded_video', EmbedBlock()), ('google_map', GoogleMapBlock()), ], icon='arrow-right', label='Center column content') right_column = blocks.StreamBlock([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embedded_video', EmbedBlock()), ('google_map', GoogleMapBlock()), ], icon='arrow-right', label='Right column content') class Meta: template = 'home/includes/three_column_block.html' icon = 'placeholder' label = 'Three Columns'
def test_serialize(self): block = EmbedBlock(required=False) block_val = EmbedValue('http://www.example.com/foo') serialized_val = block.get_prep_value(block_val) self.assertEqual(serialized_val, 'http://www.example.com/foo') serialized_empty_val = block.get_prep_value(None) self.assertEqual(serialized_empty_val, '')
def test_render_form(self): """ The form field for an EmbedBlock should be a text input containing the URL """ block = EmbedBlock() form_html = block.render_form(EmbedValue('http://www.example.com/foo'), prefix='myembed') self.assertIn('<input ', form_html) self.assertIn('value="http://www.example.com/foo"', form_html)
def test_render(self, get_embed): get_embed.return_value = Embed(html='<h1>Hello world!</h1>') block = EmbedBlock() html = block.render('http://www.example.com') # Check that get_embed was called correctly get_embed.assert_any_call('http://www.example.com') # Check that the embed was in the returned HTML self.assertIn('<h1>Hello world!</h1>', html)
def test_deserialize(self): """ Deserialising the JSONish value of an EmbedBlock (a URL) should give us an EmbedValue for that URL """ block = EmbedBlock(required=False) block_val = block.to_python('http://www.example.com/foo') self.assertIsInstance(block_val, EmbedValue) self.assertEqual(block_val.url, 'http://www.example.com/foo') # empty values should yield None empty_block_val = block.to_python('') self.assertEqual(empty_block_val, None)
def test_value_from_form(self): """ EmbedBlock should be able to turn a URL submitted as part of a form back into an EmbedValue """ block = EmbedBlock(required=False) block_val = block.value_from_datadict({'myembed': 'http://www.example.com/foo'}, {}, prefix='myembed') self.assertIsInstance(block_val, EmbedValue) self.assertEqual(block_val.url, 'http://www.example.com/foo') # empty value should result in None empty_val = block.value_from_datadict({'myembed': ''}, {}, prefix='myembed') self.assertEqual(empty_val, None)
def test_render(self, get_embed): get_embed.return_value = Embed(html='<h1>Hello world!</h1>') block = EmbedBlock() block_val = block.to_python('http://www.example.com/foo') temp = template.Template('embed: {{ embed }}') context = template.Context({'embed': block_val}) result = temp.render(context) # Check that the embed was in the returned HTML self.assertIn('<h1>Hello world!</h1>', result) # Check that get_embed was called correctly get_embed.assert_any_call('http://www.example.com/foo')
class BlogStreamBlock(StreamBlock): paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label="Aligned image", icon="image") pullquote = PullQuoteBlock() aligned_html = AlignedHTMLBlock(icon="code", label='Raw HTML') document = DocumentChooserBlock(icon="doc-full-inverse") embed = EmbedBlock(icon="media", label="Embed Media URL")
class CMSStreamBlock(StreamBlock): banner = BannerBlock(label='Banner section') ordered_list = OrderedListBlock( label='Ordered list section', help_text='Use this for sections similar to process') unordered_list = UnorderedListBlock( label='Unordered list block section', help_text='Use this for sections similar to services') image_list = ImageListBlock(label='Image list section') image_grid = ImageGridBlock(label='Image grid section', icon='table') featured_pages = FeaturedPageBlock(label='Featured pages section', icon='doc-full') live_feeds = LiveFeedsBlock(label='Live feeds section (blog/twitter)', icon='wagtail') h2 = CharBlock(icon='title', classname='title') h3 = CharBlock(icon='title', classname='title') h4 = CharBlock(icon='title', classname='title') h5 = CharBlock(icon='title', classname='title') intro = RichTextBlock(icon='pilcrow') paragraph = RichTextBlock(icon='pilcrow') pullquote = PullQuoteBlock(icon='openquote') image = ImageBlock(label='Aligned image', icon='image') document = DocumentChooserBlock(icon='doc-full-inverse') link = LinkBlock(icon='link') embed = EmbedBlock(icon='media') html = AlignedHTMLBlock(icon='code', label='Raw HTML')
class Lesson(Page): parent_page_types = ['lessons.LessonIndex'] date = models.DateField("Post date") body = StreamField([ ('heading', blocks.CharBlock(classname="full title", template='blocks/heading.html')), ('paragraph', blocks.RichTextBlock()), ('code', CodeBlock()), ('image', ImageChooserBlock()), ('video', EmbedBlock()), ]) search_fields = Page.search_fields + [ index.SearchField('body'), index.FilterField('date'), ] content_panels = Page.content_panels + [ FieldPanel('date'), StreamFieldPanel('body'), InlinePanel('techs', label="Mentioned technologies"), InlinePanel('books', label="Mentioned books"), InlinePanel('related_article_links', label="Related links"), ]
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()), ('embed', EmbedBlock())]) feed_image = models.ForeignKey('wagtailimages.Image', 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 + [ FieldPanel('date'), FieldPanel('intro'), StreamFieldPanel('body'), ] promote_panels = [ MultiFieldPanel(Page.promote_panels, "Common page configuration"), ImageChooserPanel('feed_image'), ]
class YouTubeEmbed(blocks.StructBlock): heading = blocks.CharBlock(required=False, max_length=30) text = blocks.RichTextBlock(max_length=255, required=False, features=[ "bold", "italic", "ol", "ul", "link", "document-link", "justify" ]) youtube_embed = EmbedBlock( label="YouTube Video URL", help_text= "Your YouTube URL goes here. Only YouTube video URLs will be accepted.\ The custom 'play' button will be created for valid YouTube URLs.") link = LinkBlock(required=False) customisation = CustomisationBlock(required=False) def clean(self, value): cleaned_data = super().clean(value) # Validating if URL is a valid YouTube URL youtube_embed = cleaned_data.get('youtube_embed').url youtube_finder = OEmbedFinder(providers=[oembed_providers.youtube]) if not youtube_finder.accept(youtube_embed): e = ValidationError('URL must be a YouTube URL') raise ValidationError('Validation error in StructBlock', params={'youtube_embed': ErrorList([e])}) return cleaned_data class Meta: icon = "media" template = "blocks/youtube_embed_block.html"
class FormBuilder(blocks.StreamBlock): text_field = TextFieldBlock() textarea = TextAreaBlock() text = blocks.RichTextBlock() image = ImageChooserBlock() html = blocks.RawHTMLBlock() embed = EmbedBlock()
def test_render_within_structblock(self, get_embed): """ When rendering the value of an EmbedBlock directly in a template (as happens when accessing it as a child of a StructBlock), the proper embed output should be rendered, not the URL. """ get_embed.return_value = Embed(html='<h1>Hello world!</h1>') block = blocks.StructBlock([ ('title', blocks.CharBlock()), ('embed', EmbedBlock()), ]) block_val = block.to_python({ 'title': 'A test', 'embed': 'http://www.example.com/foo' }) temp = template.Template('embed: {{ self.embed }}') context = template.Context({'self': block_val}) result = temp.render(context) self.assertIn('<h1>Hello world!</h1>', result) # Check that get_embed was called correctly get_embed.assert_any_call('http://www.example.com/foo')
class NewsPage(Page): author = models.CharField(max_length=255) date = models.DateField("Дата") body = StreamField([ ('heading', blocks.CharBlock(classname="full title",icon="title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock(icon="image")), ('embedded_video', EmbedBlock(icon="media")), ],null=True,blank=True) tags = ClusterTaggableManager(through=NewsPageTag, blank=True) categories = ParentalManyToManyField('news.NewsCategory', 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('body'), ] content_panels = Page.content_panels + [ FieldPanel('author'), MultiFieldPanel([ FieldPanel('date'), FieldPanel('tags'), FieldPanel('categories', widget=forms.CheckboxSelectMultiple), ], heading="Информация о блоге"), StreamFieldPanel('body'), InlinePanel('gallery_images', label="Фотография обложки"), ]
class GlobalStreamBlock(StreamBlock): paragraph = RichTextBlock(icon="pilcrow", template="blocks/paragraph.html") header = StructBlock([ ('header_text', CharBlock(blank=True, required=False, label='Header')), ('size', ChoiceBlock(choices=[('', 'Select a header size'), ('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4')], blank=True, required=False)) ], classname="title", icon="title", template="blocks/header.html") image = StructBlock([('image', ImageChooserBlock()), ('caption', CharBlock(blank=True, required=False)), ('style', ChoiceBlock(choices=[('', 'Select an image size'), ('full', 'Full-width'), ('contain', 'Contained-width'), ('half', 'Half-width')], required=False))], icon="image", template="blocks/image.html") blockquote = StructBlock([ ('text', TextBlock()), ('attribute_name', CharBlock(blank=True, required=False, label='e.g. Guy Picciotto')), ('attribute_group', CharBlock(blank=True, required=False, label='e.g. Fugazi')), ], icon="openquote", template="blocks/blockquote.html") embed = EmbedBlock( help_text= 'Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks')
class AboutPage(models.Page): uuid = UUIDField(editable=False, default=uuid.uuid4) # Hydra needs uuids body = fields.StreamField([ ('banner', ImageChooserBlock()), ('heading', HeadingBlock()), ('paragraph', blocks.RichTextBlock()), ('video', EmbedBlock()), ('awards', blocks.ListBlock(AwardBlock(label="awards"), template='about/blocks/awards_list.html')) ]) def create_hydra_content(self): cr = CreateContentRequest( headline=self.title, body=self.body.render_as_block(), product_id=ALLOWED_SERVICES.usmf.value, url=self.url, publish_at=self.first_published_at, uuid=str(self.uuid), visibility=100, # 100 is publish is_static=True, # Don't include in aggregators ) # Hydra requires first and last name but does its own look up and ignores these values. cr.set_primary_author(1589, 'Motley', 'Fool Staff') return cr content_panels = models.Page.content_panels + [ StreamFieldPanel('body'), ReadOnlyPanel('uuid', heading='Page UUID'), ]
class CommonEditingBlock(blocks.StreamBlock): image_block = ImageBlock() paragraph_block = ParagraphBlock() blockquote_block = BlockquoteBlock() html = blocks.RawHTMLBlock() embed = EmbedBlock(icon='media') table_block = TableBlock()
class FeaturedAudioBlock(blocks.StructBlock): audio = EmbedBlock(required=True) class Meta: icon='media' label=_('Audio') template='articles/blocks/featured_audio.html' help_text=_('The featured audio is only shown in the detail-view, make sure to also selecte a featured image')
class ProjectEmbedBlock(blocks.StructBlock): title = EmbedBlock(required=False) bgimage = ImageChooserBlock() class Meta: icon = 'cogs' form_classname = 'embed-block' template = 'home/blocks/project_embed.html'
class BlogPage(Page): def main_image(self): gallery_item = self.gallery_images.first() if gallery_item: return gallery_item.image else: return None date = models.DateField("Post date") intro = models.CharField(max_length=250) body = RichTextField(blank=True) tags = ClusterTaggableManager(through=BlogPageTag, blank=True) categories = ParentalManyToManyField('blog.BlogCategory', blank=True) page_content = StreamField([ ('h2_heading', blocks.CharBlock(classname="full title", icon="title")), ('paragraph', blocks.RichTextBlock()), ('blockquote', blocks.BlockQuoteBlock()), ('document', DocumentChooserBlock()), ('image', ImageChooserBlock(icon="image")), ('embed', EmbedBlock()), ('link', blocks.URLBlock()), ('codeblock', CodeBlock()), ], null=True, blank=True) # media = models.ForeignKey( # 'wagtailmedia.Media', # null=True, # blank=True, # on_delete=models.SET_NULL, # related_name='+' # ) video = models.ForeignKey('wagtail_embed_videos.EmbedVideo', verbose_name="Video", 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 + [ MultiFieldPanel([ FieldPanel('date'), FieldPanel('tags'), FieldPanel('categories', widget=forms.CheckboxSelectMultiple), ], heading="Blog information"), FieldPanel('intro'), FieldPanel('body', classname="full"), StreamFieldPanel('page_content'), # MediaChooserPanel('media'), # this breaks the WYSIWYG, so I'm not using it anymore EmbedVideoChooserPanel('video'), InlinePanel('gallery_images', label="Gallery images"), ]
class StoryPage(Page): date = models.DateField("Post date") intro = models.CharField(max_length=250) # intro = models.CharField(max_length=250, help_text="Listen up buddy This thing is non editable Yeah!") author = models.CharField(max_length=250,default="Anonymous") body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('images', blocks.StructBlock( [ ('image', ImageChooserBlock()), ('caption', blocks.CharBlock(blank=True,required=False,null=True)), ], icon='image', )), ('gist', blocks.TextBlock(help_text="Go to gist.github.com to write code and copy the embed Link.")), ('Link', blocks.StructBlock( [ ('URL', blocks.URLBlock()), ('Text', blocks.CharBlock()), ], icon='site', )), ('Quote',blocks.StructBlock( [ ('quote',blocks.BlockQuoteBlock()), ('Author',blocks.TextBlock(max_length=50)), ], icon='quote' )), ('embed',EmbedBlock()), ]) tags = ClusterTaggableManager(through=StoryPageTag, blank=True) categories = ParentalManyToManyField('story.StoryCategory', blank=True) search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), ] content_panels = Page.content_panels + [ MultiFieldPanel([ FieldPanel('date'), FieldPanel('author'), FieldPanel('tags'), FieldPanel('categories', widget=forms.CheckboxSelectMultiple), ], heading="Information About Story"), FieldPanel('intro'), StreamFieldPanel('body'), ]
class ProductStreamBlock(StreamBlock): h2 = CharBlock(icon="title", classname="title") h3 = CharBlock(icon="title", classname="title") h4 = CharBlock(icon="title", classname="title") intro = TextBlock(icon="pilcrow") paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label="Aligned image", icon="image") embed = EmbedBlock() document = DocumentChooserBlock(icon="doc-full-inverse")
class FullWidthEmbedBlock(blocks.StructBlock): embed = EmbedBlock(required=True, help_text="Enter URL for the embed block") embed_caption = RichTextMiniBlock(required=False) class Meta: icon = 'media' label = 'Full width embed' template = 'article/blocks/full_width_embed.html'
class HomePage(Page): tagline = models.CharField(max_length=255, null=True, blank=True) body = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embeded_content', EmbedBlock()), ('raw_HTML', RawHTMLBlock()), ])
class FabricationStreamBlock(StreamBlock): title_text_image = TitleTextImageBlock() image_title_text = ImageTitleTextBlock() title_text_imagelist = TitleTextImageListBlock() item_list = ListBlock(TitleAndTextBlock(), icon='list-ul') numbered_item_list = ListBlock(TitleAndTextBlock(), icon='list-ol') paragraph = RichTextBlock(icon="pilcrow") image = ImageChooserBlock() video = EmbedBlock()
class SimplePage(Page, MeetupMixin, SponsorMixin): """ allowed url to embed listed in lib/python3.4/site-packages/wagtail/wagtailembeds/oembed_providers.py """ body = StreamField([('heading', blocks.CharBlock(icon="home", classname="full title")), ('paragraph', blocks.RichTextBlock(icon="edit")), ('video', EmbedBlock(icon="media")), ('image', ImageChooserBlock(icon="image")), ('slide', EmbedBlock(icon="media")), ('html', RawHTMLBlock(icon="code"))]) content_panels = Page.content_panels + [ StreamFieldPanel('body'), ] settings_panels = Page.settings_panels + MeetupMixin.settings_panels + SponsorMixin.settings_panels
class SimpleBodyBlock(blocks.StreamBlock): Heading = HeadingBlock() Paragraph = ParagraphBlock() Image = ImageBlock() Embed = EmbedBlock(icon="site") List = blocks.ListBlock(blocks.RichTextBlock(label="item"), icon="list-ul") Sharable = SharableBlock() PullQuote = PullQuoteBlock() Quote = SimpleQuoteBlock() RelatedItems = RelatedItemsBlock()
class StoryBlock(StreamBlock): h2 = CharBlock(icon="title", classname="title") h3 = CharBlock(icon="title", classname="title") h4 = CharBlock(icon="title", classname="title") intro = RichTextBlock(icon="pilcrow") paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label="Aligned image") bustout = BustoutBlock() pullquote = PullQuoteBlock() raw_html = RawHTMLBlock(label='Raw HTML', icon="code") embed = EmbedBlock(icon="code")
def test_clean(self): required_block = EmbedBlock() nonrequired_block = EmbedBlock(required=False) # a valid EmbedValue should return the same value on clean cleaned_value = required_block.clean(EmbedValue('http://www.example.com/foo')) self.assertIsInstance(cleaned_value, EmbedValue) self.assertEqual(cleaned_value.url, 'http://www.example.com/foo') cleaned_value = nonrequired_block.clean(EmbedValue('http://www.example.com/foo')) self.assertIsInstance(cleaned_value, EmbedValue) self.assertEqual(cleaned_value.url, 'http://www.example.com/foo') # None should only be accepted for nonrequired blocks cleaned_value = nonrequired_block.clean(None) self.assertEqual(cleaned_value, None) with self.assertRaises(ValidationError): required_block.clean(None)
def test_default(self): block1 = EmbedBlock() self.assertEqual(block1.get_default(), None) block2 = EmbedBlock(default='') self.assertEqual(block2.get_default(), None) block3 = EmbedBlock(default=None) self.assertEqual(block3.get_default(), None) block4 = EmbedBlock(default='http://www.example.com/foo') self.assertIsInstance(block4.get_default(), EmbedValue) self.assertEqual(block4.get_default().url, 'http://www.example.com/foo') block5 = EmbedBlock(default=EmbedValue('http://www.example.com/foo')) self.assertIsInstance(block5.get_default(), EmbedValue) self.assertEqual(block5.get_default().url, 'http://www.example.com/foo')