Esempio n. 1
0
    def test_custom_editor_in_rich_text_block(self):
        block = RichTextBlock(editor='custom')

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        # Check that the custom plugin options are being passed in the hallo initialiser
        self.assertIn('makeHalloRichTextEditable("body", {"halloheadings": {"formatBlocks": ["p", "h2"]}});', form_html)
Esempio n. 2
0
    def test_features_option_on_rich_text_block(self):
        # a 'features' list passed on the RichTextBlock
        # should override the list in OPTIONS
        block = RichTextBlock(features=['h2', 'embed'])

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        self.assertIn('"type": "header-two"', form_html)
        self.assertIn('"type": "EMBED"', form_html)
        self.assertNotIn('"type": "IMAGE""', form_html)
        self.assertNotIn('"type": "ordered-list-item""', form_html)
Esempio n. 3
0
    def test_features_list_on_rich_text_block(self):
        block = RichTextBlock(features=['blockquote', 'embed', 'made-up-feature'])

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        # Check that the custom plugin options are being passed in the hallo initialiser
        self.assertIn('"halloblockquote":', form_html)
        self.assertIn('"hallowagtailembeds":', form_html)
        self.assertNotIn('"hallolists":', form_html)
        self.assertNotIn('"hallowagtailimage":', form_html)

        # check that media (js/css) from the features is being imported
        media_html = str(block.media)
        self.assertIn('testapp/js/hallo-blockquote.js', media_html)
        self.assertIn('testapp/css/hallo-blockquote.css', media_html)
        # check that we're NOT importing media for the default features we're not using
        self.assertNotIn('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js', media_html)
Esempio n. 4
0
    def test_custom_features_option_on_rich_text_block(self):
        block = RichTextBlock(editor='custom')

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        # Check that the custom plugin options are being passed in the hallo initialiser
        self.assertIn('"halloquotation":', form_html)
        self.assertIn('"hallowagtailimage":', form_html)
        self.assertNotIn('"hallowagtailembeds":', form_html)
        self.assertNotIn('"hallolists":', form_html)

        # a 'features' list passed on the RichTextBlock
        # should override the list in OPTIONS
        block = RichTextBlock(editor='custom', features=['quotation', 'embed'])

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        self.assertIn('"halloquotation":', form_html)
        self.assertIn('"hallowagtailembeds":', form_html)
        self.assertNotIn('"hallowagtailimage":', form_html)
        self.assertNotIn('"hallolists":', form_html)

        # check that media (js/css) from the features is being imported
        media_html = str(block.media)
        self.assertIn('testapp/js/hallo-quotation.js', media_html)
        self.assertIn('testapp/css/hallo-quotation.css', media_html)
        # check that we're NOT importing media for the default features we're not using
        self.assertNotIn('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js', media_html)
Esempio n. 5
0
class StreamPage(Page):
    body = StreamField([
        ('text', CharBlock()),
        ('rich_text', RichTextBlock()),
        ('image', ExtendedImageChooserBlock()),
        ('product',
         StructBlock([
             ('name', CharBlock()),
             ('price', CharBlock()),
         ])),
        ('raw_html', RawHTMLBlock()),
    ])

    api_fields = ('body', )

    content_panels = [
        FieldPanel('title'),
        StreamFieldPanel('body'),
    ]

    preview_modes = []
Esempio n. 6
0
class FormFieldsBlock(StreamBlock):
    text_markup = RichTextBlock(group=_('Custom'),
                                label=_('Section text/header'))
    char = CharFieldBlock(group=_('Fields'))
    text = TextFieldBlock(group=_('Fields'))
    number = NumberFieldBlock(group=_('Fields'))
    checkbox = CheckboxFieldBlock(group=_('Fields'))
    radios = RadioButtonsFieldBlock(group=_('Fields'))
    dropdown = DropdownFieldBlock(group=_('Fields'))
    checkboxes = CheckboxesFieldBlock(group=_('Fields'))
    date = DateFieldBlock(group=_('Fields'))
    time = TimeFieldBlock(group=_('Fields'))
    datetime = DateTimeFieldBlock(group=_('Fields'))
    image = ImageFieldBlock(group=_('Fields'))
    file = FileFieldBlock(group=_('Fields'))
    multi_file = MultiFileFieldBlock(group=_('Fields'))
    group_toggle = GroupToggleBlock(group=_("Custom"))
    group_toggle_end = GroupToggleEndBlock(group=_("Custom"))

    class Meta:
        label = _('Form fields')
Esempio n. 7
0
class BodyStreamBlock(StreamBlock):
    h3 = CharBlock(icon="title",
                   classname="title",
                   label="h3",
                   template="website/blocks/h3.html")
    h4 = CharBlock(icon="title",
                   classname="title",
                   label="h4",
                   template="website/blocks/h4.html")

    paragraph = RichTextBlock(
        icon="pilcrow",
        features=['bold', 'italic', 'ol', 'ul', 'link', 'document-link'])
    table = TableBlock()
    dl = ListBlock(DefinitionListItem,
                   label='Definition list',
                   icon="list-ul",
                   template="website/blocks/dl.html")
    aligned_image = ImageBlock(label="Aligned image", icon="image")
    document = DocumentChooserBlock(icon="doc-full-inverse")
    video = LocalVideoBlock(icon="fa-video-camera")
    math = MathMLBlock(icon="fa-calculator")
