Esempio n. 1
0
class General(TypesetBodyMixin, HeroMixin, SectionBodyMixin, Page):
    """
    General page that that can be used with strategy  and accounts pages
    """

    template = 'general/general_page.html'

    other_pages_heading = models.CharField(blank=True,
                                           max_length=255,
                                           verbose_name='Heading',
                                           default='More about')
    show_breadcrumbs = models.BooleanField(default=False)

    content_panels = Page.content_panels + [
        hero_panels(),
        FieldPanel('show_breadcrumbs'),
        StreamFieldPanel('body'),
        StreamFieldPanel('sections'),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel('other_pages', label='Related pages')
        ],
                        heading='Other Pages/Related Links'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    class Meta:
        verbose_name = 'General Page'
Esempio n. 2
0
class SpotlightPage(HeroMixin, Page):
    class Meta():
        verbose_name = 'Spotlight Page'

    parent_page_types = ['datasection.DataSectionPage']
    subpage_types = ['spotlight.SpotlightLocationComparisonPage', 'spotlight.SpotlightTheme', 'general.General']

    country_code = models.CharField(max_length=100, help_text='e.g. UG, KE', default='')
    country_name = models.CharField(max_length=255)
    currency_code = models.CharField(max_length=100, help_text='UGX, KES', default='')
    datasources_description = models.TextField(
        help_text='A description for data sources section', null=True, blank=True, verbose_name='Description')
    datasources_links = StreamField([('link', LinkBlock()), ], null=True, blank=True, verbose_name='Links')
    content_panels = Page.content_panels + [
        hero_panels(),
        MultiFieldPanel([
            FieldPanel('country_code'),
            FieldPanel('country_name'),
            FieldPanel('currency_code')
        ], heading='Settings'),
        MultiFieldPanel([
            FieldPanel('datasources_description'),
            StreamFieldPanel('datasources_links')
        ], heading='Data Sources Section')
    ]


    def serve(self, request, *args, **kwargs):
        return redirect(self.url)
Esempio n. 3
0
class CountrySpotlight(TypesetBodyMixin, HeroMixin, Page):
    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('body')
    ]

    parent_page_types = ['datasection.DataSectionPage']
    subpage_types = ['spotlight.SpotlightPage', 'general.General']

    class Meta():
        verbose_name = 'Country Spotlights Page'


    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['spotlights'] = self.get_children().specific().type(SpotlightPage).live()

        return context

    class Meta():
        verbose_name = 'Country Spotlight'


    def serve(self, request, *args, **kwargs):
        return redirect(self.get_parent().url)
Esempio n. 4
0
class VacancyIndexPage(HeroMixin, Page):
    """
    Shows a list of available vacancies
    """
    class Meta:
        db_table = 'vacancies_page'
        verbose_name = 'Vacancy Index Page'

    parent_page_types = ['workforus.WorkForUsPage']
    subpage_types = ['VacancyPage', 'general.General']

    def get_context(self, request):
        context = super().get_context(request)
        context['vacancies'] = VacancyPage.objects.live()
        return context

    email_alert_confirmation_label = RichTextField(
        blank=True,
        verbose_name='Descriptive Text for Consent to Email Alerts',
        default=
        'By checking this box you consent to us collecting the data submitted',
        features=RICHTEXT_FEATURES_NO_FOOTNOTES)

    content_panels = Page.content_panels + [
        hero_panels(),
        FieldPanel('email_alert_confirmation_label'),
        InlinePanel('page_notifications', label='Notifications')
    ]
Esempio n. 5
0
class EventIndexPage(TypesetBodyMixin, HeroMixin, Page):
    """ List of all events that have been created from events page """

    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('body'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    def get_context(self, request):
        context = super(EventIndexPage, self).get_context(request)
        page = request.GET.get('page', None)
        events = EventPage.objects.live().order_by('-start_date')

        paginator = Paginator(events, MAX_PAGE_SIZE)
        try:
            context['events'] = paginator.page(page)
        except PageNotAnInteger:
            context['events'] = paginator.page(1)
        except EmptyPage:
            context['events'] = paginator.page(paginator.num_pages)

        context['paginator_range'] = get_paginator_range(
            paginator, context['events'])

        return context

    class Meta:
        verbose_name = "Event Index Page"

    subpage_types = ['EventPage', 'general.General']
Esempio n. 6
0
class StandardPage(SectionBodyMixin, TypesetBodyMixin, HeroMixin, Page):
    """
    A generic content page. It could be used for any type of page content that only needs a hero,
    streamfield content, and related fields
    """
    other_pages_heading = models.CharField(
        blank=True,
        max_length=255,
        verbose_name='Heading',
        default='Related content'
    )

    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('body'),
        StreamFieldPanel('sections'),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel('other_pages', label='Related links')
        ], heading='Other Pages/Related Links'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    def get_context(self, request):
        context = super().get_context(request)

        context['related_pages'] = get_related_pages(self, self.other_pages.all())

        return context

    class Meta():
        verbose_name = 'Standard Page'
Esempio n. 7
0
class EventPage(TypesetBodyMixin, HeroMixin, Page):
    """ Content of each event """

    start_date = models.DateField(default=datetime.now)
    end_date = models.DateField(default=datetime.now)
    time = models.CharField(max_length=160,
                            help_text='Time information for event',
                            blank=True,
                            null=True)
    location = models.CharField(max_length=100,
                                help_text='Physical location of event',
                                blank=True,
                                null=True)
    registration_link = models.URLField(blank=True, null=True)
    raw_content = models.TextField(null=True, blank=True)

    other_pages_heading = models.CharField(
        blank=True,
        max_length=255,
        verbose_name='Section Heading',
        default='Related content',
    )

    content_panels = Page.content_panels + [
        hero_panels(),
        MultiFieldPanel([
            FieldPanel('start_date'),
            FieldPanel('end_date'),
            FieldPanel('time'),
            FieldPanel('location'),
        ],
                        heading='Event Details'),
        FieldPanel('registration_link'),
        StreamFieldPanel('body'),
        FieldPanel('raw_content'),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel('event_related_links',
                        label='Related Pages',
                        max_num=MAX_RELATED_LINKS)
        ],
                        heading='Other Pages'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = ['general.General']
    parent_page_types = ['EventIndexPage']

    def get_context(self, request):
        context = super().get_context(request)

        context['related_pages'] = get_related_pages(
            self, self.event_related_links.all(), EventPage.objects)

        return context

    class Meta:
        verbose_name = "Event Page"
Esempio n. 8
0
class WhatWeDoPage(TypesetBodyMixin, HeroMixin, Page):
    """
    http://development-initiatives.surge.sh/page-templates/07-what-we-do
    """
    class Meta:
        verbose_name = 'What We Do Page'

    sections = StreamField([('locations_map', LocationsMapBlock()),
                            ('focus_area', FocusAreasBlock()),
                            ('expertise', ExpertiseBlock()),
                            ('banner', BannerBlock()),
                            ('video_duo', VideoDuoTextBlock()),
                            ('image_duo', ImageDuoTextBlock()),
                            ('testimonial', TestimonialBlock())],
                           verbose_name="Sections",
                           null=True,
                           blank=True)
    other_pages_heading = models.CharField(blank=True,
                                           max_length=255,
                                           verbose_name='Heading',
                                           default='More about')
    locations_where_we_work = StreamField(
        MapStreamBlock,
        verbose_name="Add Where We Work Locations",
        null=True,
        blank=True)

    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('body'),
        StreamFieldPanel('sections'),
        StreamFieldPanel('locations_where_we_work'),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel(
                'other_pages', label='Related pages', max_num=MAX_OTHER_PAGES)
        ],
                        heading='Other Pages/Related Links'),
        InlinePanel('page_notifications', label='Notifications'),
    ]

    subpage_types = [
        'project.FocusAreasPage', 'whatwedo.ServicesPage',
        'news.NewsIndexPage', 'events.EventIndexPage', 'place.PlacesPage',
        'general.General'
    ]
    parent_page_types = ['home.HomePage']
