コード例 #1
0
ファイル: test_blocks.py プロジェクト: lauantai/wagtail
    def test_initialise_with_instance(self):
        child_block = blocks.CharBlock()
        block = blocks.ListBlock(child_block)

        self.assertEqual(block.child_block, child_block)
コード例 #2
0
ファイル: models.py プロジェクト: n6151h/pyconau2017
class KeynotesBlock(blocks.StructBlock):
    class Meta:
        template = "cms_pages/home_page_blocks/keynotes.html"

    heading = blocks.CharBlock(required=True)
    speakers = blocks.ListBlock(KeynoteSpeakerBlock)
コード例 #3
0
ファイル: test_blocks.py プロジェクト: lauantai/wagtail
    def test_initialise_with_class(self):
        block = blocks.ListBlock(blocks.CharBlock)

        # Child block should be initialised for us
        self.assertIsInstance(block.child_block, blocks.CharBlock)
コード例 #4
0
class ProductBlock(blocks.StructBlock):
    title = blocks.CharBlock()
    subtitle = blocks.CharBlock()
    products = blocks.ListBlock(ProductChooserBlock)
コード例 #5
0
class InfoUnitGroup(blocks.StructBlock):
    format = blocks.ChoiceBlock(
        choices=[
            ('50-50', '50/50'),
            ('33-33-33', '33/33/33'),
            ('25-75', '25/75'),
        ],
        default='50-50',
        label='Format',
        help_text='Choose the number and width of info unit columns.',
    )

    heading = v1_blocks.HeadingBlock(required=False)

    intro = blocks.RichTextBlock(required=False,
                                 help_text='If this field is not empty, '
                                 'the Heading field must also be set.')

    link_image_and_heading = blocks.BooleanBlock(
        default=True,
        required=False,
        help_text=(
            'Check this to link all images and headings to the URL of '
            'the first link in their unit\'s list, if there is a link.'))

    has_top_rule_line = blocks.BooleanBlock(
        default=False,
        required=False,
        help_text=('Check this to add a horizontal rule line to top of '
                   'info unit group.'))

    lines_between_items = blocks.BooleanBlock(
        default=False,
        required=False,
        label='Show rule lines between items',
        help_text=('Check this to show horizontal rule lines between info '
                   'units.'))

    info_units = blocks.ListBlock(molecules.InfoUnit())

    sharing = blocks.StructBlock([
        ('shareable',
         blocks.BooleanBlock(label='Include sharing links?',
                             help_text='If checked, share links '
                             'will be included below '
                             'the items.',
                             required=False)),
        ('share_blurb',
         blocks.CharBlock(help_text='Sets the tweet text, '
                          'email subject line, and '
                          'LinkedIn post text.',
                          required=False)),
    ])

    def clean(self, value):
        cleaned = super(InfoUnitGroup, self).clean(value)

        # Intro paragraph may only be specified with a heading.
        if cleaned.get('intro') and not cleaned.get('heading'):
            raise ValidationError(
                'Validation error in InfoUnitGroup: intro with no heading',
                params={
                    'heading':
                    ErrorList([
                        'Required if paragraph is not empty. (If it looks empty, '
                        'click into it and hit the delete key a bunch of times.)'
                    ])
                })

        # If 25/75, info units must have images.
        if cleaned.get('format') == '25-75':
            for unit in cleaned.get('info_units'):
                if not unit['image']['upload']:
                    raise ValidationError(
                        ('Validation error in InfoUnitGroup: '
                         '25-75 with no image'),
                        params={
                            'format':
                            ErrorList([
                                'Info units must include images when using the '
                                '25/75 format. Search for an "FPO" image if you '
                                'need a temporary placeholder.'
                            ])
                        })

        return cleaned

    class Meta:
        icon = 'list-ul'
        template = '_includes/organisms/info-unit-group-2.html'