class CommonStreamBlock(StreamBlock):
    # Simple Blocks
    title = CharBlock(classname="full title", blank=True, max_length=200, icon='title', template='streams/title_block.html')
    videoembed = EmbedBlock("Video embed (YouTube and Facebook)", label='Enter Video URL',  max_length=500, icon='media', null=True, blank=True, template='streams/video_embed_block.html')
    image = ImageChooserBlock("Choose an image ...", label='Choose an image ...', icon='image', template='streams/image_block.html')
    googlemap = CharBlock("Google Calendar URL", label='Enter Google Map URL', icon='site', max_length=500, null=True, blank=True, template='streams/google_map_block.html')
    googlecal = CharBlock("Google Calendar URL", label='Enter Google Calendar URL', max_length=500, icon='date', null=True, blank=True, template='streams/google_cal_block.html')
    # Complex Blocks
    code = ContentStreamBlock()
    hero = HeroBlock()
    richtext = RichTextBlock()
    card = CardBlock()
    cards = CardGroupBlock()
    carousel = CarouselBlock()
    button = ButtonBlock()
    buttongroup = ButtonGroupBlock()
    testimonial = TestimonialBlock()

    class Meta:
        icon = 'cogs'
        null = True
        blank = True
class WarningCalloutBlock(FlattenValueContext, StructBlock):

    title = CharBlock(required=True, default='Important')
    visually_hidden_prefix = BooleanBlock(
        required=False,
        label='Visually hidden prefix',
        help_text=
        'If the title doesn\'t contain the word \"Important\" select this to add a visually hidden \"Important\", to aid screen readers.'
    )
    heading_level = IntegerBlock(
        required=True,
        min_value=2,
        max_value=6,
        default=3,
        help_text=
        'The heading level affects users with screen readers. Default=3, Min=2, Max=6.'
    )
    body = RichTextBlock(required=True)

    class Meta:
        icon = 'warning'
        template = 'wagtailnhsukfrontend/warning_callout.html'
Esempio n. 10
0
class InformationPage(JanisBasePage):
    janis_url_page_type = "information"

    description = models.TextField(blank=True, verbose_name='Write a description of this page')
    options = StreamField(
        [
            ('option', RichTextBlock(
                features=WYSIWYG_GENERAL,
                label='Option'
            ))
        ],
        verbose_name='Add option sections as needed.',
        help_text='Options are needed when the reader needs to make a choice between a few options, such as ways to fill out a form (online, by phone, in person, etc.).',
        blank=True
    )

    additional_content = RichTextField(
        features=WYSIWYG_GENERAL,
        verbose_name='Write any additional content describing the service',
        blank=True
    )

    # TODO: Add images array field

    base_form_class = InformationPageForm

    content_panels = [
        FieldPanel('title_en', widget=countMe),
        FieldPanel('title_es', widget=countMe),
        FieldPanel('title_ar'),
        FieldPanel('title_vi'),
        InlinePanel('topics', label='Topics'),
        InlinePanel('related_departments', label='Related Departments'),
        FieldPanel('description', widget=countMeTextArea),
        # hidden for now, see: https://austininnovation.slack.com/archives/C8T4YD23T/p1570659780017500?thread_ts=1570659723.017100&cid=C8T4YD23T
        # StreamFieldPanel('options'),
        FieldPanel('additional_content'),
        InlinePanel('contacts', label='Contacts'),
    ]
Esempio n. 11
0
class Table(StructBlock):
    class Meta:
        help_text = 'Displays tabular data with an optional heading.'
        icon = 'list-ol'
        label = 'Table'
        form_template = 'publications/block_forms/custom_struct.html'
        template = 'publications/blocks/table.html'

    heading = CharBlock(required=False)
    table = TableBlock()
    caption = RichTextBlock(
        required=False,
        features=FOOTNOTE_RICHTEXT_FEATURES,
        help_text='Optional: caption text to appear below the table')
    caption_link = URLBlock(
        required=False,
        help_text='Optional: external link to appear below the table')
    caption_label = CharBlock(
        required=False,
        help_text=
        'Optional: label for the caption link, defaults to the link if left blank'
    )
Esempio n. 12
0
class EscuelaVarillajeUbicacionLightBlock(StructBlock):
    nombre = CharBlock(classname="text-white mt-0", required=False)
    clase_css = ChoiceBlock(choices=[
        ('bg-white', 'bg-white'),
        ('bg-transparent', 'bg-transparent'),
        ('bg-light', 'bg-light'),
    ])
    titulo = CharBlock(classname="text-white mt-0", required=False)
    cuerpo = RichTextBlock(required=False)
    telefono = blocks.CharBlock(max_length=22)
    calle = blocks.CharBlock(max_length=255)
    colonia = blocks.CharBlock(max_length=255)
    ciudad = blocks.CharBlock(max_length=255)
    estado = blocks.CharBlock(max_length=255)
    facebook_url = blocks.URLBlock()
    youtube_url = blocks.URLBlock()
    instagram_url = blocks.URLBlock()
    email = blocks.EmailBlock()

    class Meta:
        template = 'escueladevarillaje/blocks/escuela_varillaje_ubicacion_light_block.html'
        icon = "fa-globe"