Esempio n. 9
0
class NewsIndexPage(HeroMixin, Page):
    intro = RichTextField(blank=True,
                          null=True,
                          help_text="Something about our newsletters",
                          features=RICHTEXT_FEATURES_NO_FOOTNOTES)

    content_panels = Page.content_panels + [
        hero_panels(),
        FieldPanel('intro'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = ['NewsStoryPage', 'general.General']
    parent_page_types = ['whatwedo.WhatWeDoPage']

    class Meta():
        verbose_name = 'News Index Page'

    def get_context(self, request):
        context = super(NewsIndexPage, self).get_context(request)
        page = request.GET.get('page', None)
        topic_filter = request.GET.get('topic', None)
        if topic_filter:
            news_stories = NewsStoryPage.objects.live().filter(
                topics__slug=topic_filter).order_by('-published_date')
        else:
            news_stories = NewsStoryPage.objects.live().order_by(
                '-published_date')

        paginator = Paginator(news_stories, MAX_PAGE_SIZE)
        try:
            context['stories'] = paginator.page(page)
        except PageNotAnInteger:
            context['stories'] = paginator.page(1)
        except EmptyPage:
            context['stories'] = paginator.page(paginator.num_pages)

        news_content_type = ContentType.objects.get_for_model(NewsStoryPage)
        context['topics'] = Tag.objects.filter(
            news_newstopic_items__content_object__content_type=news_content_type
        ).distinct()
        context['selected_topic'] = topic_filter
        context['paginator_range'] = get_paginator_range(
            paginator, context['stories'])
        context['newsletter'] = NewsLetter.objects.first()

        return context
Esempio n. 10
0
class BlogIndexPage(HeroMixin, Page):
    subpage_types = ['general.General', 'BlogArticlePage']
    parent_page_types = ['home.HomePage']

    class Meta():
        verbose_name = 'Blog Index Page'

    def get_context(self, request):
        context = super(BlogIndexPage, self).get_context(request)
        page = request.GET.get('page', None)
        topic_filter = request.GET.get('topic', None)
        if topic_filter:
            articles = BlogArticlePage.objects.live().filter(topics__slug=topic_filter).order_by('-published_date')
        else:
            articles = BlogArticlePage.objects.live().order_by('-published_date')

        if not request.user.is_authenticated:
            articles = articles.public()

        paginator = Paginator(articles, MAX_PAGE_SIZE)
        try:
            context['articles'] = paginator.page(page)
        except PageNotAnInteger:
            context['articles'] = paginator.page(1)
        except EmptyPage:
            context['articles'] = paginator.page(paginator.num_pages)

        blog_content_type = ContentType.objects.get_for_model(BlogArticlePage)
        context['topics'] = Tag.objects.filter(
            blog_blogtopic_items__content_object__content_type=blog_content_type
        ).distinct().order_by('name')
        context['selected_topic'] = topic_filter
        context['paginator_range'] = get_paginator_range(paginator, context['articles'])

        return context

    content_panels = Page.content_panels + [
        hero_panels(),
        InlinePanel('page_notifications', label='Notifications')
    ]
Esempio n. 11
0
class MediaCenterPage(TypesetBodyMixin, HeroMixin, Page):
    contact_box = StreamField([('contact', ContactBlock())],
                              null=True,
                              blank=True)
    spokespeople = StreamField([('person', PersonBlock())],
                               null=True,
                               blank=True)

    def get_context(self, request):
        context = super(MediaCenterPage, self).get_context(request)
        page = request.GET.get('page', None)
        news_stories = NewsStoryPage.objects.live().filter(
            press_release=True).order_by('-published_date')

        paginator = Paginator(news_stories, MAX_PAGE_SIZE)
        try:
            context['stories'] = paginator.page(page)
        except PageNotAnInteger:
            context['stories'] = paginator.page(1)
        except EmptyPage:
            context['stories'] = paginator.page(paginator.num_pages)

        context['paginator_range'] = get_paginator_range(
            paginator, context['stories'])

        return context

    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('contact_box'),
        StreamFieldPanel('body'),
        StreamFieldPanel('spokespeople'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    class Meta():
        verbose_name = 'Media Center Page'

    subpage_types = ['general.General']
    parent_page_types = ['home.HomePage']
Esempio n. 12
0
class OurTeamPage(HeroMixin, Page):

    """ List of Team Members Page """

    other_pages_heading = models.CharField(
        blank=True,
        max_length=255,
        verbose_name='Heading',
        default='More about'
    )

    def get_context(self, request):
        context = super(OurTeamPage, self).get_context(request)
        team_filter = request.GET.get('team-filter', None)
        if team_filter:
            context['profiles'] = TeamMemberPage.objects.live().filter(teammember_departments__department__slug=team_filter).order_by('name')
        else:
            context['profiles'] = TeamMemberPage.objects.live().order_by('name')
        context['departments'] = Department.objects.all()
        context['selected_team'] = team_filter

        return context

    class Meta:
        verbose_name = "Our Team Page"

    subpage_types = ['TeamMemberPage', 'general.General']
    parent_page_types = ['about.WhoWeArePage']

    content_panels = Page.content_panels + [
        hero_panels(),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel('other_pages', label='Related pages')
        ], heading='Other Pages/Related Links'),
        InlinePanel('page_notifications', label='Notifications')
    ]
Esempio n. 13
0
class VacancyPage(TypesetBodyMixin, SectionBodyMixin, HeroMixin, Page):
    vacancy = models.ForeignKey('users.JobTitle',
                                null=True,
                                on_delete=models.SET_NULL,
                                related_name='+')
    duration = models.CharField(null=True, max_length=255)
    location = models.ForeignKey(OfficeLocation,
                                 null=True,
                                 on_delete=models.SET_NULL,
                                 related_name='+')
    salary_scale = models.CharField(blank=True, max_length=255)
    application_close = models.DateField(blank=True,
                                         null=True,
                                         auto_now=False,
                                         auto_now_add=False)
    first_interview = models.CharField(blank=True, null=True, max_length=255)
    second_interview = models.CharField(blank=True, null=True, max_length=255)
    job_start = models.DateField(blank=True,
                                 null=True,
                                 auto_now=False,
                                 auto_now_add=False)
    other_pages_heading = models.CharField(
        blank=True,
        max_length=255,
        verbose_name='Heading',
        default='Learn more about Development Initiatives')
    downloads_title = models.CharField(
        blank=True,
        max_length=255,
        default='Apply for this position',
        verbose_name='Title',
        help_text='Title for the downloads section on a vacancy page')
    downloads_description = RichTextField(
        blank=True,
        verbose_name='Description',
        help_text='Optional: a brief description of what to do in this section',
        features=RICHTEXT_FEATURES_NO_FOOTNOTES)

    content_panels = Page.content_panels + [
        hero_panels(),
        MultiFieldPanel([
            FieldPanel('vacancy'),
            FieldPanel('duration'),
            FieldPanel('location'),
            FieldPanel('salary_scale')
        ],
                        heading='Vacancy Info'),
        MultiFieldPanel([
            FieldPanel('application_close'),
            FieldPanel('first_interview'),
            FieldPanel('second_interview'),
            FieldPanel('job_start')
        ],
                        heading='Dates'),
        StreamFieldPanel('body'),
        MultiFieldPanel([
            FieldPanel('downloads_title'),
            FieldPanel('downloads_description'),
            InlinePanel('page_downloads', label='Download', max_num=None)
        ],
                        heading='Downloads'),
        StreamFieldPanel('sections'),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel('other_pages', label='Other Pages')
        ],
                        heading='Other Pages'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = ['general.General']
    parent_page_types = ['VacancyIndexPage']

    @cached_property
    def get_page_downloads(self):
        return self.page_downloads.all()

    class Meta():
        db_table = 'vacancy_page'
        verbose_name = 'Vacancy Page'
Esempio n. 14
0
class ContactPage(TypesetBodyMixin, HeroMixin, Page):
    """
        Form with pre-built form fields to handle contact us info
    """
    template = 'contactus/contact_page.html'
    landing_template = 'contactus/contact_page_landing.html'

    success_alert = models.CharField(
        max_length=255,
        default='Your message was sent successfully',
    )

    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('body'),
        FieldPanel('success_alert', classname="full"),
        InlinePanel('page_notifications', label='Notifications')
    ]

    class Meta():
        verbose_name = 'Contact Us Page'

    subpage_types = ['general.General']
    parent_page_types = ['home.HomePage']

    def render_landing_page(
            self,
            request,
            form_submission=None,
            *args,
            **kwargs):
        """
        Renders the landing page as used in wagtails default form implementation
        """
        context = self.get_context(request)
        context['form_submission'] = form_submission
        return render(
            request,
            self.landing_template,
            context
        )

    def generate_hubspot_object(self, form_object):

        today = date.today()
        subject = today.strftime("%Y%m%d")

        hubspot_payload = []
        kv_p = {}
        kv_p['name'] = 'subject'
        kv_p['value'] = HS_TICKET_PREFIX + subject
        hubspot_payload.append(kv_p)

        kv_p2 = {}
        kv_p2['name'] = 'hs_pipeline'
        kv_p2['value'] = settings.HS_TICKET_PIPELINE
        hubspot_payload.append(kv_p2)

        kv_p3 = {}
        kv_p3['name'] = 'hs_pipeline_stage'
        kv_p3['value'] = settings.HS_TICKET_PIPELINE_STAGE
        hubspot_payload.append(kv_p3)

        kv_p4 = {}
        kv_p4['name'] = 'client_first_name'
        kv_p4['value'] = form_object.get('name')
        hubspot_payload.append(kv_p4)

        kv_p5 = {}
        kv_p5['name'] = 'organisation'
        kv_p5['value'] = form_object.get('organisation')
        hubspot_payload.append(kv_p5)

        kv_p6 = {}
        kv_p6['name'] = 'email_address'
        kv_p6['value'] = form_object.get('email_address')
        hubspot_payload.append(kv_p6)

        kv_p7 = {}
        kv_p7['name'] = 'contact_details'
        kv_p7['value'] = form_object.get('telephone')
        hubspot_payload.append(kv_p7)

        kv_p8 = {}
        kv_p8['name'] = 'content'
        kv_p8['value'] = form_object.get('message')
        hubspot_payload.append(kv_p8)

        return hubspot_payload

    def serve(self, request, *args, **kwargs):
        if request.method == 'POST':
            form = ContactUsForm(request.POST)

            """
                Check if hidden field has been filled by robots, if its filled; then its spam,
                return the default form page to be refilled
            """
            try:
                if request.POST.get(HONEYPOT_FORM_FIELD, '') != '':
                    context = self.get_context(request)
                    context['form'] = form

                    return render(
                        request,
                        self.get_template(request),
                        context
                    )
            except KeyError:
                # If honeypot fails, form should be marked as possible spam
                pass

            if form.is_valid():
                form_submission = form.save()

                hs_obj = self.generate_hubspot_object(request.POST)
                create_new_ticket(hs_obj)

                return self.render_landing_page(
                    request, form_submission, *args, **kwargs)
            else:
                context = self.get_context(request)
                context['form'] = form

                return render(
                    request,
                    self.get_template(request),
                    context
                )

        else:
            form = ContactUsForm()

            context = self.get_context(request)
            context['form'] = form

            return render(
                request,
                self.get_template(request),
                context
            )