コード例 #6
0
class ArticlePage(CFGOVPage):
    """
    General article page type.
    """
    category = models.CharField(
        choices=[
            ('basics', 'Basics'),
            ('common_issues', 'Common issues'),
            ('howto', 'How to'),
            ('know_your_rights', 'Know your rights'),
        ],
        max_length=255,
    )
    heading = models.CharField(
        max_length=255,
        blank=False,
    )
    intro = models.TextField(blank=False)
    inset_heading = models.CharField(max_length=255,
                                     blank=True,
                                     verbose_name="Heading")
    sections = StreamField([
        ('section',
         blocks.StructBlock([
             ('heading',
              blocks.CharBlock(max_length=255,
                               required=True,
                               label='Section heading')),
             ('summary',
              blocks.TextBlock(required=False,
                               blank=True,
                               label='Section summary')),
             ('link_text',
              blocks.CharBlock(required=False,
                               blank=True,
                               label="Section link text")),
             ('url',
              blocks.CharBlock(
                  required=False,
                  blank=True,
                  label='Section link URL',
                  max_length=255,
              )),
             ('subsections',
              blocks.ListBlock(
                  blocks.StructBlock([
                      ('heading',
                       blocks.CharBlock(max_length=255,
                                        required=False,
                                        blank=True,
                                        label='Subsection heading')),
                      ('summary',
                       blocks.TextBlock(required=False,
                                        blank=True,
                                        label='Subsection summary')),
                      ('link_text',
                       blocks.CharBlock(required=True,
                                        label='Subsection link text')),
                      ('url',
                       blocks.CharBlock(required=True,
                                        label='Subsection link URL'))
                  ])))
         ]))
    ])
    content_panels = CFGOVPage.content_panels + [
        MultiFieldPanel([
            FieldPanel('category'),
            FieldPanel('heading'),
            FieldPanel('intro')
        ],
                        heading="Heading",
                        classname="collapsible"),
        MultiFieldPanel([
            FieldPanel('inset_heading'),
            InlinePanel('article_links', label='Inset link', max_num=2),
        ],
                        heading="Inset links",
                        classname="collapsible"),
        StreamFieldPanel('sections'),
    ]

    sidebar = StreamField([
        ('call_to_action', molecules.CallToAction()),
        ('related_links', molecules.RelatedLinks()),
        ('related_metadata', molecules.RelatedMetadata()),
        ('email_signup', organisms.EmailSignUp()),
        ('reusable_text', v1_blocks.ReusableTextChooserBlock(ReusableText)),
    ],
                          blank=True)

    sidebar_panels = [
        StreamFieldPanel('sidebar'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('title'),
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels, heading='Content'),
        ObjectList(sidebar_panels, heading='Sidebar'),
        ObjectList(CFGOVPage.settings_panels, heading='Configuration'),
    ])

    template = 'ask-cfpb/article-page.html'

    objects = CFGOVPageManager()

    def get_context(self, request, *args, **kwargs):
        context = super(ArticlePage, self).get_context(request)
        context['about_us'] = get_standard_text(self.language, 'about_us')
        return context

    def __str__(self):
        return self.title
コード例 #7
0
ファイル: models.py プロジェクト: isabella232/fec-cms
class ResourcePage(Page):
    # Class for pages that include a side nav, multiple sections and citations
    date = models.DateField(default=datetime.date.today)
    intro = StreamField([
        ('paragraph', blocks.RichTextBlock())
    ], null=True)
    sidebar_title = models.CharField(max_length=255, null=True, blank=True)
    related_pages = StreamField([
        ('related_pages', blocks.ListBlock(blocks.PageChooserBlock()))
    ], null=True, blank=True)
    sections = StreamField([
        ('sections', ResourceBlock())
    ], null=True)
    citations = StreamField([
        ('citations', blocks.ListBlock(CitationsBlock()))
    ], null=True)
    related_topics = StreamField([
        ('related_topics', blocks.ListBlock(
            blocks.PageChooserBlock(label="Related topic")
        ))
    ], null=True)
    category = models.CharField(max_length=255,
                                choices=constants.report_child_categories.items(),
                                help_text='If this is a report, add a category',
                                blank=True,
                                null=True)
    breadcrumb_style = models.CharField(max_length=255,
        choices=[('primary', 'Blue'), ('secondary', 'Red')],
        default='primary')
    show_contact_card = models.BooleanField(
                                    max_length=255, default=False,
                                    null=False, blank=False,
                                    choices=[
                                        (True, 'Show contact card'),
                                        (False, 'Do not show contact card')
                                    ])

    content_panels = Page.content_panels + [
        StreamFieldPanel('intro'),
        FieldPanel('sidebar_title'),
        StreamFieldPanel('related_pages'),
        StreamFieldPanel('sections'),
        StreamFieldPanel('citations'),
        StreamFieldPanel('related_topics'),
        FieldPanel('show_contact_card')
    ]

    promote_panels = Page.promote_panels + [
        FieldPanel('breadcrumb_style'),
        FieldPanel('category'),
        FieldPanel('date')
    ]

    # Adds a settings field for making a custom title that displays in the Wagtail page explorer
    menu_title = models.CharField(max_length=255, null=True)
    settings_panels = Page.settings_panels + [
        FieldPanel('menu_title')
    ]

    def get_admin_display_title(self):
        return self.menu_title if self.menu_title else self.title

    @property
    def display_date(self):
        return self.date.strftime('%B %Y')

    @property
    def content_section(self):
        return get_content_section(self)