class ArticlePage(HeadlessPreviewMixin, Page):
    content = StreamField(
        [('section', SectionBlock()),
         ('content', RichTextBlock(default='Add your content here!')),
         ('media', EmbedBlock()), ('file', DocumentChooserBlock()),
         ('link', PageChooserBlock()), ('faqs', FAQListBlock(label='FAQs'))],
        blank=True)
    # body = RichTextField(blank=True)
    legacyArticleId = models.IntegerField(blank=True, null=True)
    search_fields = Page.search_fields + [
        index.SearchField('content'),
        index.SearchField('legacyArticleId')
    ]

    content_panels = Page.content_panels + [StreamFieldPanel('content')]

    parent_page_types = ['ArticleIndexPage']

    # Specifies what content types can exist as children of ArticlePage.
    # Empty list means that no child content types are allowed.
    subpage_types = []

    api_fields = [APIField('content'), APIField('legacyArticleId')]
Esempio n. 14
0
class AccordionBlock(StructBlock):
    compact = BooleanBlock(
        required=False,
        help_text='Display a compact accordion for use between paragraphs.')
    panels = ListBlock(
        StructBlock([
            ('title',
             TextBlock(
                 help_text=
                 'The headline to display when the accordion panel is closed.')
             ),
            ('body',
             RichTextBlock(
                 help_text=
                 'The inner content of this accordion panel. It is initially hidden.'
             ))
        ],
                    label='Panel'))

    class Meta:
        icon = 'emoji-scroll'
        template = 'blocks/accordion.html'
        help_text = 'Accordions are elements that help you organize and navigate multiple documents in a single container. They can be used for switching between items in the container.'
Esempio n. 15
0
 def test_that_new_article_page_should_has_all_mandatory_parameters(
         self, parameter_name, parameter_value):
     author = BossFactory()
     body_block = StreamBlock([(ArticleBodyBlockNames.PARAGRAPH.value,
                                RichTextBlock())])
     body = StreamValue(body_block, [
         (ArticleBodyBlockNames.PARAGRAPH.value, RichText("Hello, World"))
     ])
     test_title = "Simple Article Title"
     blog_article_parameter = {
         "title": test_title,
         "page_title": test_title,
         "date": datetime.now(),
         "body": body,
         "author": author,
         "read_time": 7,
         "views": 0,
         parameter_name: parameter_value,
     }
     with self.assertRaises(ValidationError):
         blog_article_page = BlogArticlePage(**blog_article_parameter)
         self.blog_index_page.add_child(instance=blog_article_page)
         blog_article_page.save()
Esempio n. 16
0
class TypesetStreamBlock(StreamBlock):
    """
    The custom blocks that can be used under an element with the typeset class (not sections)
    """
    anchor = AnchorBlock()
    paragraph_block = RichTextBlock(
        icon='fa-paragraph',
        template='blocks/paragraph_block.html',
        features=RICHTEXT_FEATURES_NO_FOOTNOTES
    )
    block_quote = BlockQuote()
    button_block = ButtonBlock()
    link_block = LinkBlock()
    image = TypeSetImageBlock()
    video = EmbedBlock(
        help_text='Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks',
        icon='fa-video-camera',
        template='blocks/embed_block.html',
        required=False
    )
    cta = CallToActionBlock()

    required = False
Esempio n. 17
0
class ContentStreamBlock(StreamBlock):
    paragraph = RichTextBlock(icon='fa-paragraph')
    bigger_heading = TextBlock(icon='fa-header',
                               template='blocks/h2.html',
                               label='H2')
    heading = TextBlock(icon='fa-header',
                        template='blocks/h3.html',
                        label='H3')
    smaller_heading = TextBlock(icon='fa-header',
                                template='blocks/h4.html',
                                label='H4')
    smallest_heading = TextBlock(icon='fa-header',
                                 template='blocks/h5.html',
                                 label='H5')
    image = CaptionedImageBlock()
    download = DocumentChooserBlock(icon='fa-download',
                                    template='blocks/download.html')
    accordion = AccordionBlock()
    notice = NoticeBlock()
    embed = EmbedBlock(icon="media")
    button = CallToActionButtonBlock()
    simple_flow_boxes = SimpleFlowBlockList()
    detailed_flow_boxes = DetailedFlowBlockList()
    periodic_boxes = PeriodicBlockList()
    highlight_block = HightlightBlock()
    slider_block = SimpleSliderBlock()
    hr_block = StructBlock(icon='fa-window-minimize',
                           template='blocks/hr.html',
                           label='Divider')
    cards = ListBlock(CardBlock(),
                      icon='fa-clone',
                      template='blocks/cards.html')
    graphic_link_grid_grid = GraphicLinkGridBlock()
    featured_content_block = FeaturedContentBlock()

    class Meta:
        template = 'blocks/streamfield.html'
Esempio n. 18
0
class BootstrapWell(StructBlock):
    """
    Custom 'StructBlock' that allows user to make a bootstrap well.
    (optimized for bootstrap 4 using card)
    """
    message = RichTextBlock(help_text="Enter some message inside well")
    well_bg_color = ChoiceBlock(choices=[
        ('bg-primary', 'DEFAULT'),
        ('bg-secondary', 'GREY'),
        ('bg-success', 'GREEN'),
        ('bg-danger', 'RED'),
        ('bg-warning', 'ORANGE'),
        ('bg-dark', 'DARK'),
        ('bg-light', 'LIGHT'),
    ], blank=True, required=False, help_text="select a background color")
    custom_class = TextBlock(
        required=False,
        blank=True,
        help_text="control this element by giving unique class names "
                  "separated by space and styling the class in css")

    class Meta:
        icon = "fa-window-minimize"
        template = "blocks/bootstrap/well.html"