Esempio n. 15
0
class LegacyPublicationPage(HeroMixin, PublishedDateMixin,
                            ParentPageSearchMixin, FilteredDatasetMixin,
                            CallToActionMixin, ReportDownloadMixin, Page):
    class Meta:
        verbose_name = 'Legacy Publication'

    parent_page_types = ['PublicationIndexPage']
    subpage_types = []

    colour = models.CharField(max_length=256,
                              choices=COLOUR_CHOICES,
                              default=RED)
    authors = StreamField(
        [('internal_author',
          PageChooserBlock(required=False,
                           target_model='ourteam.TeamMemberPage',
                           icon='fa-user',
                           label='Internal Author')),
         ('external_author',
          StructBlock([('name', CharBlock(required=False)),
                       ('title', CharBlock(required=False)),
                       ('photograph', ImageChooserBlock(required=False)),
                       ('page', URLBlock(required=False))],
                      icon='fa-user',
                      label='External Author'))],
        blank=True)
    publication_type = models.ForeignKey(PublicationType,
                                         related_name="+",
                                         null=True,
                                         blank=False,
                                         on_delete=models.SET_NULL,
                                         verbose_name="Resource Type")
    topics = ClusterTaggableManager(through=LegacyPublicationTopic,
                                    blank=True,
                                    verbose_name="Topics")

    raw_content = models.TextField(null=True, blank=True)
    content = RichTextField(help_text='Content for the legacy report',
                            null=True,
                            blank=True,
                            features=RICHTEXT_FEATURES)
    summary_image = WagtailImageField(
        required=False,
        help_text='Optimal minimum size 800x400px',
    )

    content_panels = Page.content_panels + [
        FieldPanel('colour'),
        hero_panels(),
        StreamFieldPanel('authors'),
        call_to_action_panel(),
        SnippetChooserPanel('publication_type'),
        FieldPanel('topics'),
        InlinePanel('page_countries', label="Countries"),
        PublishedDatePanel(),
        InlinePanel('publication_datasets', label='Datasets'),
        DownloadsPanel(heading='Reports',
                       description='Report downloads for this legacy report.'),
        DownloadsPanel(
            related_name='data_downloads',
            heading='Data downloads',
            description='Optional: data download for this legacy report.'),
        ReportDownloadPanel(),
        MultiFieldPanel([
            FieldPanel('content'),
            FieldPanel('raw_content'),
        ],
                        heading='Summary',
                        description='Summary for the legacy publication.'),
        InlinePanel('page_notifications', label='Notifications'),
        InlinePanel('publication_related_links',
                    label='Related links',
                    max_num=MAX_RELATED_LINKS),
    ]

    @cached_property
    def publication_downloads_title(self):
        return 'Downloads'

    @cached_property
    def publication_downloads_list(self):
        return get_downloads(self)

    @cached_property
    def data_downloads_title(self):
        return 'Data downloads'

    @cached_property
    def data_downloads_list(self):
        return get_downloads(self, with_parent=False, data=True)

    @cached_property
    def page_publication_downloads(self):
        return self.publication_downloads.all()

    @cached_property
    def page_data_downloads(self):
        return self.data_downloads.all()

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)

        context['related_pages'] = get_related_pages(
            self, self.publication_related_links.all(),
            LegacyPublicationPage.objects)

        return context