コード例 #8
0
class HomePageStreamBlock(blocks.StreamBlock):

    carousel = blocks.ListBlock(ImageWithCaptionBlock(),
                                template='home/blocks/carousel.html',
                                icon='image')
コード例 #9
0
ファイル: organisms.py プロジェクト: m3brown/cfgov-refresh
class LinkBlobGroup(blocks.StructBlock):
    heading = blocks.CharBlock(icon='title', required=False)
    has_top_border = blocks.BooleanBlock(required=False)
    has_bottom_border = blocks.BooleanBlock(required=False)
    link_blobs = blocks.ListBlock(molecules.HalfWidthLinkBlob())
コード例 #10
0
 class ProductBlock(blocks.StructBlock):
     products = blocks.ListBlock(ProductChooserBlock)
コード例 #11
0
class BadgetBlock(blocks.StructBlock):
    content = blocks.ListBlock(SingleBadgetBlock(), label='Items')

    class Meta:
        template = 'wagtail_blocks/badget.html'
        icon = "list-ul"
コード例 #12
0
        label = 'Hoogte',
        help_text = 'Hoogte van het blok in pixels.',
        min_value = 0,
        max_value = 999,
        default = 250,
    )



grid_array = \
    [('tabellen', TableStructBlock(
        label='Tabellen',
        template = 'streamfields/table.html',
        icon='fa-table'))
    ,('citaten', blocks.ListBlock(
        QuoteBlock(),
        template = 'streamfields/quotes.html',
        icon="openquote",))
    ,('koppen', blocks.ListBlock(
        HeaderBlock(),
        template = 'streamfields/header.html',
        icon="title",))
    ,('tekst_velden', blocks.ListBlock(
        TextFieldBlock(),
        template = 'streamfields/text_field.html',
        icon="fa-align-justify",))
    ,('lijst', blocks.ListBlock(
        UnorderedListBlock(),
        template = 'streamfields/list.html',
        icon="list-ul"))
    ,('accordions', blocks.ListBlock(
        AccordionBlock(),
コード例 #13
0
ファイル: models.py プロジェクト: cfaanchorage/startherecms
class RoadmapSection(blocks.StructBlock):
    title = blocks.CharBlock()
    pages = blocks.ListBlock(blocks.PageChooserBlock())
    image = ImageChooserBlock(required=False)
コード例 #14
0
ファイル: models.py プロジェクト: ouhft/quod
class MultiPage(Page):
    """
    Multipurpose page model, allowing pretty much all types to be combined onto one page

    From Page:
        title - Char(255)
        slug - Slug/Char(255)
        content_type - FK(content_type)
        live - Boolean
        has_unpublished_changes - Boolean
        url_path - Text
        owner - FK(auth_user)
        seo_title - Char(255)
        show_in_menus - Boolean
        search_description - Text
        go_live_at - DateTime
        expire_at - DateTime
        expired - Boolean
        locked - Boolean
        first_published_at - DateTime
        latest_revision_created_at - DateTime
    """

    # Database fields
    subtitle = models.CharField(max_length=255, null=True, blank=True)
    author = models.CharField(max_length=255)  # Because the author may not be the person entering it on the website
    body = StreamField([
        ('heading', blocks.CharBlock(classname="full title")),
        ('text', blocks.RichTextBlock()),
        ('image', ImageChooserBlock()),
        ('table', TableBlock(template="website/blocks/table.html")),
        ('publications_list', blocks.ListBlock(SnippetChooserBlock(Publication, label="publication"),
                                               template="website/blocks/publications_list.html")),
        ('projects_list', blocks.ListBlock(SnippetChooserBlock(Project, label="project"))),
        ('qa_list', blocks.ListBlock(QandABlock(label="entry"), template="website/blocks/qa_list.html")),
    ])
    date = models.DateField("Post date")
    feed_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    # Search index configuration

    search_fields = Page.search_fields + [
        index.SearchField('body'),
        index.SearchField('author'),
        index.FilterField('date'),
    ]

    # Editor panels configuration

    content_panels = Page.content_panels + [
        FieldPanel('subtitle'),
        FieldPanel('author'),
        FieldPanel('date'),
        StreamFieldPanel('body'),
        InlinePanel('related_links', label="Related links"),
    ]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration"),
        ImageChooserPanel('feed_image'),
    ]

    # Parent page / subpage type rules

    parent_page_types = ['HomePage', 'MultiPage']
コード例 #15
0
ファイル: test_blocks.py プロジェクト: lauantai/wagtail
    def test_media_inheritance(self):
        class ScriptedCharBlock(blocks.CharBlock):
            media = forms.Media(js=['scripted_char_block.js'])

        block = blocks.ListBlock(ScriptedCharBlock())
        self.assertIn('scripted_char_block.js', ''.join(block.all_media().render_js()))
コード例 #16
0
class ContentStreamField(blocks.StreamBlock):
    h2 = blocks.CharBlock(icon="title",
                          classname="title",
                          label='H2',
                          template='content/stream_fields/h2.html')
    embed = EmbedBlock(label='Эмбед', icon="link")
    image = ImageBlock(icon="image",
                       label='Фотография',
                       template='content/stream_fields/image.html')
    wide_image = ImageBlock(icon="image",
                            label='Широкая фотография',
                            template='content/stream_fields/wide_image.html')
    left_image = ImageNotesBlock(
        icon="image",
        label='Фотография слева',
        template='content/stream_fields/left_image.html')
    left_text = LeftText(template='content/stream_fields/left_text.html',
                         label='Текст слева')
    left_text_gray = LeftText(
        template='content/stream_fields/left_text_gray.html',
        label='Текст слева на сером фоне')
    paragraph = blocks.RichTextBlock(
        editor='tinymce',
        language='ru',
        label='Параграф',
        template='content/stream_fields/paragraph.html')
    read_also = ReadAlso()
    gallery = blocks.ListBlock(ImageBlock,
                               label='Галерея',
                               icon="image",
                               template='content/stream_fields/gallery.html')
    notes = blocks.ListBlock(
        NoteBlock(),
        label='Подписи',
        template='content/stream_fields/notes.html',
    )

    html_field = blocks.TextBlock(
        label='html врезка',
        help_text=
        'Поле для html, css и js (может использоваться для сложных embed-кодов)',
        template='content/stream_fields/html_field.html',
        icon='code')
    anchor_field = blocks.StaticBlock(
        admin_text='Якорь (передергивает скрипты аналитики и баннеры)',
        icon="repeat",
        label="Якорь",
        template='content/stream_fields/anchor_field.html',
    )
    box_field = BoxBlock()
    blockquote = blocks.CharBlock(
        label='Цитата',
        template='content/stream_fields/blockquote.html',
        icon='openquote')
    poll = PollBlock()

    giphy_block = GiphyChooserBlock(
        help_text='Поиск гифок', template='content/stream_fields/giphy.html')

    big_side_image = BigSideImageBlock()

    simple_quote_1 = blocks.TextBlock(
        required=True,
        label="Простая цитата 1",
        template="content/stream_fields/simple_quote_1.html",
        icon="openquote")
    simple_quote_2 = blocks.TextBlock(
        required=True,
        label="Простая цитата 2",
        template="content/stream_fields/simple_quote_2.html",
        icon="openquote")
コード例 #17
0
class MyBlock(blocks.StructBlock):
    title = blocks.CharBlock(max_length=100)
    item = MyBlockItem()
    items = blocks.ListBlock(MyBlockItem)
    image = ImageChooserBlock()
コード例 #18
0
ファイル: models.py プロジェクト: mark-meyer/startherecms
class Track(Page):
    page_body = RichTextField(
        blank=True,
        help_text=
        "The main content of the page, above the list of steps and form")
    form_submission_message = models.CharField(
        max_length=255,
        help_text=
        "The text that is shown to the user after they make a form submissiom",
        default="Based on your choices we suggest looking at the following:")
    question = models.CharField(
        max_length=255,
        blank=True,
        help_text="The question for the form on the page (optional)")
    choices = StreamField([
        ('label', blocks.CharBlock(required=True)),
    ],
                          blank=True,
                          null=True)

    has_strict_rules = models.BooleanField(
        default=False,
        help_text=
        "If the rule definitions are strict it will ONLY display results that match the exact answers (instead of the union of the answers)"
    )

    rules = StreamField(
        [('rule',
          blocks.StructBlock([
              ('name', ChoiceRulesBlock()),
              ('pages', blocks.ListBlock(blocks.PageChooserBlock())),
              ('override', blocks.BooleanBlock(default=False, required=False))
          ]))],
        default=[],
        blank=True)

    default_steps = StreamField(
        [('page', blocks.PageChooserBlock())],
        blank=True,
        default=[],
        help_text=
        "The steps to show if someone submits a form with answers that are not covered by the rules"
    )

    content_panels = Page.content_panels + [
        FieldPanel('page_body', classname='full'),
        MultiFieldPanel(
            [
                MultiFieldPanel([
                    FieldPanel('question'),
                    FieldPanel('form_submission_message'),
                    StreamFieldPanel('choices')
                ]),
                FieldPanel('has_strict_rules'),
                StreamFieldPanel('rules'),
                StreamFieldPanel('default_steps'),
            ],
            heading="Options form for the page to help narrow down choices",
            classname="collapsible")
    ]

    template = 'roadmap/track/base.html'

    def steps(self):
        # Get list of all step pages that are descendants of this page
        events = Step.objects.live().descendant_of(self)
        return events

    # Directs people to the walk through or self service routes
    # Walk through path uses the choices model to filter steps to take
    def route(self, request, path_components):
        if len(request.GET):
            return RouteResult(self,
                               kwargs={'template': 'roadmap/track/base.html'})
        else:
            return super(Track, self).route(request, path_components)

    def serve(self, request, template=''):
        if template == '':
            template = self.template
        #Kind of hacky but intercept request if it has 'submit-choice' in the slug
        #Serve the rules for the selected choices
        if len(request.GET):
            #Get selected checkbox values from params in request
            selected_choices = list(request.GET.values())

            #Sort the choices so we have them in the same order as the admin defined rules
            selected_choices.sort()

            pages = []  #list of pages that will be presented to the user
            default_pages = [
            ]  #default pages if there isn't a rule defined for the choices the user selected
            all_selected_choices = ','.join(selected_choices)

            #loop through each admin defined rule to see if we have a defined rule for the selected choices
            if self.has_strict_rules:
                #Find the one rule that matches the selected choices and only suggest those steps
                for rule in self.rules:
                    if rule.value['override'] and re.search(
                            rule.value['name'], all_selected_choices):
                        pages = rule.value['pages']
                        break
                    if rule.value['name'] == all_selected_choices:
                        pages = rule.value['pages']
            else:
                #Union all the pages that match with a rule
                for rule in self.rules:
                    if rule.value['override'] and re.search(
                            rule.value['name'], all_selected_choices):
                        pages = rule.value['pages']
                        break
                    if rule.value['name'] in selected_choices:
                        for page in rule.value['pages']:
                            if page not in pages:
                                pages.append(page)

            for page in self.default_steps:
                #if the user defines default pages in the admin then create a list of pages
                #otherwise the default default_pages list is all the steps in the track
                default_pages.append(Page.objects.get(id=page.value.id))

            if not pages:
                if not default_pages:
                    default_pages = Step.objects.live().descendant_of(self)
                pages = default_pages

            request.path = '/'.join(request.path.split('/')[:3])

            return render(
                request, template, {
                    'steps': list(map((lambda page: page.specific), pages)),
                    'page': self,
                    'selected_choices': ','.join(map(str, selected_choices)),
                    'default_pages': default_pages,
                    'showMessage': True
                })
        #Otherwise just render the track page with the appropriate template
        return render(request, template, {'page': self, 'steps': self.steps()})
コード例 #19
0
ファイル: models.py プロジェクト: isabella232/fec-cms
class CustomPage(Page):
    """Flexible customizable page."""
    author = models.CharField(max_length=255)
    date = models.DateField('Post date')
    body = StreamField([
        ('heading', blocks.CharBlock(classname='full title')),
        ('paragraph', blocks.RichTextBlock()),
        ('html', blocks.RawHTMLBlock()),
        ('image', ImageChooserBlock()),
        ('table', TableBlock()),
        ('example_paragraph', ExampleParagraph()),
        ('example_forms', ExampleForms()),
        ('reporting_example_cards', ReportingExampleCards())
    ])
    sidebar = stream_factory(null=True, blank=True)
    citations = StreamField([('citations', blocks.ListBlock(CitationsBlock()))],
                    null=True)
    record_articles = StreamField([
        ('record_articles', blocks.ListBlock(
            blocks.PageChooserBlock(target_model=RecordPage)
        ))
    ], null=True)
    continue_learning = StreamField([
        ('continue_learning', blocks.ListBlock(ThumbnailBlock(), icon='doc-empty')),
    ], null=True)
    show_contact_link = models.BooleanField(
                                    max_length=255, default=True,
                                    null=False, blank=False,
                                    choices=[
                                        (True, 'Show contact link'),
                                        (False, 'Do not show contact link')
                                    ])

    content_panels = Page.content_panels + [
        FieldPanel('author'),
        FieldPanel('date'),
        StreamFieldPanel('body'),
        StreamFieldPanel('citations'),
        StreamFieldPanel('continue_learning'),
        MultiFieldPanel([
                StreamFieldPanel('sidebar'),
                StreamFieldPanel('record_articles'),
                FieldPanel('show_contact_link'),
            ],
            heading="Sidebar",
            classname="collapsible"
        )
    ]

    # Adds a settings field for making a custom title that displays in the Wagtail page explorer
    menu_title = models.CharField(max_length=255, null=True)
    settings_panels = Page.settings_panels + [
        FieldPanel('menu_title')
    ]

    def get_admin_display_title(self):
        return self.menu_title if self.menu_title else self.title

    @property
    def content_section(self):
        return get_content_section(self)
コード例 #20
0
class BureauStructureOffice(BureauStructurePosition):
    offices = blocks.ListBlock(BureauStructurePosition(required=False))
コード例 #21
0
ファイル: organisms.py プロジェクト: schbetsy/cfgov-refresh
class RelatedPosts(blocks.StructBlock):
    limit = blocks.CharBlock(
        default='3',
        help_text=('This limit applies to EACH TYPE of post this module '
                   'retrieves, not the total number of retrieved posts.'))
    show_heading = blocks.BooleanBlock(
        required=False,
        default=True,
        label='Show Heading and Icon?',
        help_text=('This toggles the heading and '
                   'icon for the related types.'))
    header_title = blocks.CharBlock(default='Further reading',
                                    label='Slug Title')

    relate_posts = blocks.BooleanBlock(required=False,
                                       default=True,
                                       label='Blog Posts',
                                       editable=False)
    relate_newsroom = blocks.BooleanBlock(required=False,
                                          default=True,
                                          label='Newsroom',
                                          editable=False)
    relate_events = blocks.BooleanBlock(required=False,
                                        default=True,
                                        label='Events')

    specific_categories = blocks.ListBlock(blocks.ChoiceBlock(
        choices=ref.related_posts_categories, required=False),
                                           required=False)

    and_filtering = blocks.BooleanBlock(
        required=False,
        default=False,
        label='Match all topic tags',
        help_text=('If checked, related posts will only be pulled in if they '
                   'match ALL topic tags set on this page. Otherwise, related '
                   'posts can match any one topic tag.'))

    alternate_view_more_url = blocks.CharBlock(
        required=False,
        label='Alternate "View more" URL',
        help_text=('By default, the "View more" link will go to the Activity '
                   'Log, filtered based on the above parameters. Enter a URL '
                   'in this field to override that link destination.'))

    def get_context(self, value, parent_context=None):
        context = super(RelatedPosts,
                        self).get_context(value, parent_context=parent_context)

        page = context['page']
        request = context['request']

        context.update({
            'posts':
            self.related_posts(page, value),
            'view_more_url': (value['alternate_view_more_url']
                              or self.view_more_url(page, request)),
        })

        return context

    @staticmethod
    def related_posts(page, value):
        from v1.models.learn_page import AbstractFilterPage

        def tag_set(related_page):
            return set([tag.pk for tag in related_page.tags.all()])

        def match_all_topic_tags(queryset, page_tags):
            """Return pages that share every one of the current page's tags."""
            current_tag_set = set([tag.pk for tag in page_tags])
            return [
                page for page in queryset
                if current_tag_set.issubset(tag_set(page))
            ]

        related_types = []
        related_items = {}
        if value.get('relate_posts'):
            related_types.append('blog')
        if value.get('relate_newsroom'):
            related_types.append('newsroom')
        if value.get('relate_events'):
            related_types.append('events')
        if not related_types:
            return related_items

        tags = page.tags.all()
        and_filtering = value['and_filtering']
        specific_categories = value['specific_categories']
        limit = int(value['limit'])
        queryset = AbstractFilterPage.objects.live().exclude(
            id=page.id).order_by('-date_published').distinct().specific()

        for parent in related_types:  # blog, newsroom or events
            # Include children of this slug that match at least 1 tag
            children = Page.objects.child_of_q(Page.objects.get(slug=parent))
            filters = children & Q(('tags__in', tags))

            if parent == 'events':
                # Include archived events matches
                archive = Page.objects.get(slug='archive-past-events')
                children = Page.objects.child_of_q(archive)
                filters |= children & Q(('tags__in', tags))

            if specific_categories:
                # Filter by any additional categories specified
                categories = ref.get_appropriate_categories(
                    specific_categories=specific_categories, page_type=parent)
                if categories:
                    filters &= Q(('categories__name__in', categories))

            related_queryset = queryset.filter(filters)

            if and_filtering:
                # By default, we need to match at least one tag
                # If specified in the admin, change this to match ALL tags
                related_queryset = match_all_topic_tags(related_queryset, tags)

            related_items[parent.title()] = related_queryset[:limit]

        # Return items in the dictionary that have non-empty querysets
        return {key: value for key, value in related_items.items() if value}

    @staticmethod
    def view_more_url(page, request):
        """Generate a URL to see more pages like this one.
        This method generates a link to the Activity Log page (which must
        exist and must have a unique site-wide slug of "activity-log") with
        filters set by the tags assigned to this page, like this:
        /activity-log/?topics=foo&topics=bar&topics=baz
        If for some reason a page with slug "activity-log" does not exist,
        this method will raise Page.DoesNotExist.
        """
        activity_log = Page.objects.get(slug='activity-log')
        url = activity_log.get_url(request)

        tags = urlencode([('topics', tag) for tag in page.tags.slugs()])
        if tags:
            url += '?' + tags

        return url

    class Meta:
        icon = 'link'
        template = '_includes/molecules/related-posts.html'
コード例 #22
0
class AddressBlock(blocks.StructBlock):

    lines = blocks.ListBlock(blocks.CharBlock(label="Line", required=False))

    class Meta:
        template = 'wagtail_extensions/blocks/address.html'