Esempio n. 19
0
class CaptionedImage(StructBlock):
    class Meta:
        help_text = 'Displays an image with an optionally linked caption.'
        icon = 'image'
        label = 'Captioned image'
        form_template = 'publications/block_forms/custom_struct.html'
        template = 'publications/blocks/captioned_image.html'

    image = ImageChooserBlock(help_text='Optimal minimum width 800px')
    descriptive_text = RichTextBlock(
        required=False,
        features=FOOTNOTE_RICHTEXT_FEATURES,
        help_text='Optional: descriptive text to appear above the image')
    caption = TextBlock(
        required=False,
        help_text='Optional: caption text to appear below the image')
    caption_link = URLBlock(
        required=False,
        help_text='Optional: external link to appear below the image')
    caption_label = CharBlock(
        required=False,
        help_text=
        'Optional: label for the caption link, defaults to the link if left blank'
    )
Esempio n. 20
0
class ImprovisationTypePage(Page, MenuPageMixin):
    body = StreamField([
        ('rich_text',
         RichTextBlock(features=[
             'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'bold', 'italic', 'ol', 'hr',
             'link', 'document-link', 'image', 'embed'
         ])), ('image', ImageBlock()),
        ('video', VideoEmbedBlock(required=False))
    ])

    def get_context(self, request, *args, **kwargs):
        ctx = super().get_context(request, *args, **kwargs)
        ctx['improv_type_pages'] = pack_nav_pages(
            [p.specific for p in self.get_siblings()], self)
        return ctx

    class Meta:
        verbose_name = "Improvisation Type Page"

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

    settings_panels = Page.settings_panels + [menupage_panel]

    parent_page_types = ['main.ImprovisationTypeIndexPage']
Esempio n. 21
0
class ProjectPage(
        ArchiveablePageAbstract,
        BasicPageAbstract,
        ContentPage,
        FeatureablePageAbstract,
        ShareablePageAbstract,
):
    body = StreamField(
        BasicPageAbstract.body_default_blocks +
        BasicPageAbstract.body_poster_block + [
            ('igc_timeline',
             StructBlock([
                 ('date', CharBlock(required=True)),
                 ('title', CharBlock(required=False)),
                 ('body', RichTextBlock(required=False)),
                 ('location', CharBlock(required=False)),
                 ('countries_represented', ImageChooserBlock(required=False)),
                 ('outcomes',
                  StreamBlock(
                      [
                          ('outcome',
                           StructBlock([
                               ('date', DateBlock(required=False)),
                               ('text', RichTextBlock(required=False)),
                           ])),
                      ],
                      required=False,
                  )),
                 ('witnesses',
                  StreamBlock(
                      [
                          ('witness_date',
                           StructBlock([
                               ('date', DateBlock(required=False)),
                               ('witnesses',
                                StreamBlock([
                                    ('witnesses_full_session',
                                     StructBlock([
                                         ('title', CharBlock(required=False)),
                                         ('witness_transcript',
                                          URLBlock(required=False)),
                                         ('witness_video',
                                          URLBlock(required=False)),
                                     ])),
                                    ('witness',
                                     StructBlock([
                                         ('name', CharBlock(required=False)),
                                         ('title', CharBlock(required=False)),
                                         ('witness_transcript',
                                          URLBlock(required=False)),
                                         ('witness_video',
                                          URLBlock(required=False)),
                                     ])),
                                ], )),
                           ])),
                      ],
                      required=False,
                  )),
             ])),
        ],
        blank=True,
    )
    project_contacts = StreamField(
        [
            ('contact',
             PageChooserBlock(required=True, page_type='people.PersonPage')),
        ],
        blank=True,
    )
    project_leads = StreamField(
        [
            ('project_lead',
             PageChooserBlock(required=True, page_type='people.PersonPage')),
            ('external_project_lead', CharBlock(required=True)),
        ],
        blank=True,
    )
    project_members = StreamField(
        [
            ('project_member',
             PageChooserBlock(required=True, page_type='people.PersonPage')),
            ('external_project_member', CharBlock(required=True)),
        ],
        blank=True,
    )
    project_types = ParentalManyToManyField('research.ProjectType', blank=True)
    related_files = StreamField(
        [
            ('file', DocumentChooserBlock()),
        ],
        blank=True,
    )

    # Reference field for the Drupal-Wagtail migrator. Can be removed after.
    drupal_node_id = models.IntegerField(blank=True, null=True)

    content_panels = [
        BasicPageAbstract.title_panel,
        BasicPageAbstract.body_panel,
        MultiFieldPanel(
            [
                FieldPanel('publishing_date'),
                FieldPanel('project_types'),
            ],
            heading='General Information',
            classname='collapsible',
        ),
        MultiFieldPanel(
            [
                StreamFieldPanel('project_leads'),
                StreamFieldPanel('project_members'),
                StreamFieldPanel('project_contacts'),
            ],
            heading='People',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                ImageChooserPanel('image_hero'),
            ],
            heading='Images',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                FieldPanel('topics'),
                StreamFieldPanel('related_files'),
            ],
            heading='Related',
            classname='collapsible collapsed',
        ),
    ]

    promote_panels = Page.promote_panels + [
        FeatureablePageAbstract.feature_panel,
        ShareablePageAbstract.social_panel,
    ]

    settings_panels = Page.settings_panels + [
        ArchiveablePageAbstract.archive_panel,
    ]

    parent_page_types = ['core.BasicPage', 'research.ProjectListPage']
    subpage_types = []
    templates = 'research/project_page.html'

    class Meta:
        verbose_name = 'Project'
        verbose_name_plural = 'Projects'