Esempio n. 16
0
class PublicationAppendixPage(HeroMixin, ReportChildMixin,
                              FlexibleContentMixin, PageSearchMixin, UUIDMixin,
                              FilteredDatasetMixin, ReportDownloadMixin, Page):
    class Meta:
        verbose_name = 'Publication Appendix'
        verbose_name_plural = 'Publication Appendices'

    parent_page_types = ['PublicationPage']
    subpage_types = []

    appendix_number = models.PositiveIntegerField(
        choices=[(i, num2words(i).title()) for i in range(1, 21)])
    colour = models.CharField(max_length=256,
                              choices=COLOUR_CHOICES,
                              default=RED)

    content_panels = Page.content_panels + [
        FieldPanel('colour'),
        hero_panels(),
        MultiFieldPanel(
            [
                FieldPanel('appendix_number', widget=forms.Select),
            ],
            heading='Appendix number',
            description=
            'Appendix number: this should be unique for each appendix of a report.'
        ),
        ContentPanel(),
        InlinePanel('publication_datasets', label='Datasets'),
        DownloadsPanel(heading='Downloads',
                       description='Downloads for this appendix page.'),
        DownloadsPanel(
            related_name='data_downloads',
            heading='Data downloads',
            description='Optional: data download for this appendix page.'),
        ReportDownloadPanel(),
        InlinePanel('page_notifications', label='Notifications'),
        InlinePanel('publication_related_links',
                    label='Related links',
                    max_num=MAX_RELATED_LINKS),
    ]

    @cached_property
    def appendix_word(self):
        return num2words(self.appendix_number)

    @cached_property
    def label_type(self):
        return 'appendix'

    @cached_property
    def label(self):
        return 'appendix %s' % self.appendix_word

    @cached_property
    def label_num(self):
        return 'appendix %s' % str(self.appendix_number).zfill(2)

    @cached_property
    def nav_label(self):
        return 'appendix %s' % self.appendix_word

    @cached_property
    def publication_downloads_title(self):
        return 'Downloads'

    @cached_property
    def publication_downloads_list(self):
        return get_downloads(self)

    @cached_property
    def data_downloads_title(self):
        return 'Data downloads'

    @cached_property
    def data_downloads_list(self):
        return get_downloads(self, with_parent=False, data=True)

    @cached_property
    def page_publication_downloads(self):
        return self.publication_downloads.all()

    @cached_property
    def page_data_downloads(self):
        return self.data_downloads.all()

    @cached_property
    def sections(self):
        sections = []
        for block in self.content:
            if block.block_type == 'section_heading':
                sections.append(block)
        return sections
Esempio n. 17
0
class PublicationSummaryPage(HeroMixin, ReportChildMixin, FlexibleContentMixin,
                             PageSearchMixin, UniqueForParentPageMixin,
                             UUIDMixin, FilteredDatasetMixin,
                             ReportDownloadMixin, InheritCTAMixin, Page):
    class Meta:
        verbose_name = 'Publication Summary'
        verbose_name_plural = 'Publication Summaries'

    parent_page_types = ['PublicationPage']
    subpage_types = []

    colour = models.CharField(max_length=256,
                              choices=COLOUR_CHOICES,
                              default=RED)

    content_panels = Page.content_panels + [
        FieldPanel('colour'),
        hero_panels(),
        ContentPanel(),
        InlinePanel('publication_datasets', label='Datasets'),
        DownloadsPanel(heading='Downloads',
                       description='Downloads for this summary.'),
        DownloadsPanel(
            related_name='data_downloads',
            heading='Data downloads',
            description='Optional: data download for this summary.'),
        ReportDownloadPanel(),
        InlinePanel('page_notifications', label='Notifications'),
    ]

    @cached_property
    def label_type(self):
        return 'summary'

    @cached_property
    def label(self):
        return 'the executive summary'

    @cached_property
    def nav_label(self):
        return 'executive summary'

    @cached_property
    def publication_downloads_title(self):
        return 'Downloads'

    @cached_property
    def publication_downloads_list(self):
        return get_downloads(self)

    @cached_property
    def data_downloads_title(self):
        return 'Data downloads'

    @cached_property
    def data_downloads_list(self):
        return get_downloads(self, with_parent=False, data=True)

    @cached_property
    def page_publication_downloads(self):
        return self.publication_downloads.all()

    @cached_property
    def page_data_downloads(self):
        return self.data_downloads.all()

    @cached_property
    def sections(self):
        sections = []
        for block in self.content:
            if block.block_type == 'section_heading':
                sections.append(block)
        return sections
Esempio n. 18
0
class PublicationForewordPage(HeroMixin, ReportChildMixin,
                              FlexibleContentMixin, PageSearchMixin,
                              UniqueForParentPageMixin, UUIDMixin,
                              FilteredDatasetMixin, ReportDownloadMixin,
                              InheritCTAMixin, Page):
    class Meta:
        verbose_name = 'Publication Foreword'

    parent_page_types = ['PublicationPage']
    subpage_types = []

    colour = models.CharField(max_length=256,
                              choices=COLOUR_CHOICES,
                              default=RED)

    content_panels = Page.content_panels + [
        hero_panels(),
        FieldPanel('colour'),
        ContentPanel(),
        InlinePanel('publication_datasets', label='Datasets'),
        DownloadsPanel(heading='Downloads',
                       description='Downloads for this foreword.'),
        DownloadsPanel(
            related_name='data_downloads',
            heading='Data downloads',
            description='Optional: data download for this foreword.',
            max_num=1,
        ),
        ReportDownloadPanel(),
        InlinePanel('publication_related_links',
                    label='Related links',
                    max_num=MAX_RELATED_LINKS),
        InlinePanel('page_notifications', label='Notifications')
    ]

    @cached_property
    def label(self):
        return 'the foreword'

    @cached_property
    def nav_label(self):
        return 'foreword'

    @cached_property
    def publication_downloads_title(self):
        return 'Downloads'

    @cached_property
    def publication_downloads_list(self):
        return get_downloads(self)

    @cached_property
    def data_downloads_title(self):
        return 'Data downloads'

    @cached_property
    def data_downloads_list(self):
        return get_downloads(self, with_parent=False, data=True)

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)

        context['related_pages'] = get_related_pages(
            self, self.publication_related_links.all(),
            PublicationForewordPage.objects)

        return context