Esempio n. 22
0
class RichTextNoFootnotes(AbstractRichText):
    class Meta:
        template = 'publications/blocks/rich_text_no_footnotes.html'

    rich_text = RichTextBlock(features=RICHTEXT_FEATURES_NO_FOOTNOTES, )
Esempio n. 23
0
class RichText(AbstractRichText):
    class Meta:
        template = 'publications/blocks/rich_text.html'

    rich_text = RichTextBlock(features=RICHTEXT_FEATURES, )
Esempio n. 24
0
class DetailedBlock(BaseBlock):

    short_description = TextBlock(required=False)
    detailed_description = TextBlock(required=False)
    left_detailed_content = RichTextBlock(required=False)
    right_detailed_content = RichTextBlock(required=False)
Esempio n. 25
0
class InfoBlock(StructBlock):
    title = CharBlock(required=True)
    photo = ImageChooserBlock(required=True)
    summary = RichTextBlock(required=True)
    action = CharBlock(required=False)
    url = URLBlock(required=False)
Esempio n. 26
0
class MultimediaPage(
        BasicPageAbstract,
        ContentPage,
        FeatureablePageAbstract,
        FromTheArchivesPageAbstract,
        ShareablePageAbstract,
        ThemeablePageAbstract,
):
    class MultimediaTypes(models.TextChoices):
        AUDIO = ('audio', 'Audio')
        VIDEO = ('video', 'Video')

    image_square = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Square image',
    )
    multimedia_series = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    multimedia_type = models.CharField(
        blank=False,
        max_length=8,
        choices=MultimediaTypes.choices,
    )
    multimedia_url = models.URLField(
        blank=True,
        verbose_name='Multimedia URL',
        help_text=
        'The URL of the multimedia source from YouTube or Simplecast.',
    )
    podcast_audio_duration = models.CharField(blank=True, max_length=8)
    podcast_audio_file_size = models.IntegerField(blank=True, null=True)
    podcast_audio_url = models.URLField(blank=True)
    podcast_episode = models.IntegerField(
        blank=True,
        null=True,
        verbose_name='Episode Number',
    )
    podcast_guests = StreamField(
        [
            ('guest', CharBlock(required=True)),
        ],
        blank=True,
    )
    podcast_season = models.IntegerField(
        blank=True,
        null=True,
        verbose_name='Season Number',
    )
    podcast_subtitle = models.CharField(blank=True, max_length=255)
    podcast_video_duration = models.CharField(blank=True, max_length=8)
    podcast_video_file_size = models.IntegerField(blank=True, null=True)
    podcast_video_url = models.URLField(blank=True)
    projects = ParentalManyToManyField('research.ProjectPage', blank=True)
    speakers = StreamField(
        [
            ('speaker',
             PageChooserBlock(required=True, page_type='people.PersonPage')),
            ('external_speaker', CharBlock(required=True)),
        ],
        blank=True,
    )
    transcript = StreamField(
        [
            ('accordion',
             StructBlock([
                 ('title', CharBlock(required=True)),
                 ('text', RichTextBlock(required=True)),
             ])),
            ('read_more',
             StructBlock([
                 ('title', CharBlock(required=True)),
                 ('text', RichTextBlock(required=True)),
             ])),
        ],
        blank=True,
    )
    video_chapters = StreamField(
        [
            ('video_chapter',
             StructBlock([
                 ('chapter_title', CharBlock(required=True)),
                 ('location_time', IntegerBlock(required=True)),
                 ('chapter_description', TextBlock(required=False)),
             ])),
        ],
        blank=True,
    )
    youtube_id = models.CharField(
        blank=True,
        max_length=32,
        verbose_name='YouTube ID',
        help_text=
        'Enter just the YouTube ID for this video. This is the series of letters and numbers found either at www.youtube.com/embed/[here], or www.youtube.com/watch?v=[here]. This is used for the video chaptering below.',
    )

    # Reference field for the Drupal-Wagtail migrator. Can be removed after.
    drupal_node_id = models.IntegerField(blank=True, null=True)

    content_panels = [
        BasicPageAbstract.title_panel,
        BasicPageAbstract.body_panel,
        MultiFieldPanel(
            [
                FieldPanel('multimedia_type'),
                FieldPanel('publishing_date'),
                FieldPanel('multimedia_url'),
            ],
            heading='General Information',
            classname='collapsible',
        ),
        MultiFieldPanel(
            [
                StreamFieldPanel('speakers'),
            ],
            heading='Speakers',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                FieldPanel('youtube_id'),
                StreamFieldPanel('video_chapters'),
            ],
            heading='Video Chapters',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                StreamFieldPanel('transcript'),
            ],
            heading='Transcript',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                FieldPanel('podcast_subtitle'),
                FieldPanel('podcast_season'),
                FieldPanel('podcast_episode'),
                StreamFieldPanel('podcast_guests'),
                MultiFieldPanel(
                    [
                        FieldPanel('podcast_audio_url'),
                        FieldPanel('podcast_audio_duration'),
                        FieldPanel('podcast_audio_file_size'),
                    ],
                    heading='Audio',
                    classname='collapsible collapsed',
                ),
                MultiFieldPanel(
                    [
                        FieldPanel('podcast_video_url'),
                        FieldPanel('podcast_video_duration'),
                        FieldPanel('podcast_video_file_size'),
                    ],
                    heading='Video',
                    classname='collapsible collapsed',
                ),
            ],
            heading='Podcast Details',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                ImageChooserPanel('image_hero'),
                ImageChooserPanel('image_square'),
            ],
            heading='Images',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            [
                PageChooserPanel(
                    'multimedia_series',
                    ['multimedia.MultimediaSeriesPage'],
                ),
                FieldPanel('topics'),
                FieldPanel('projects'),
            ],
            heading='Related',
            classname='collapsible collapsed',
        ),
        FromTheArchivesPageAbstract.from_the_archives_panel,
    ]

    promote_panels = Page.promote_panels + [
        FeatureablePageAbstract.feature_panel,
        ShareablePageAbstract.social_panel,
    ]

    settings_panels = Page.settings_panels + [
        ThemeablePageAbstract.theme_panel,
    ]

    parent_page_types = ['multimedia.MultimediaListPage']
    subpage_typse = []
    templates = 'multimedia/multimedia_page.html'

    class Meta:
        verbose_name = 'Multimedia'
        verbose_name_plural = 'Multimedia'
Esempio n. 27
0
class ProgramPage(Page):
    """
    CMS page representing the department e.g. Biology
    """
    description = StreamField(
        [('paragraph', RichTextBlock(blank=True)),
         ('image_with_link',
          ImageWithLinkBlock(help_text='Upload an image with a clickable link',
                             blank=True))],
        blank=True,
        help_text='The description shown on the program page')

    faculty_description = models.CharField(
        max_length=500,
        blank=True,
        null=True,
        help_text=
        'The text to be shown as an introduction in the Faculty section')
    program = models.OneToOneField(
        'courses.Program',
        null=True,
        on_delete=models.SET_NULL,
        help_text='The program for this page',
    )
    program_home_page_url = models.URLField(
        blank=True,
        null=True,
        help_text=
        "A url for an external homepage. There will be a link to this url from the program page."
    )
    title_program_home_page_url = models.TextField(
        blank=True, help_text='The text for the link to an external homepage.')
    program_contact_email = models.EmailField(
        blank=True, null=True, help_text="A contact email for the program.")
    background_image = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='The hero image on the program page')
    title_over_image = RichTextField(blank=True)

    thumbnail_image = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=(
            'Thumbnail size must be at least 690x530 pixels. '
            'Thumbnails are cropped down to this size, preserving aspect ratio.'
        ),
    )
    program_letter_logo = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        ('The logo that will appear at the top of the program congratulation letter.'
         ),
    )
    program_letter_header_text = RichTextField(
        blank=True,
        null=True,
        help_text="Header text that will appear next to the logo.")

    program_letter_footer = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        ('The logo that will appear at the bottom of the program congratulation letter.'
         ),
    )

    program_letter_text = RichTextField(
        blank=True,
        null=True,
        help_text="Text that will appear on the program congratulation letter."
    )

    program_letter_footer_text = RichTextField(
        blank=True,
        null=True,
        help_text=
        "Footer text that will appear on the program congratulation letter.")

    program_subscribe_link = models.URLField(
        blank=True,
        null=True,
        help_text=
        "A url for I'm interested button, if there is no course(s) available.")

    subpage_types = ['FaqsPage', 'CourseTeamTabPage', 'ProgramTabPage']
    content_panels = Page.content_panels + [
        StreamFieldPanel('description'),
        FieldPanel('program'),
        FieldPanel('thumbnail_image'),
        FieldPanel('program_home_page_url'),
        FieldPanel('title_program_home_page_url'),
        FieldPanel('program_contact_email'),
        FieldPanel('background_image'),
        FieldPanel('title_over_image'),
        FieldPanel('faculty_description'),
        FieldPanel('program_letter_logo'),
        FieldPanel('program_letter_header_text'),
        FieldPanel('program_letter_footer'),
        FieldPanel('program_letter_text'),
        FieldPanel('program_letter_footer_text'),
        FieldPanel('program_subscribe_link'),
        InlinePanel('courses', label='Program Courses'),
        InlinePanel('info_links', label='More Info Links'),
        InlinePanel('faculty_members', label='Faculty'),
        InlinePanel('semester_dates', label='Future Semester Dates'),
        InlinePanel('course_certificate_signatories',
                    label='Course Certificate Signatories'),
        InlinePanel('program_certificate_signatories',
                    label='Program Certificate Signatories'),
        InlinePanel('program_letter_signatories',
                    label='Program Letter Signatories'),
    ]

    def get_context(self, request, *args, **kwargs):
        context = get_program_page_context(self, request)
        context['active_tab'] = 'about'
        child_pages = self.get_children()
        course_team_page = child_pages.type(CourseTeamTabPage).live().first()

        # the course team tab should always be second, first one is about tab
        context['child_pages'] = [course_team_page] + [
            page for page in child_pages.not_type(CourseTeamTabPage)
        ]
        context['course_team_page'] = course_team_page

        return context