Esempio n. 19
0
class PublicationPage(HeroMixin, HeroButtonMixin, PublishedDateMixin,
                      ParentPageSearchMixin, UUIDMixin, FilteredDatasetMixin,
                      ReportDownloadMixin, Page):
    class Meta:
        verbose_name = 'Publication Page'

    parent_page_types = ['PublicationIndexPage', 'general.General']
    subpage_types = [
        'PublicationForewordPage',
        'PublicationSummaryPage',
        'PublicationChapterPage',
        'PublicationAppendixPage',
    ]

    colour = models.CharField(max_length=256,
                              choices=COLOUR_CHOICES,
                              default=RED)

    authors = StreamField(
        [('internal_author',
          PageChooserBlock(required=False,
                           target_model='ourteam.TeamMemberPage',
                           icon='fa-user',
                           label='Internal Author')),
         ('external_author',
          StructBlock([('name', CharBlock(required=False)),
                       ('title', CharBlock(required=False)),
                       ('photograph', ImageChooserBlock(required=False)),
                       ('page', URLBlock(required=False))],
                      icon='fa-user',
                      label='External Author'))],
        blank=True)

    publication_type = models.ForeignKey(PublicationType,
                                         related_name="+",
                                         null=True,
                                         blank=False,
                                         on_delete=models.SET_NULL,
                                         verbose_name="Resource Type")
    topics = ClusterTaggableManager(through=PublicationTopic,
                                    blank=True,
                                    verbose_name="Topics")

    content_panels = Page.content_panels + [
        FieldPanel('colour'),
        hero_panels(),
        MultiFieldPanel([
            FieldPanel('read_online_button_text'),
            FieldPanel('request_hard_copy_text'),
        ],
                        heading='Hero Button Captions',
                        description='Edit captions for hero buttons'),
        StreamFieldPanel('authors'),
        SnippetChooserPanel('publication_type'),
        FieldPanel('topics'),
        InlinePanel('publication_datasets', label='Datasets'),
        InlinePanel('page_countries', label="Countries"),
        PublishedDatePanel(),
        DownloadsPanel(heading='Downloads',
                       description='Downloads for this report.'),
        DownloadsPanel(related_name='data_downloads',
                       heading='Data downloads',
                       description='Optional: data download for this report.'),
        ReportDownloadPanel(),
        UUIDPanel(),
        InlinePanel('page_notifications', label='Notifications'),
        InlinePanel('publication_related_links',
                    label='Related links',
                    max_num=MAX_RELATED_LINKS),
        InlinePanel('publication_cta', label='Call To Action', max_num=2),
    ]

    @cached_property
    def publication_downloads_title(self):
        return 'Downloads'

    @cached_property
    def publication_downloads_list(self):
        return get_downloads(self)

    @cached_property
    def data_downloads_title(self):
        return 'Data downloads'

    @cached_property
    def data_downloads_list(self):
        return get_downloads(self, with_parent=False, data=True)

    @cached_property
    def page_publication_downloads(self):
        return self.publication_downloads.all()

    @cached_property
    def page_data_downloads(self):
        return self.data_downloads.all()

    @cached_property
    def foreword(self):
        return get_first_child_of_type(self, PublicationForewordPage)

    @cached_property
    def summary(self):
        return get_first_child_of_type(self, PublicationSummaryPage)

    @cached_property
    def chapters(self):
        return get_ordered_children_of_type(
            self, PublicationChapterPage,
            'publicationchapterpage__chapter_number')

    @cached_property
    def appendices(self):
        return get_ordered_children_of_type(
            self, PublicationAppendixPage,
            'publicationappendixpage__appendix_number')

    @cached_property
    def listing(self):
        children = [self.foreword, self.summary]
        children += list(self.chapters)
        return list(filter(None, children))

    @cached_property
    def meta_and_appendices(self):
        children = list()
        children += list(self.appendices)
        return list(filter(None, children))

    @cached_property
    def listing_and_appendicies(self):
        return self.listing + self.meta_and_appendices

    @cached_property
    def chapter_max(self):
        try:
            return max([chapter.chapter_number for chapter in self.chapters])
        except ValueError:
            return 0

    @cached_property
    def call_to_action(self):
        return self.publication_cta.all()

    @cached_property
    def call_to_action_has_top_position(self):
        for cta in self.publication_cta.all():
            if cta.position == 'top':
                return True
        return False

    def save(self, *args, **kwargs):
        super(PublicationPage, self).save(*args, **kwargs)

        old_path = '/%s' % self.slug
        redirect = Redirect.objects.filter(old_path=old_path).first()
        if not redirect:
            Redirect(old_path=old_path, redirect_page=self).save()

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)

        context['related_pages'] = get_related_pages(
            self, self.publication_related_links.all(),
            PublicationPage.objects)

        return context