Esempio n. 28
0
class PrintSeries(Page):
    footer_colour = models.CharField(max_length=255, blank=True, null=True)
    """ All Series Page """
    year = models.CharField(max_length=255, blank=True, null=True)
    series_description = RichTextField(blank=True)
    print_type = models.CharField(max_length=255,
                                  blank=True,
                                  null=True,
                                  help_text='E.g "Photogram Screen Print"')
    edition = models.CharField('Edition of',
                               max_length=255,
                               blank=True,
                               null=True)
    dim_x = models.IntegerField(blank=True, null=True)
    dim_y = models.IntegerField(blank=True, null=True)

    items = StreamField([
        ('item', StructBlock([('select_page', PageChooserBlock(blank=True))])),
    ],
                        blank=True)

    story = StreamField(
        [('title',
          CharBlock(blank=True,
                    classname="full title",
                    template='home/blocks/inner_title.html',
                    icon='title')),
         ('text_block',
          StructBlock([
              ('text', RichTextBlock(blank=True)),
              ('size',
               ChoiceBlock(required=False,
                           max_length=20,
                           choices=(
                               (u'6', u'Half'),
                               (u'9', u'Full'),
                           ))),
          ],
                      template='home/blocks/text.html',
                      icon='pilcrow')),
         ('image',
          StructBlock([
              ('image', ImageChooserBlock(blank=True, required=False)),
              ('caption', CharBlock(required=False)),
              ('size',
               ChoiceBlock(required=False,
                           max_length=20,
                           choices=(
                               (u'4', u'Small'),
                               (u'6', u'Medium'),
                               (u'8', u'Large'),
                           ))),
          ],
                      template='home/blocks/image.html',
                      icon='image'))],
        blank=True)

    behind_the_scenes = StreamField(
        [('text_block',
          StructBlock([
              ('text', RichTextBlock(blank=True)),
              ('size',
               ChoiceBlock(required=False,
                           max_length=20,
                           choices=(
                               (u'6', u'Half'),
                               (u'9', u'Full'),
                           ))),
          ],
                      template='home/blocks/text.html',
                      icon='pilcrow')),
         ('image',
          StructBlock([
              ('image', ImageChooserBlock(blank=True, required=False)),
              ('caption', CharBlock(required=False)),
              ('size',
               ChoiceBlock(required=False,
                           max_length=20,
                           choices=(
                               (u'4', u'Small'),
                               (u'6', u'Medium'),
                               (u'8', u'Large'),
                           ))),
          ],
                      template='home/blocks/image.html',
                      icon='image'))],
        blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('year'),
        FieldPanel('edition'),
        FieldPanel('print_type'),
        FieldPanel('dim_x'),
        FieldPanel('dim_y'),
        FieldPanel('series_description'),
        StreamFieldPanel('items'),
        StreamFieldPanel('story'),
        StreamFieldPanel('behind_the_scenes'),
    ]

    promote_panels = [
        FieldPanel('footer_colour'),
    ] + Page.promote_panels
Esempio n. 29
0
class StoryPage(Page):
    MAX_RELATED_STORIES = 10

    # This is a leaf page
    subpage_types = []
    parent_page_types = [
        'news.StoryIndexPage'
    ]

    author = models.ForeignKey(
        'common.User', 
        null=True, 
        blank=True, 
        on_delete=models.SET_NULL, 
        related_name="+"
    )
    date = models.DateField("post date")
    lede = models.CharField(
        max_length=1024, 
        help_text="A short intro that appears in the story index page"
    )
    tags = ClusterTaggableManager(through=StoryTag, blank=True)
    categories = ParentalManyToManyField(
        'news.StoryCategory', 
        blank=True, 
        help_text="The set of categories this page will be served"
    )

    # Add allowed block types to StreamPanel
    content = StreamField(
        [
            ('paragraph', RichTextBlock(features=[
                'h2', 'h3', 'bold', 'italic', 'link', 'ol', 'ul'
            ])),
            ('markdown', MarkdownBlock(icon='code')),
            ('image', StructBlock([
                ('image', ImageChooserBlock()),
                ('caption', CharBlock(required=False))
            ])),
            ('carousel', ImageCarouselBlock()),
            ('quote', BlockQuoteBlock()),
            ('embedded_content', EmbedContentBlock()),
        ]
    )

    def get_context(self, request):
        
        context = super().get_context(request)
        tags_list = list(self.tags.all())

        # Collects set of stories that has the same tags as this story.
        related = StoryPage.objects.live().order_by('-first_published_at')
        related = related.filter(tags__in=tags_list)
        related = related.exclude(id=self.id)
        if related.count() > 0:
            related = related.distinct()[0:self.MAX_RELATED_STORIES]
            context["related"] = related

        try:
            context['prevstory'] = self.get_previous_by_date(tags__in=tags_list)
        except (StoryPage.DoesNotExist, ValueError):
            pass

        try:
            context['nextstory'] = self.get_next_by_date(tags__in=tags_list)
        except (StoryPage.DoesNotExist, ValueError):
            pass

        return context

    def hero_image(self):
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None

    def media_thumbnail_url(self):
        for child in self.content:
            if child.block.name == 'embedded_content':
                return child.value.thumbnail_url
        return None

    def hero_image_url(self):
        hero_image = self.hero_image()
        if hero_image:
            return hero_image.url
        return self.media_thumbnail_url()

    def author_name(self):
        if not self.author:
            return ANONYMOUS_AUTHOR_NAME
        else:
            return self.owner.username
        
    search_fields = Page.search_fields = [
        index.SearchField('lede'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            StoryAuthorFieldPanel('author', widget=forms.Select),
            FieldPanel('date'),
            FieldPanel('tags'),
            FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
        ]),
        FieldPanel('lede'),
        InlinePanel('gallery_images', label="Gallery Images"),
        StreamFieldPanel('content')
    ]
Esempio n. 30
0
class ArticlePage(Page):
    title_fr = models.CharField(max_length=255, default="")
    title_en = models.CharField(max_length=255, default="", blank=True)
    trans_title = TranslatedField(
        'title',
        'title_fr',
        'title_en',
    )

    intro_de = RichTextField(default='', blank=True)
    intro_fr = RichTextField(default='', blank=True)
    intro_en = RichTextField(default='', blank=True)
    trans_intro = TranslatedField(
        'intro_de',
        'intro_fr',
        'intro_en',
    )

    gallery = StreamField([
        ('image', ListBlock(ImageCarouselBlock(), icon="image")),
    ],
                          blank=True)
    # documents = StreamField([
    #     ('documents', ListBlock(DocumentChooserBlock(), icon="document")),
    # ])

    body_de = StreamField(
        [('paragraph', RichTextBlock()),
         ('section', CharBlock(form_classname="full title")),
         ('info', InfoBlock(icon='help')),
         ('media',
          ChoiceBlock(choices=[
              ('gallery', 'Image gallery'),
          ], icon='media'))],
        null=True,
        blank=True)
    body_fr = StreamField(
        [('paragraph', RichTextBlock()),
         ('section', CharBlock(form_classname="full title")),
         ('info', InfoBlock(icon='help')),
         ('media',
          ChoiceBlock(choices=[
              ('gallery', 'Image gallery'),
          ], icon='media'))],
        null=True,
        blank=True)
    body_en = StreamField(
        [('paragraph', RichTextBlock()),
         ('section', CharBlock(form_classname="full title")),
         ('info', InfoBlock(icon='help')),
         ('media',
          ChoiceBlock(choices=[
              ('gallery', 'Image gallery'),
          ], icon='media'))],
        null=True,
        blank=True)
    trans_body = TranslatedField(
        'body_de',
        'body_fr',
        'body_en',
    )

    date = models.DateField("Date", null=True, blank=True)

    on_homepage = models.BooleanField(default=False,
                                      verbose_name="Featured",
                                      help_text="Auf der Frontpage anzeigen")

    feed_image = models.ForeignKey('wagtailimages.Image',
                                   null=True,
                                   blank=True,
                                   on_delete=models.SET_NULL,
                                   related_name='+')

    search_fields = Page.search_fields + [
        index.SearchField('title', partial_match=True, boost=10),
        index.SearchField('title_fr', partial_match=True, boost=10),
        index.SearchField('title_en', partial_match=True, boost=10),
        index.SearchField('body_de', partial_match=True),
        index.SearchField('body_fr', partial_match=True),
        index.SearchField('body_en', partial_match=True),
        index.SearchField('intro_de', partial_match=True),
        index.SearchField('intro_fr', partial_match=True),
        index.SearchField('intro_en', partial_match=True),
    ]
    content_panels = [
        MultiFieldPanel([
            FieldPanel('title'),
            FieldPanel('intro_de'),
        ],
                        heading="Deutsch",
                        classname="collapsible collapsed"),
        StreamFieldPanel('body_de'),
        MultiFieldPanel([
            FieldPanel('title_fr'),
            FieldPanel('intro_fr'),
        ],
                        heading="Français",
                        classname="collapsible collapsed"),
        StreamFieldPanel('body_fr'),
        MultiFieldPanel([
            FieldPanel('title_en'),
            FieldPanel('intro_en'),
        ],
                        heading="English",
                        classname="collapsible collapsed"),
        StreamFieldPanel('body_en'),
        MultiFieldPanel([
            ImageChooserPanel('feed_image'),
        ], heading="Images"),
        StreamFieldPanel('gallery'),
    ]
    promote_panels = [
        InlinePanel('related_links', label="Links"),
        MultiFieldPanel([
            FieldPanel('date'),
            FieldPanel('on_homepage'),
        ],
                        heading="Veröffentlichung"),
        MultiFieldPanel(Page.promote_panels, "Einstellungen"),
    ]

    parent_page_types = ['home.ArticleIndexPage', 'home.HomePage']
    subpage_types = []

    class Meta:
        verbose_name = "Artikel"
Esempio n. 31
0
class ImageBlock(StructBlock):
    image = ImageChooserBlock()
    caption = RichTextBlock()
    alignment = ImageFormatChoiceBlock()
Esempio n. 32
0
class StreamModel(models.Model):
    body = StreamField([
        ('text', CharBlock()),
        ('rich_text', RichTextBlock()),
        ('image', ImageChooserBlock()),
    ])
Esempio n. 33
0
class ImageText(StructBlock):
    reverse = BooleanBlock(required=False)
    text = RichTextBlock()
    image = CustomImageChooserBlock(rendition="width-800")
Esempio n. 34
0
class BustoutBlock(StructBlock):
    image = ImageChooserBlock()
    text = RichTextBlock()

    class Meta:
        icon = "pick"