Esempio n. 20
0
class PublicationIndexPage(HeroMixin, Page):

    content_panels = Page.content_panels + [
        hero_panels(),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = [
        'PublicationPage', 'LegacyPublicationPage', 'ShortPublicationPage',
        'general.General', 'AudioVisualMedia'
    ]
    parent_page_types = ['home.HomePage']

    def get_context(self, request):
        context = super(PublicationIndexPage, self).get_context(request)
        search_filter = request.GET.get('q', None)
        if search_filter:
            sort_options = [('date_desc', 'newest first'),
                            ('date_asc', 'oldest first'),
                            ('score', 'relevance')]
        else:
            sort_options = [('date_desc', 'newest first'),
                            ('date_asc', 'oldest first')]
        sort_ids = [sort_opt[0] for sort_opt in sort_options]
        page = request.GET.get('page', None)
        topic_filter = request.GET.get('topic', None)
        country_filter = request.GET.get('country', None)
        types_filter = request.GET.get('types', None)
        selected_sort = request.GET.get('sort', 'date_desc')
        if selected_sort not in sort_ids:
            selected_sort = 'date_desc'

        if topic_filter:
            stories = PublicationPage.objects.descendant_of(
                self).live().filter(topics__slug=topic_filter)
            legacy_pubs = LegacyPublicationPage.objects.descendant_of(
                self).live().filter(topics__slug=topic_filter)
            short_pubs = ShortPublicationPage.objects.descendant_of(
                self).live().filter(topics__slug=topic_filter)
            audio_visual_media = AudioVisualMedia.objects.descendant_of(
                self).live().filter(topics__slug=topic_filter)
        else:
            stories = PublicationPage.objects.descendant_of(self).live()
            legacy_pubs = LegacyPublicationPage.objects.descendant_of(
                self).live()
            short_pubs = ShortPublicationPage.objects.descendant_of(
                self).live()
            audio_visual_media = AudioVisualMedia.objects.descendant_of(
                self).live()

        if not request.user.is_authenticated:
            stories = stories.public()
            legacy_pubs = legacy_pubs.public()
            short_pubs = short_pubs.public()
            audio_visual_media = audio_visual_media.public()

        if country_filter:
            stories = stories.filter(
                page_countries__country__slug=country_filter)
            legacy_pubs = legacy_pubs.filter(
                page_countries__country__slug=country_filter)
            short_pubs = short_pubs.filter(
                page_countries__country__slug=country_filter)
            audio_visual_media = audio_visual_media.filter(
                page_countries__country__slug=country_filter)

        if types_filter:
            stories = stories.filter(publication_type__slug=types_filter)
            legacy_pubs = legacy_pubs.filter(
                publication_type__slug=types_filter)
            short_pubs = short_pubs.filter(publication_type__slug=types_filter)
            audio_visual_media = audio_visual_media.filter(
                publication_type__slug=types_filter)

        if search_filter:
            query = Query.get(search_filter)
            query.add_hit()
            if stories:
                child_count = reduce(
                    operator.add, [len(pub.get_children()) for pub in stories])
                if child_count:
                    pub_children = reduce(
                        operator.or_,
                        [pub.get_children()
                         for pub in stories]).live().specific().search(
                             search_filter).annotate_score("_child_score")
                    if pub_children:
                        matching_parents = reduce(operator.or_, [
                            stories.parent_of(child).annotate(
                                _score=models.Value(
                                    child._child_score,
                                    output_field=models.FloatField()))
                            for child in pub_children
                        ])
                        stories = list(
                            chain(
                                stories.exclude(id__in=matching_parents.
                                                values_list('id', flat=True)).
                                search(search_filter).annotate_score("_score"),
                                matching_parents))
                    else:
                        stories = stories.search(search_filter).annotate_score(
                            "_score")
                else:
                    stories = stories.search(search_filter).annotate_score(
                        "_score")
            legacy_pubs = legacy_pubs.search(search_filter).annotate_score(
                "_score")
            short_pubs = short_pubs.search(search_filter).annotate_score(
                "_score")
            audio_visual_media = audio_visual_media.search(
                search_filter).annotate_score('_score')

        story_list = list(
            chain(stories, legacy_pubs, short_pubs, audio_visual_media))
        elasticsearch_is_active = True
        for story in story_list:
            if hasattr(story, "_score"):
                if story._score is None:
                    elasticsearch_is_active = False
        if selected_sort == "score" and elasticsearch_is_active:
            story_list.sort(key=lambda x: x._score, reverse=True)
        elif selected_sort == "date_asc":
            story_list.sort(key=lambda x: x.published_date, reverse=False)
        else:
            story_list.sort(key=lambda x: x.published_date, reverse=True)

        promos = get_search_promotions(search_filter)
        promo_pages = [
            promo.page.specific for promo in promos
            if promo.page.live and isinstance(promo.page.specific, (
                PublicationPage, ShortPublicationPage, LegacyPublicationPage))
        ]
        if promo_pages:
            story_list = [
                story for story in story_list if story not in promo_pages
            ]
            story_list = list(chain(promo_pages, story_list))

        paginator = Paginator(story_list, MAX_PAGE_SIZE)
        try:
            context['stories'] = paginator.page(page)
        except PageNotAnInteger:
            context['stories'] = paginator.page(1)
        except EmptyPage:
            context['stories'] = paginator.page(paginator.num_pages)

        pubs_content_type = ContentType.objects.get_for_model(PublicationPage)
        leg_pubs_content_type = ContentType.objects.get_for_model(
            LegacyPublicationPage)
        short_pubs_content_type = ContentType.objects.get_for_model(
            ShortPublicationPage)
        context['topics'] = Tag.objects.filter(
            models.
            Q(publications_publicationtopic_items__content_object__content_type
              =pubs_content_type) | models.
            Q(publications_legacypublicationtopic_items__content_object__content_type
              =leg_pubs_content_type) | models.
            Q(publications_shortpublicationtopic_items__content_object__content_type
              =short_pubs_content_type)).distinct().order_by('name')
        resource_types = PublicationType.objects.filter(
            show_in_filter=True).order_by('resource_category', 'name')
        context['resource_types'] = resource_types
        # ensure only used resource types are pushed to the page
        for resource_type in resource_types:
            if not self.resource_type_has_publications(resource_type):
                context['resource_types'] = context['resource_types'].exclude(
                    id=resource_type.id)
        context['selected_type'] = types_filter
        context['selected_topic'] = topic_filter
        context['countries'] = Country.objects.all().order_by('region', 'name')
        context['selected_country'] = country_filter
        context['search_filter'] = search_filter
        context['selected_sort'] = selected_sort
        context['sort_options'] = sort_options
        context[
            'is_filtered'] = search_filter or topic_filter or country_filter or types_filter
        context['paginator_range'] = get_paginator_range(
            paginator, context['stories'])

        return context

    def resource_type_has_publications(self, resource_type):
        return (PublicationPage.objects.filter(
            publication_type=resource_type).first()
                or ShortPublicationPage.objects.filter(
                    publication_type=resource_type).first()
                or LegacyPublicationPage.objects.filter(
                    publication_type=resource_type).first()
                or AudioVisualMedia.objects.filter(
                    publication_type=resource_type).first())

    class Meta():
        verbose_name = 'Resources Index Page'
Esempio n. 21
0
class AudioVisualMedia(PublishedDateMixin, TypesetBodyMixin, HeroMixin,
                       ParentPageSearchMixin, SectionBodyMixin,
                       CallToActionMixin, Page):
    """
    Audio Visual page to be used as a child of the Resources Index Page
    """

    template = 'publications/audio_visual_media.html'

    publication_type = models.ForeignKey(PublicationType,
                                         related_name="+",
                                         null=True,
                                         blank=False,
                                         on_delete=models.SET_NULL,
                                         verbose_name="Resource Type")

    participants = StreamField(
        [('internal_participant',
          PageChooserBlock(required=False,
                           target_model='ourteam.TeamMemberPage',
                           icon='fa-user',
                           label='Internal Participant')),
         ('external_participant',
          StructBlock([('name', CharBlock(required=False)),
                       ('title', CharBlock(required=False)),
                       ('photograph', ImageChooserBlock(required=False)),
                       ('page', URLBlock(required=False))],
                      icon='fa-user',
                      label='External Participant'))],
        blank=True,
        help_text="The people involved in the podcast or webinar")
    topics = ClusterTaggableManager(through=AudioVisualMediaTopic,
                                    blank=True,
                                    verbose_name="Topics")

    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('participants'),
        call_to_action_panel(),
        StreamFieldPanel('body'),
        StreamFieldPanel('sections'),
        FieldPanel('publication_type'),
        InlinePanel('page_countries', label="Countries"),
        FieldPanel('topics'),
        PublishedDatePanel(),
        InlinePanel('publication_related_links',
                    label='Related links',
                    max_num=MAX_RELATED_LINKS),
        InlinePanel('page_notifications', label='Notifications'),
    ]

    parent_page_types = ['PublicationIndexPage']
    subpage_types = []

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)

        context['related_pages'] = get_related_pages(
            self, self.publication_related_links.all(),
            AudioVisualMedia.objects)

        return context

    class Meta:
        verbose_name = 'Audio and Visual Media Page'
Esempio n. 22
0
class DataSectionPage(TypesetBodyMixin, HeroMixin, Page):
    """ Main page for datasets """

    quotes = StreamField(QuoteStreamBlock,
                         verbose_name="Quotes",
                         null=True,
                         blank=True)
    dataset_info = RichTextField(null=True,
                                 blank=True,
                                 help_text='A description of the datasets',
                                 features=RICHTEXT_FEATURES_NO_FOOTNOTES)
    tools = StreamField([
        ('tool', BannerBlock(template='datasection/tools_banner_block.html'))
    ],
                        verbose_name="Tools",
                        null=True,
                        blank=True)
    other_pages_heading = models.CharField(blank=True,
                                           max_length=255,
                                           verbose_name='Heading',
                                           default='More about')

    content_panels = Page.content_panels + [
        hero_panels(allowed_pages=['datasection.DataSetListing']),
        StreamFieldPanel('body'),
        FieldPanel('dataset_info'),
        StreamFieldPanel('tools'),
        StreamFieldPanel('quotes'),
        MultiFieldPanel([
            FieldPanel('other_pages_heading'),
            InlinePanel('other_pages', label='Related pages')
        ],
                        heading='Other Pages/Related Links'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    parent_page_types = ['home.HomePage']
    subpage_types = [
        'general.General', 'datasection.DataSetListing',
        'spotlight.SpotlightPage', 'publications.ShortPublicationPage'
    ]

    class Meta:
        verbose_name = "Data Section Page"

    @cached_property
    def get_dataset_listing_page(self):
        return self.get_children().type(DataSetListing)[0]

    def count_quotes(self):
        quote_counter = 0
        for quote in self.quotes:
            quote_counter = quote_counter + 1
        return quote_counter

    def get_random_quote(self):
        number_of_quotes = self.count_quotes()
        if number_of_quotes == 1:
            for quote in self.quotes:
                return quote
        elif number_of_quotes >= 2:
            random_number = random.randint(0, number_of_quotes - 1)
            for index, quote in enumerate(self.quotes):
                if random_number == index:
                    return quote
        return

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['random_quote'] = self.get_random_quote()
        context['dataset_count'] = DatasetPage.objects.live().count()
        return context
Esempio n. 23
0
class ServicesPage(TypesetBodyMixin, HeroMixin, Page):
    """
    http://development-initiatives.surge.sh/page-templates/09-consultancy-services
    """
    def get_context(self, request):
        context = super(ServicesPage, self).get_context(request)
        topic_filter = request.GET.get('topic', None)
        if topic_filter:
            examples = ServicesPageRelatedExample.objects.filter(
                topics__slug=topic_filter)
        else:
            examples = ServicesPageRelatedExample.objects.all()

        context['topics'] = ExampleTopic.objects.all()
        context['selected_topic'] = topic_filter
        context['examples'] = examples
        context['related_news'] = get_related_pages(
            self,
            self.services_related_news.all(),
            NewsStoryPage.objects,
            min_len=0)

        return context

    contact_text = models.CharField(
        blank=True,
        null=True,
        max_length=250,
        default=
        'Find out more about our consultancy services and what we can do for you'
    )
    contact_button_text = models.CharField(blank=True,
                                           null=True,
                                           max_length=100,
                                           default='Get in touch')
    contact_email = models.EmailField(blank=True, null=True)

    specialities = StreamField([
        ('speciality',
         StructBlock([('image', ImageChooserBlock(required=False)),
                      ('heading', CharBlock(required=False)),
                      ('body',
                       RichTextBlock(required=False,
                                     features=RICHTEXT_FEATURES_NO_FOOTNOTES))
                      ]))
    ])

    skills = StreamField([
        ('skill',
         StructBlock([('heading', CharBlock(required=False)),
                      ('body',
                       RichTextBlock(required=False,
                                     features=RICHTEXT_FEATURES_NO_FOOTNOTES))
                      ]))
    ])

    richtext_columns = StreamField(
        [('column',
          StructBlock([('heading', TextBlock(required=False, icon='title')),
                       ('content',
                        RichTextBlock(features=RICHTEXT_FEATURES_NO_FOOTNOTES,
                                      icon='fa-paragraph'))],
                      template='blocks/richtext_column.html'))],
        null=True,
        blank=True)

    sections = StreamField(SectionStreamBlock(),
                           verbose_name="Sections",
                           null=True,
                           blank=True)

    class Meta:
        verbose_name = 'Services Page'

    content_panels = Page.content_panels + [
        hero_panels(),
        MultiFieldPanel([
            FieldPanel('contact_text'),
            FieldPanel('contact_button_text'),
            FieldPanel('contact_email')
        ],
                        heading='Contact aside'),
        StreamFieldPanel('body'),
        StreamFieldPanel('specialities'),
        StreamFieldPanel('skills'),
        InlinePanel('services_related_news', label="Related news"),
        InlinePanel('services_related_example', label="Project examples"),
        StreamFieldPanel('richtext_columns'),
        StreamFieldPanel('sections'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = ['general.General']
    parent_page_types = [WhatWeDoPage]
Esempio n. 24
0
class BlogArticlePage(TypesetBodyFootnoteMixin, HeroMixin, CallToActionMixin, Page):
    topics = ClusterTaggableManager(through=BlogTopic, blank=True)

    internal_author_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text="The author's page if the author has an internal profile. Photograph, job title, and page link will be drawn from this.",
        verbose_name='Internal Author'
    )
    other_authors = StreamField(
        [
            ('internal_author', PageChooserBlock(
                required=False, target_model='ourteam.TeamMemberPage', icon='user', label='Internal Author')),
            ('external_author', StructBlock([
                ('name', CharBlock(required=False)),
                ('title', CharBlock(required=False)),
                ('photograph', ImageChooserBlock(required=False)),
                ('page', URLBlock(required=False))
            ], icon='user', label='External Author'))
        ],
        blank=True,
        help_text="Additional authors. If order is important, please use this instead of internal author page.",
        verbose_name='Other Authors')

    published_date = models.DateTimeField(
        blank=True,
        default=now,
        help_text='This date will be used for display and ordering',
    )

    content_panels = Page.content_panels + [
        hero_panels(),
        MultiFieldPanel([
            PageChooserPanel('internal_author_page', TeamMemberPage),
            StreamFieldPanel('other_authors')
        ], heading="Author information"),
        call_to_action_panel(),
        FieldPanel('topics'),
        StreamFieldPanel('body'),
        FieldPanel('published_date'),
        InlinePanel('blog_related_links', label='Related links', max_num=MAX_RELATED_LINKS),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = ['general.General']
    parent_page_types = [
        'BlogIndexPage'
    ]

    class Meta():
        verbose_name = 'Blog Article Page'

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['related_pages'] = get_related_pages(
            self, self.blog_related_links.all(), BlogArticlePage.objects)

        return context
Esempio n. 25
0
class ShortPublicationPage(HeroMixin, PublishedDateMixin, FlexibleContentMixin,
                           ParentPageSearchMixin, UUIDMixin,
                           FilteredDatasetMixin, CallToActionMixin,
                           ReportDownloadMixin, Page):
    class Meta:
        verbose_name = 'Short Publication'

    parent_page_types = ['PublicationIndexPage', 'datasection.DataSectionPage']
    subpage_types = []

    colour = models.CharField(max_length=256,
                              choices=COLOUR_CHOICES,
                              default=RED)
    authors = StreamField(
        [('internal_author',
          PageChooserBlock(required=False,
                           target_model='ourteam.TeamMemberPage',
                           icon='fa-user',
                           label='Internal Author')),
         ('external_author',
          StructBlock([('name', CharBlock(required=False)),
                       ('title', CharBlock(required=False)),
                       ('photograph', ImageChooserBlock(required=False)),
                       ('page', URLBlock(required=False))],
                      icon='fa-user',
                      label='External Author'))],
        blank=True)
    publication_type = models.ForeignKey(PublicationType,
                                         related_name="+",
                                         null=True,
                                         blank=False,
                                         on_delete=models.SET_NULL,
                                         verbose_name="Resource Type")
    topics = ClusterTaggableManager(through=ShortPublicationTopic,
                                    blank=True,
                                    verbose_name="Topics")

    content_panels = Page.content_panels + [
        FieldPanel('colour'),
        hero_panels(),
        StreamFieldPanel('authors'),
        call_to_action_panel(),
        SnippetChooserPanel('publication_type'),
        FieldPanel('topics'),
        InlinePanel('page_countries', label="Countries"),
        PublishedDatePanel(),
        ContentPanel(),
        InlinePanel('publication_datasets', label='Datasets'),
        DownloadsPanel(heading='Downloads',
                       description='Downloads for this chapter.'),
        DownloadsPanel(
            related_name='data_downloads',
            heading='Data downloads',
            description='Optional: data download for this chapter.'),
        ReportDownloadPanel(),
        InlinePanel('page_notifications', label='Notifications'),
        InlinePanel('publication_related_links',
                    label='Related links',
                    max_num=MAX_RELATED_LINKS),
    ]

    @cached_property
    def publication_downloads_title(self):
        return 'Downloads'

    @cached_property
    def publication_downloads_list(self):
        return get_downloads(self)

    @cached_property
    def data_downloads_title(self):
        return 'Data downloads'

    @cached_property
    def data_downloads_list(self):
        return get_downloads(self, with_parent=False, data=True)

    @cached_property
    def page_publication_downloads(self):
        return self.publication_downloads.all()

    @cached_property
    def page_data_downloads(self):
        return self.data_downloads.all()

    @cached_property
    def chapter_number(self):
        return 1

    @cached_property
    def chapters(self):
        return [self]

    @cached_property
    def listing_and_appendicies(self):
        return [self]

    @cached_property
    def chapter_word(self):
        return num2words(self.chapter_number)

    @cached_property
    def label_type(self):
        return 'publication'

    @cached_property
    def label(self):
        return 'publication'

    @cached_property
    def label_num(self):
        return 'publication'

    @cached_property
    def sections(self):
        sections = []
        for block in self.content:
            if block.block_type == 'section_heading':
                sections.append(block)
        return sections

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)

        context['related_pages'] = get_related_pages(
            self, self.publication_related_links.all(),
            ShortPublicationPage.objects)

        return context
Esempio n. 26
0
class DatasetPage(DataSetMixin, TypesetBodyMixin, HeroMixin, Page):
    """ Content of each dataset """
    class Meta():
        verbose_name = 'Data Set Page'

    dataset_id = models.CharField(max_length=255,
                                  unique=True,
                                  blank=True,
                                  null=True)
    dataset_title = models.TextField(unique=True, blank=True, null=True)
    related_datasets_title = models.CharField(blank=True,
                                              max_length=255,
                                              default='Related datasets',
                                              verbose_name='Section Title')

    content_panels = Page.content_panels + [
        hero_panels(),
        FieldPanel('dataset_id'),
        FieldPanel('dataset_title'),
        FieldPanel('release_date'),
        StreamFieldPanel('body'),
        StreamFieldPanel('authors'),
        InlinePanel('dataset_downloads', label='Downloads', max_num=None),
        metadata_panel(),
        MultiFieldPanel([
            FieldPanel('related_datasets_title'),
            InlinePanel('related_datasets', label="Related Datasets")
        ],
                        heading='Related Datasets'),
        other_pages_panel(),
        InlinePanel('page_notifications', label='Notifications')
    ]

    def get_context(self, request):
        context = super().get_context(request)

        context['topics'] = [
            orderable.topic for orderable in self.dataset_topics.all()
        ]
        context['related_datasets'] = get_related_dataset_pages(
            self.related_datasets.all(), self)
        context['reports'] = self.get_usages()

        return context

    @cached_property
    def get_dataset_downloads(self):
        return self.dataset_downloads.all()

    @cached_property
    def get_dataset_sources(self):
        return self.dataset_sources.all()

    def get_usages(self):
        reports = Page.objects.live().filter(
            models.Q(
                publicationpage__publication_datasets__dataset__slug=self.slug)
            | models.Q(
                legacypublicationpage__publication_datasets__dataset__slug=self
                .slug) | models.
            Q(publicationsummarypage__publication_datasets__dataset__slug=self.
              slug) | models.
            Q(publicationchapterpage__publication_datasets__dataset__slug=self.
              slug) | models.
            Q(publicationappendixpage__publication_datasets__dataset__slug=self
              .slug)
            | models.Q(
                shortpublicationpage__publication_datasets__dataset__slug=self.
                slug)).specific()

        return reports

    def get_download_name(self):
        return self.title
Esempio n. 27
0
class WorkForUsPage(TypesetBodyMixin, HeroMixin, Page):
    class Meta():
        verbose_name = 'Work For Us Page'

    benefits = StreamField(BenefitsStreamBlock,
                           verbose_name="Benefits",
                           null=True,
                           blank=True)
    value_section_heading = models.CharField(blank=True,
                                             max_length=255,
                                             verbose_name='Value Heading',
                                             default='Our values')
    value_section_sub_heading = RichTextField(
        blank=True,
        verbose_name='Value Sub-heading',
        help_text='A brief description of the section contents',
        features=RICHTEXT_FEATURES_NO_FOOTNOTES)
    values = StreamField([
        ('value', ValueBlock()),
    ], null=True, blank=True)
    team_story_section_heading = models.CharField(
        blank=True,
        max_length=255,
        verbose_name='Section Heading',
        default='Team stories')
    team_story_section_sub_heading = RichTextField(
        blank=True,
        verbose_name='Section Sub-heading',
        help_text='A brief description of the section contents',
        features=RICHTEXT_FEATURES_NO_FOOTNOTES)
    team_stories = StreamField(TeamStoryStreamBlock,
                               verbose_name="Team Stories",
                               null=True,
                               blank=True)
    vacancy_section_heading = models.TextField(blank=True,
                                               max_length=255,
                                               verbose_name='Section Heading',
                                               default='Latest vacancies')
    vacancy_section_sub_heading = RichTextField(
        blank=True,
        verbose_name='Section Sub-heading',
        help_text='A brief description of the section contents',
        features=RICHTEXT_FEATURES_NO_FOOTNOTES)
    content_panels = Page.content_panels + [
        hero_panels(),
        StreamFieldPanel('body'),
        StreamFieldPanel('benefits'),
        MultiFieldPanel([
            FieldPanel('value_section_heading'),
            FieldPanel('value_section_sub_heading'),
            StreamFieldPanel('values')
        ],
                        heading='Values Section'),
        MultiFieldPanel([
            FieldPanel('team_story_section_heading'),
            FieldPanel('team_story_section_sub_heading'),
            StreamFieldPanel('team_stories')
        ],
                        heading='Team Stories Section'),
        MultiFieldPanel([
            FieldPanel('vacancy_section_heading'),
            FieldPanel('vacancy_section_sub_heading')
        ],
                        heading='Vacancies Section'),
        InlinePanel('page_notifications', label='Notifications')
    ]

    subpage_types = ['vacancies.VacancyIndexPage', 'general.General']

    def get_context(self, request):
        context = super().get_context(request)
        context['vacancies'] = VacancyPage.objects.live()

        return context