示例#1
0
文件: models.py 项目: janun/janunde
class JobOfferPage(StandardPage):
    parent_page_types = ["JobOfferIndexPage"]
    subpage_types = ["core.StandardPage"]

    valid_through = models.DateTimeField(
        "Bewerbungsfrist",
        blank=True,
        null=True,
        validators=[
            MinValueValidator(timezone.now, message="Sollte in der Zukunft liegen")
        ],
    )
    job_title = models.CharField("Job-Titel", max_length=255)
    job_location = models.CharField(
        "Job-Ort", max_length=255, blank=True, default="Hannover"
    )
    hiring_organization_name = models.CharField(
        "Arbeitgeber", max_length=255, default="JANUN e.V."
    )
    hiring_organization_url = models.URLField(
        "Website des Arbeitgebers", blank=True, default="https://www.janun.de/"
    )
    EMPLOYMENT_TYPE_CHOICES = [
        ("FULL_TIME", "Vollzeit"),
        ("PART_TIME", "Teilzeit"),
        ("CONTRACTOR", "Auftragnehmer"),
        ("TEMPORARY", "befristet"),
        ("INTERN", "Praktikum"),
        ("VOLUNTEER", "Freiwilligendienst"),
        ("PER_DIEM", "tageweise"),
        ("OTHER", "anderes"),
    ]
    employment_type = ChoiceArrayField(
        models.CharField(max_length=20, choices=EMPLOYMENT_TYPE_CHOICES),
        verbose_name="Art der Anstellung",
        blank=True,
        null=True,
    )
    base_salary_amount = models.DecimalField(
        "Grundgehalt", blank=True, null=True, decimal_places=2, max_digits=10
    )
    BASE_SALARY_UNIT_CHOICES = [
        ("HOUR", "pro Stunde"),
        ("DAY", "pro Tag"),
        ("WEEK", "pro Woche"),
        ("MONTH", "pro Monat"),
        ("YEAR", "pro Jahr"),
    ]
    base_salary_unit = models.CharField(
        "Zeitraum für Grundgehalt",
        max_length=10,
        default="MONTH",
        choices=BASE_SALARY_UNIT_CHOICES,
    )
    auto_unpublish = models.BooleanField(
        "Automatisch depublizieren",
        help_text="Depubliziert die Seite automatisch nach der Bewerbungsfrist",
        default=True,
    )

    def get_employment_type_display(self) -> [str]:
        result = []
        for employment_type in self.employment_type:
            for choice in self.EMPLOYMENT_TYPE_CHOICES:
                if employment_type == choice[0]:
                    result.append(choice[1])
        return result

    @property
    def structured_data(self):
        return {
            "@type": "JobPosting",
            "title": self.job_title,
            "description": str(self.body),
            "datePosted": self.first_published_at,
            "validThrough": self.valid_through,
            "hiringOrganization": {
                "@type": "Organization",
                "name": self.hiring_organization_name,
                "sameAs": self.hiring_organization_url,
            },
            "jobLocation": {"@type": "Place", "address": self.job_location},
            "employmentType": self.employment_type,
            "baseSalary": {
                "@type": "MonetaryAmount",
                "currency": "EUR",
                "value": {
                    "@type": "QuantitativeValue",
                    "value": self.base_salary_amount,
                    "unitText": self.base_salary_unit,
                },
            },
        }

    def save(self, *args, **kwargs):
        if self.valid_through and self.auto_unpublish:
            self.expire_at = self.valid_through
        super().save(*args, **kwargs)

    content_panels = [
        FieldPanel("title"),
        FieldPanel("subtitle"),
        ImageChooserPanel("feed_image"),
        MultiFieldPanel(
            [
                HelpPanel(
                    "<p>Sorgt für eine bessere Platzierung als Jobanzeige bei Google und co.</p>"
                ),
                FieldPanel("job_title"),
                FieldPanel("job_location"),
                FieldPanel("hiring_organization_name"),
                FieldPanel("hiring_organization_url"),
                FieldPanel("valid_through"),
                FieldPanel("auto_unpublish"),
                FieldPanel("employment_type", widget=forms.CheckboxSelectMultiple),
                FieldPanel("base_salary_amount"),
                FieldPanel("base_salary_unit"),
            ],
            heading="Infos",
        ),
        StreamFieldPanel("body"),
    ]

    class Meta:
        verbose_name = "Stellenausschreibung"
        verbose_name_plural = "Stellenausschreibungen"
示例#2
0
class JobListingPage(CFGOVPage):
    description = RichTextField('Summary')
    open_date = models.DateField('Open date')
    close_date = models.DateField('Close date')
    salary_min = models.DecimalField(
        'Minimum salary',
        max_digits=11,
        decimal_places=2
    )
    salary_max = models.DecimalField(
        'Maximum salary',
        max_digits=11,
        decimal_places=2
    )
    division = models.ForeignKey(
        JobCategory,
        on_delete=models.PROTECT,
        null=True
    )
    job_length = models.ForeignKey(
        JobLength,
        on_delete=models.PROTECT,
        null=True,
        verbose_name="Position length",
        blank=True
    )
    service_type = models.ForeignKey(
        ServiceType,
        on_delete=models.PROTECT,
        null=True,
        blank=True
    )
    offices = ParentalManyToManyField(
        Office,
        related_name='job_listings',
        blank=True
    )
    allow_remote = models.BooleanField(
        default=False,
        verbose_name="Office location can also be remote"
    )
    regions = ParentalManyToManyField(
        Region,
        related_name='job_listings',
        blank=True
    )
    responsibilities = RichTextField(
        'Responsibilities',
        null=True,
        blank=True
    )
    travel_required = models.BooleanField(
        blank=False,
        default=False,
        help_text=(
            'Optional: Check to add a "Travel required" section to the '
            'job description. Section content defaults to "Yes".'
        )
    )
    travel_details = RichTextField(
        null=True,
        blank=True,
        help_text='Optional: Add content for "Travel required" section.'
    )
    additional_section_title = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text='Optional: Add title for an additional section '
                  'that will display at end of job description.'
    )
    additional_section_content = RichTextField(
        null=True,
        blank=True,
        help_text='Optional: Add content for an additional section '
                  'that will display at end of job description.'
    )

    content_panels = CFGOVPage.content_panels + [
        MultiFieldPanel([
            FieldPanel('division'),
            InlinePanel('grades', label='Grades'),
            FieldRowPanel([
                FieldPanel('open_date', classname='col6'),
                FieldPanel('close_date', classname='col6'),
            ]),
            FieldRowPanel([
                FieldPanel('salary_min', classname='col6'),
                FieldPanel('salary_max', classname='col6'),
            ]),
            FieldRowPanel([
                FieldPanel('service_type', classname='col6'),
                FieldPanel('job_length', classname='col6'),
            ]),
        ], heading='Details'),
        MultiFieldPanel([
            HelpPanel(LOCATION_HELP_TEXT),
            FieldRowPanel([
                FieldPanel('offices', widget=forms.CheckboxSelectMultiple),
                FieldPanel('allow_remote'),
            ]),
            FieldPanel('regions', widget=forms.CheckboxSelectMultiple),
        ], heading='Location'),
        MultiFieldPanel([
            FieldPanel('description'),
            FieldPanel('responsibilities'),
            FieldPanel('travel_required'),
            FieldPanel('travel_details'),
            FieldPanel('additional_section_title'),
            FieldPanel('additional_section_content'),
        ], heading='Description'),
        InlinePanel(
            'usajobs_application_links',
            label='USAJobs application links'
        ),
        InlinePanel(
            'email_application_links',
            label='Email application links'
        ),
    ]

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

    base_form_class = JobListingPageForm

    objects = JobListingPageManager()

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

        try:
            context['about_us'] = ReusableText.objects.get(
                title='About us (For consumers)'
            )
        except ReusableText.DoesNotExist:
            pass

        context.update({
            'offices': [
                {
                    'name': office.name,
                    'state_id': office.state_id,
                } for office in self.offices.all()
            ],
            'regions': [
                {
                    'name': region.name,
                    'states': [
                        state.abbreviation for state in region.states.all()
                    ],
                    'major_cities': list(
                        region.major_cities.values('name', 'state_id')
                    ),
                } for region in self.regions.all()
            ],
            'grades': list(map(str, self.grades.all())),
        })

        return context

    @property
    def page_js(self):
        return super(JobListingPage, self).page_js + ['read-more.js']
示例#3
0
文件: models.py 项目: janun/janunde
class WimmelbildPage(BasePage):
    base_form_class = WimmelbildPageForm

    subtitle = models.CharField("Untertitel", max_length=255, blank=True)

    feed_image = models.ForeignKey(
        Image,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="+",
        verbose_name="Hauptbild",
        help_text="Wird in Übersichten verwendet.",
    )

    before = StreamField(
        StandardStreamBlock(required=False),
        blank=True,
        null=True,
        verbose_name="Vor dem Wimmelbild",
    )
    after = StreamField(
        StandardStreamBlock(required=False),
        blank=True,
        null=True,
        verbose_name="Nach dem Wimmelbild",
    )

    tile_url = models.URLField(
        "Kachel-URL",
        help_text=
        "URL zu den Kacheln, aus denen das Bild besteht. Benutze {z}, {x}, {y} in der URL für die Koordinaten",
        blank=True,
    )
    width = models.IntegerField("Breite",
                                help_text="Breite des Wimmelbilds in Pixeln",
                                blank=True,
                                null=True)
    height = models.IntegerField("Höhe",
                                 help_text="Höhe des Wimmelbilds in Pixeln",
                                 blank=True,
                                 null=True)

    search_fields = BasePage.search_fields + [
        index.SearchField("subtitle"),
        index.SearchField("before"),
        index.SearchField("after"),
    ]

    content_panels = [
        FieldPanel("title"),
        FieldPanel("subtitle"),
        ImageChooserPanel("feed_image"),
        StreamFieldPanel("before"),
        HelpPanel("Hier kommt das Wimmelbild"),
        StreamFieldPanel("after"),
    ]

    wimmelbild_panels = [
        MultiFieldPanel(
            [
                HelpPanel(
                    "Das Wimmelbild muss in Kacheln aufgeteilt werden (z.B. mit gdal2tiles) und diese dann Hochgeladen werden."
                ),
                FieldPanel("tile_url"),
                FieldPanel("width"),
                FieldPanel("height"),
            ],
            heading="Allgemeines",
        ),
        # HelpPanel(template="wimmelbilder/map_edit.html", heading="Übersicht über Info-Punkte"), # TODO
        InlinePanel("groups", heading="Gruppen von Info-Punkten"),
        InlinePanel("points", heading="Info-Punkte"),
    ]

    edit_handler = TabbedInterface([
        ObjectList(content_panels, heading="Text-Inhalt"),
        ObjectList(wimmelbild_panels, heading="Wimmelbild"),
        ObjectList(BasePage.promote_panels, heading="Veröffentlichung"),
        ObjectList(BasePage.settings_panels,
                   heading="Einstellungen",
                   classname="settings"),
    ])

    @property
    def json_dict(self):
        groups = [g.json_dict for g in self.groups.all()]
        jd = {
            "tileUrl": self.tile_url,
            "width": self.width,
            "height": self.height,
            "groups": groups,
        }
        return jd

    def clean(self):
        super().clean()
        if self.tile_url:
            if not self.width:
                raise ValidationError(
                    {"width": "Erforderlich, wenn Kacheln angegeben"})
            if not self.height:
                raise ValidationError(
                    {"height": "Erforderlich, wenn Kacheln angegeben"})

    class Meta:
        verbose_name = "Wimmelbild-Seite"
        verbose_name_plural = "Wimmelbild-Seiten"
class InternationalInvestmentSectorPagePanels:
    content_panels = [
        FieldPanel('title'),
        MultiFieldPanel(heading='Heading',
                        classname='collapsible',
                        children=[
                            FieldPanel('heading'),
                            ImageChooserPanel('hero_image'),
                            MediaChooserPanel('hero_video'),
                            FieldPanel('standfirst'),
                            FieldPanel('featured_description')
                        ]),
        MultiFieldPanel(heading='Intro',
                        classname='collapsible',
                        children=[
                            FieldPanel('intro_text'),
                            ImageChooserPanel('intro_image'),
                        ]),
        MultiFieldPanel(heading='Contact details',
                        classname='collapsible',
                        children=[
                            FieldPanel('contact_name'),
                            ImageChooserPanel('contact_avatar'),
                            FieldPanel('contact_job_title'),
                            FieldPanel('contact_link'),
                            FieldPanel('contact_link_button_preamble'),
                            FieldPanel('contact_link_button_label'),
                        ]),
        MultiFieldPanel(
            heading='Related opportunities',
            classname='collapsible',
            children=[
                FieldPanel('related_opportunities_header'),
                HelpPanel(
                    'See the dedicated tab for selecting the opportunities themselves'
                ),
            ]),
        StreamFieldPanel('downpage_content'),
        MultiFieldPanel(heading='Early opportunities',
                        classname='collapsible',
                        children=[
                            FieldPanel('early_opportunities_header'),
                            StreamFieldPanel('early_opportunities'),
                        ]),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('slug'),
        FieldPanel('tags'),
    ]

    related_entities_panels = [
        FieldRowPanel(
            heading='Related Opportunities',
            children=[
                StreamFieldPanel('manually_selected_related_opportunities'),
            ]),
    ]

    edit_handler = make_translated_interface(
        content_panels=content_panels,
        other_panels=related_entities_panels,  # These are shown as separate tabs
        settings_panels=settings_panels)
示例#5
0
class InternationalSectorPage(BasePage):
    service_name_value = cms.GREAT_INTERNATIONAL
    parent_page_types = ['great_international.InternationalTopicLandingPage']
    subpage_types = []

    tags = ParentalManyToManyField(Tag, blank=True)

    heading = models.CharField(max_length=255)
    sub_heading = models.CharField(max_length=255)
    hero_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    heading_teaser = models.TextField(blank=True)

    section_one_body = MarkdownField(
        null=True,
        verbose_name='Bullets markdown'
    )
    section_one_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Bullets image'
    )
    section_one_image_caption = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Bullets image caption')
    section_one_image_caption_company = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Bullets image caption — company name')

    statistic_1_number = models.CharField(max_length=255)
    statistic_1_heading = models.CharField(max_length=255)
    statistic_1_smallprint = models.CharField(max_length=255, blank=True)

    statistic_2_number = models.CharField(max_length=255)
    statistic_2_heading = models.CharField(max_length=255)
    statistic_2_smallprint = models.CharField(max_length=255, blank=True)

    statistic_3_number = models.CharField(max_length=255, blank=True)
    statistic_3_heading = models.CharField(max_length=255, blank=True)
    statistic_3_smallprint = models.CharField(max_length=255, blank=True)

    statistic_4_number = models.CharField(max_length=255, blank=True)
    statistic_4_heading = models.CharField(max_length=255, blank=True)
    statistic_4_smallprint = models.CharField(max_length=255, blank=True)

    statistic_5_number = models.CharField(max_length=255, blank=True)
    statistic_5_heading = models.CharField(max_length=255, blank=True)
    statistic_5_smallprint = models.CharField(max_length=255, blank=True)

    statistic_6_number = models.CharField(max_length=255, blank=True)
    statistic_6_heading = models.CharField(max_length=255, blank=True)
    statistic_6_smallprint = models.CharField(max_length=255, blank=True)

    section_two_heading = models.CharField(
        max_length=255,
        verbose_name='Highlights heading'
    )
    section_two_teaser = models.TextField(
        verbose_name='Highlights teaser'
    )

    section_two_subsection_one_icon = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Highlight 1 icon'
    )
    section_two_subsection_one_heading = models.CharField(
        max_length=255,
        verbose_name='Highlight 1 heading'
    )
    section_two_subsection_one_body = models.TextField(
        verbose_name='Highlight 1 body'
    )

    section_two_subsection_two_icon = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Highlight 2 icon'
    )
    section_two_subsection_two_heading = models.CharField(
        max_length=255,
        verbose_name='Highlight 2 heading'
    )
    section_two_subsection_two_body = models.TextField(
        verbose_name='Highlight 2 body'
    )

    section_two_subsection_three_icon = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Highlight 3 icon'
    )
    section_two_subsection_three_heading = models.CharField(
        max_length=255,
        verbose_name='Highlight 3 heading'
    )
    section_two_subsection_three_body = models.TextField(
        verbose_name='Highlight 3 body'
    )

    case_study_title = models.CharField(max_length=255, blank=True)
    case_study_description = models.CharField(max_length=255, blank=True)
    case_study_cta_text = models.TextField(blank=True)
    case_study_cta_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    case_study_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    section_three_heading = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Fact sheets heading'
    )
    section_three_teaser = models.TextField(
        blank=True,
        verbose_name='Fact sheets teaser'
    )

    section_three_subsection_one_heading = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Fact sheet 1 heading'
    )
    section_three_subsection_one_teaser = models.TextField(
        blank=True,
        verbose_name='Fact sheet 1 teaser'
    )
    section_three_subsection_one_body = MarkdownField(
        blank=True,
        null=True,
        verbose_name='Fact sheet 1 body'
    )

    section_three_subsection_two_heading = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Fact sheet 2 heading'
    )
    section_three_subsection_two_teaser = models.TextField(
        blank=True,
        verbose_name='Fact sheet 2 teaser'
    )
    section_three_subsection_two_body = MarkdownField(
        blank=True,
        null=True,
        verbose_name='Fact sheet 2 body'
    )

    related_page_one = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    related_page_two = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    related_page_three = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    content_panels = [
        MultiFieldPanel(
            heading='Heading',
            children=[
                FieldPanel('heading'),
                FieldPanel('sub_heading'),
                ImageChooserPanel('hero_image'),
                FieldPanel('heading_teaser')
            ]

        ),
        MultiFieldPanel(
            heading='Bullets',
            children=[
                HelpPanel(
                    'For accessibility reasons, use only "## [Your text here]"'
                    ' for headings in this markdown field'),
                FieldRowPanel(
                    [
                        FieldPanel('section_one_body'),
                        MultiFieldPanel(
                            [
                                ImageChooserPanel('section_one_image'),
                                FieldPanel('section_one_image_caption'),
                                FieldPanel('section_one_image_caption_company')
                            ]
                        )
                    ]
                )
            ]
        ),
        MultiFieldPanel(
            heading='Statistics',
            children=[
                FieldRowPanel(
                    [
                        MultiFieldPanel(
                            [
                                FieldPanel('statistic_1_number'),
                                FieldPanel('statistic_1_heading'),
                                FieldPanel('statistic_1_smallprint')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                FieldPanel('statistic_2_number'),
                                FieldPanel('statistic_2_heading'),
                                FieldPanel('statistic_2_smallprint')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                FieldPanel('statistic_3_number'),
                                FieldPanel('statistic_3_heading'),
                                FieldPanel('statistic_3_smallprint')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                FieldPanel('statistic_4_number'),
                                FieldPanel('statistic_4_heading'),
                                FieldPanel('statistic_4_smallprint')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                FieldPanel('statistic_5_number'),
                                FieldPanel('statistic_5_heading'),
                                FieldPanel('statistic_5_smallprint')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                FieldPanel('statistic_6_number'),
                                FieldPanel('statistic_6_heading'),
                                FieldPanel('statistic_6_smallprint')
                            ]
                        ),
                    ]
                )
            ]
        ),
        MultiFieldPanel(
            heading='Highlights',
            children=[
                FieldPanel('section_two_heading'),
                FieldPanel('section_two_teaser'),
                FieldRowPanel(
                    [
                        MultiFieldPanel(
                            [
                                ImageChooserPanel(
                                    'section_two_subsection_one_icon'),
                                FieldPanel(
                                    'section_two_subsection_one_heading'),
                                FieldPanel(
                                    'section_two_subsection_one_body')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                ImageChooserPanel(
                                    'section_two_subsection_two_icon'),
                                FieldPanel(
                                    'section_two_subsection_two_heading'),
                                FieldPanel(
                                    'section_two_subsection_two_body')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                ImageChooserPanel(
                                    'section_two_subsection_three_icon'),
                                FieldPanel(
                                    'section_two_subsection_three_heading'),
                                FieldPanel(
                                    'section_two_subsection_three_body')
                            ]
                        )
                    ]
                )
            ]
        ),
        MultiFieldPanel(
            heading='Case Study',
            classname='collapsible',
            children=[
                FieldPanel('case_study_title'),
                FieldPanel('case_study_description'),
                FieldPanel('case_study_cta_text'),
                PageChooserPanel(
                    'case_study_cta_page',
                    [
                        'great_international.InternationalArticlePage',
                        'great_international.InternationalCampaignPage',
                    ]),
                ImageChooserPanel('case_study_image')
            ]
        ),
        MultiFieldPanel(
            heading='Fact Sheets',
            classname='collapsible collapsed',
            children=[
                FieldPanel('section_three_heading'),
                FieldPanel('section_three_teaser'),
                FieldRowPanel(
                    [
                        MultiFieldPanel(
                            [
                                FieldPanel(
                                    'section_three_subsection_one_heading'),
                                FieldPanel(
                                    'section_three_subsection_one_teaser'),
                                HelpPanel(
                                    'For accessibility reasons, use only '
                                    '"#### [Your text here]" for subheadings '
                                    'in this markdown field'),
                                FieldPanel(
                                    'section_three_subsection_one_body')
                            ]
                        ),
                        MultiFieldPanel(
                            [
                                FieldPanel(
                                    'section_three_subsection_two_heading'),
                                FieldPanel(
                                    'section_three_subsection_two_teaser'),
                                HelpPanel(
                                    'For accessibility reasons, use only '
                                    '"#### [Your text here]" for subheadings '
                                    'in this markdown field'),
                                FieldPanel(
                                    'section_three_subsection_two_body')
                            ]
                        )
                    ]
                )
            ]
        ),
        MultiFieldPanel(
            heading='Related articles',
            children=[
                FieldRowPanel([
                    PageChooserPanel(
                        'related_page_one',
                        [
                            'great_international.InternationalArticlePage',
                            'great_international.InternationalCampaignPage',
                        ]),
                    PageChooserPanel(
                        'related_page_two',
                        [
                            'great_international.InternationalArticlePage',
                            'great_international.InternationalCampaignPage',
                        ]),
                    PageChooserPanel(
                        'related_page_three',
                        [
                            'great_international.InternationalArticlePage',
                            'great_international.InternationalCampaignPage',
                        ]),
                ])
            ]
        ),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('title_en_gb'),
        FieldPanel('slug'),
        FieldPanel('tags', widget=CheckboxSelectMultiple)
    ]
示例#6
0
class ServicePage(JanisPage):

    # TODO: FKs
    # department = models.ForeignKey(
    #     'base.DepartmentPage',
    #     on_delete=models.PROTECT,
    #     verbose_name='Select a Department',
    #     blank=True,
    #     null=True,
    # )

    steps = StreamField(
        [
            ('basic_step',
             RichTextBlock(features=WYSIWYG_SERVICE_STEP, label='Basic Step')),
            ('step_with_options_accordian',
             StructBlock([
                 ('options_description',
                  TextBlock('Describe the set of options')),
                 ('options',
                  ListBlock(
                      StructBlock([
                          ('option_name',
                           TextBlock(
                               label=
                               'Option name. (When clicked, this name will expand the content for this option'
                           )),
                          ('option_description',
                           RichTextBlock(
                               features=WYSIWYG_SERVICE_STEP,
                               label='Option Content',
                           )),
                      ]), )),
             ],
                         label="Step With Options")),
        ],
        verbose_name=
        'Write out the steps a resident needs to take to use the service',
        # this gets called in the help panel
        help_text=
        'A step may have a basic text step or an options accordian which reveals two or more options',
        blank=True)

    # TODO: custom blocks
    # dynamic_content = StreamField(
    #     [
    #         ('map_block', custom_blocks.SnippetChooserBlockWithAPIGoodness('base.Map', icon='site')),
    #         ('what_do_i_do_with_block', custom_blocks.WhatDoIDoWithBlock()),
    #         ('collection_schedule_block', custom_blocks.CollectionScheduleBlock()),
    #         ('recollect_block', custom_blocks.RecollectBlock()),
    #     ],
    #     verbose_name='Add any maps or apps that will help the resident use the service',
    #     blank=True
    # )
    additional_content = RichTextField(
        features=WYSIWYG_GENERAL,
        verbose_name='Write any additional content describing the service',
        help_text='Section header: What else do I need to know?',
        blank=True)

    # TODO: custom forms
    base_form_class = custom_forms.ServicePageForm

    short_description = models.TextField(
        max_length=SHORT_DESCRIPTION_LENGTH,
        blank=True,
        verbose_name='Write a description of this service')

    content_panels = [
        FieldPanel('title'),
        FieldPanel('short_description'),
        # TODO: FKs
        # InlinePanel('topics', label='Topics'),
        # FieldPanel('department'),
        MultiFieldPanel([
            HelpPanel(steps.help_text, classname="coa-helpPanel"),
            StreamFieldPanel('steps')
        ],
                        heading=steps.verbose_name,
                        classname='coa-multiField-nopadding'),
        # TODO: custom blocks
        # StreamFieldPanel('dynamic_content'),
        MultiFieldPanel([
            HelpPanel(additional_content.help_text, classname="coa-helpPanel"),
            FieldPanel('additional_content')
        ],
                        heading=additional_content.verbose_name,
                        classname='coa-multiField-nopadding'),
        # TODO: FKs
        # InlinePanel('contacts', label='Contacts'),
    ]
示例#7
0
    def __iter__(self):
        # build submenu panels, including the FluidIterable for the widget
        submenu_panels = [
            HelpPanel(_("Select the menu that this sub-menu will load")),
            SubMenuFieldPanel("submenu_id",
                              MenuListQuerySet()()),
            FieldPanel("display_option"),
            FieldPanel("show_when"),
            FieldPanel("menu_display_order"),
            FieldPanel("show_divider_after_this_item"),
        ]

        # two custom panels here:
        # ReadOnlyPanel - displays field as a non-field text, optionally adds a hidden input field to
        #                 allow accessing that field in the clean() method
        # RichHelpPanel - like a django template, swap out {{vars}} for values (field or function returns)
        #                 also allows basic html (formatting, links etc)

        msg = _(
            'Items in the menu will be arranged by <b>Menu Display Order</b> over the order in which they appear below.'
        )
        style = "margin-top: -1.5em; margin-bottom: -1.5em;"
        panels = [
            MultiFieldPanel(
                [
                    ReadOnlyPanel(
                        "id", heading="Menu ID", add_hidden_input=True),
                    FieldPanel("title"),
                    ImageChooserPanel("icon"),
                ],
                heading=_("Menu Heading"),
            ),
            MultiFieldPanel(
                [
                    RichHelpPanel(
                        msg,
                        style=style,
                    ),
                ],
                heading=_(
                    "Menu Items - Add items to show in the menu below. "),
            ),
            MultiFieldPanel(
                [
                    InlinePanel("sub_menu_items",
                                label=_("Sub-menu"),
                                panels=submenu_panels)
                ],
                heading="Submenus",
                classname="collapsible collapsed",
            ),
            MultiFieldPanel(
                [
                    InlinePanel("link_menu_items", label=_("Link")),
                ],
                heading="Links",
                classname="collapsible collapsed",
            ),
            MultiFieldPanel(
                [
                    InlinePanel("autofill_menu_items",
                                label=_("Autofill Link")),
                ],
                heading="Autofill Links",
                classname="collapsible collapsed",
            ),
        ]
        return panels.__iter__()
示例#8
0
class BlogPost(Page):
    """Model for blog posts"""

    # Main blog post content and information.
    intro = models.CharField(max_length=150, blank=True, null=True)
    date = models.DateTimeField("Post date")
    text = RichTextField(blank=True)
    tags = ClusterTaggableManager(through=BlogPostTag,
                                  related_name='blog_post_tag',
                                  blank=True)

    # Show or hide the gallery.
    show = models.BooleanField(null=True)

    # HTML meta tags for the specific blog post.
    description = models.CharField(max_length=160, blank=True, null=True)
    keywords = ClusterTaggableManager(through=BlogPostKeyword,
                                      related_name='blog_post_keyword',
                                      blank=True)

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

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            HelpPanel(template='help_panel/content_help.html'),
            FieldPanel('intro'),
            FieldPanel('date'),
            FieldPanel('tags'),
            FieldPanel('text'),
        ],
                        heading="Content"),
        MultiFieldPanel([
            HelpPanel(template='help_panel/gallery_help.html'),
            FieldPanel('show', widget=forms.CheckboxInput),
            InlinePanel('gallery_images', label="Gallery images"),
        ],
                        heading="Gallery"),
        MultiFieldPanel([
            HelpPanel(template='help_panel/metatag_help.html'),
            FieldPanel('keywords', classname="full"),
            FieldPanel('description', classname="full"),
        ],
                        heading="HTML meta tags"),
    ]

    def intro_text(self):
        """Return intro text for the tiles"""
        if self.intro:
            return self.intro + "..."
        else:
            # If no intro, remove HTML and return the 150 first character
            # of the posts text as intro instead.
            return re.sub("<[^>]*>", "", self.text[:300])[:150] + "..."

    def featured_image(self):
        """Give posts a feature image."""
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None

    def next_post(self):
        """Return the next blog post."""
        posts = self.get_siblings().live().filter(
            blogpost__date__lte=timezone.now()).order_by('-blogpost__date')
        next = None
        for post in posts:
            if post.title == self.title:
                return next
            next = post
        return None

    def previous_post(self):
        """Return the previous blog post."""
        posts = self.get_siblings().live().filter(
            blogpost__date__lte=timezone.now()).order_by('blogpost__date')
        previous = None
        for post in posts:
            if post.title == self.title:
                return previous
            previous = post
        return None
class AboutUkRegionPagePanels:

    content_panels = [
        FieldPanel('title'),
        FieldPanel('breadcrumbs_label'),
        MultiFieldPanel(
            heading="Hero",
            children=[
                FieldPanel('hero_title'),
                ImageChooserPanel('hero_image'),
            ],
        ),
        FieldPanel('featured_description'),
        MultiFieldPanel(
            heading="Region summary",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Region Summary Section Content'),
                ImageChooserPanel('region_summary_section_image'),
                FieldPanel('region_summary_section_strapline'),
                FieldPanel('region_summary_section_intro'),
                FieldPanel('region_summary_section_content'),
            ],
        ),
        MultiFieldPanel(heading="Investment opportunities",
                        classname='collapsible collapsed',
                        children=[
                            FieldPanel('investment_opps_title'),
                            FieldPanel('investment_opps_intro'),
                        ]),
        MultiFieldPanel(
            heading="Economics Statistics",
            classname='collapsible',
            children=[
                HelpPanel(
                    'Required: at least 4 statistics for the section to show'),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('economics_stat_1_heading'),
                        FieldPanel('economics_stat_1_number'),
                        FieldPanel('economics_stat_1_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('economics_stat_2_heading'),
                        FieldPanel('economics_stat_2_number'),
                        FieldPanel('economics_stat_2_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('economics_stat_3_heading'),
                        FieldPanel('economics_stat_3_number'),
                        FieldPanel('economics_stat_3_smallprint'),
                    ]),
                ]),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('economics_stat_4_heading'),
                        FieldPanel('economics_stat_4_number'),
                        FieldPanel('economics_stat_4_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('economics_stat_5_heading'),
                        FieldPanel('economics_stat_5_number'),
                        FieldPanel('economics_stat_5_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('economics_stat_6_heading'),
                        FieldPanel('economics_stat_6_number'),
                        FieldPanel('economics_stat_6_smallprint'),
                    ]),
                ]),
            ],
        ),
        MultiFieldPanel(
            heading="Location Statistics",
            classname='collapsible',
            children=[
                HelpPanel(
                    'Required: at least 4 statistics for the section to show'),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('location_stat_1_heading'),
                        FieldPanel('location_stat_1_number'),
                        FieldPanel('location_stat_1_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('location_stat_2_heading'),
                        FieldPanel('location_stat_2_number'),
                        FieldPanel('location_stat_2_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('location_stat_3_heading'),
                        FieldPanel('location_stat_3_number'),
                        FieldPanel('location_stat_3_smallprint'),
                    ]),
                ]),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('location_stat_4_heading'),
                        FieldPanel('location_stat_4_number'),
                        FieldPanel('location_stat_4_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('location_stat_5_heading'),
                        FieldPanel('location_stat_5_number'),
                        FieldPanel('location_stat_5_smallprint'),
                    ]),
                    MultiFieldPanel([
                        FieldPanel('location_stat_6_heading'),
                        FieldPanel('location_stat_6_number'),
                        FieldPanel('location_stat_6_smallprint'),
                    ]),
                ]),
            ],
        ),
        MultiFieldPanel(
            heading="Extra optional Property and Infrastructure section",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Property and Infrastructure Section Title, '
                          'Property and Infrastructure Section Content'),
                ImageChooserPanel('property_and_infrastructure_section_image'),
                FieldPanel('property_and_infrastructure_section_title'),
                FieldPanel('property_and_infrastructure_section_content'),
            ],
        ),
        MultiFieldPanel(
            heading="Accordions subsections",
            classname='collapsible collapsed',
            children=[
                HelpPanel(
                    'Required: subsections title and at least one title and content for an accordion to show'
                ),
                FieldPanel('subsections_title'),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('sub_section_one_title'),
                        ImageChooserPanel('sub_section_one_icon'),
                        FieldPanel('sub_section_one_content')
                    ]),
                    MultiFieldPanel([
                        FieldPanel('sub_section_two_title'),
                        ImageChooserPanel('sub_section_two_icon'),
                        FieldPanel('sub_section_two_content')
                    ]),
                    MultiFieldPanel([
                        FieldPanel('sub_section_three_title'),
                        ImageChooserPanel('sub_section_three_icon'),
                        FieldPanel('sub_section_three_content')
                    ]),
                ]),
            ]),
        MultiFieldPanel(
            heading="Case study",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Case Study Image, Case Study Title'),
                ImageChooserPanel('case_study_image'),
                FieldPanel('case_study_title'),
                FieldPanel('case_study_text'),
                HelpPanel('Cta\'s require both text and a link to show '
                          'on page. '),
                FieldPanel('case_study_cta_text'),
                FieldPanel('case_study_cta_link'),
            ],
        ),
        MultiFieldPanel(
            heading="Contact",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Contact Title, Contact Text'),
                FieldPanel('contact_title'),
                FieldPanel('contact_text'),
                FieldPanel('contact_cta_text'),
                FieldPanel('contact_cta_link'),
            ],
        ),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('slug'),
    ]

    edit_handler = make_translated_interface(content_panels=content_panels,
                                             settings_panels=settings_panels)
class AboutUkWhyChooseTheUkPagePanels:

    content_panels = [
        FieldPanel('title'),
        FieldPanel('breadcrumbs_label'),
        MultiFieldPanel(
            heading="Hero",
            children=[
                FieldPanel('hero_title'),
                ImageChooserPanel('hero_image'),
            ],
        ),
        MultiFieldPanel(
            heading="Teaser",
            children=[
                FieldPanel('teaser'),
                FieldPanel('primary_contact_cta_text'),
                FieldPanel('primary_contact_cta_link')
            ],
        ),
        MultiFieldPanel(
            heading="Section 1",
            classname='collapsible',
            children=[
                HelpPanel('At least one field required for section to show'),
                FieldRowPanel([
                    FieldPanel('section_one_body'),
                    MultiFieldPanel([
                        ImageChooserPanel('section_one_image'),
                        FieldPanel('section_one_video',
                                   widget=AdminMediaChooser)
                    ])
                ])
            ],
        ),
        MultiFieldPanel(heading='Statistics',
                        classname='collapsible',
                        children=[
                            FieldRowPanel([
                                MultiFieldPanel([
                                    FieldPanel('statistic_1_heading'),
                                    FieldPanel('statistic_1_number'),
                                    FieldPanel('statistic_1_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_2_heading'),
                                    FieldPanel('statistic_2_number'),
                                    FieldPanel('statistic_2_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_3_heading'),
                                    FieldPanel('statistic_3_number'),
                                    FieldPanel('statistic_3_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_4_heading'),
                                    FieldPanel('statistic_4_number'),
                                    FieldPanel('statistic_4_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_5_heading'),
                                    FieldPanel('statistic_5_number'),
                                    FieldPanel('statistic_5_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_6_heading'),
                                    FieldPanel('statistic_6_number'),
                                    FieldPanel('statistic_6_smallprint')
                                ]),
                            ])
                        ]),
        MultiFieldPanel(heading="Articles section",
                        classname='collapsible',
                        children=[
                            InlinePanel('about_uk_articles_fields',
                                        label="About UK articles")
                        ]),
        MultiFieldPanel(
            heading="EBook section",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: title, body'),
                FieldRowPanel([
                    ImageChooserPanel('ebook_section_image'),
                    FieldPanel('ebook_section_image_alt_text')
                ]),
                MultiFieldPanel([
                    FieldPanel('ebook_section_title'),
                    FieldPanel('ebook_section_body'),
                    HelpPanel(
                        'CTAs require both text and a link to show on page.'),
                    FieldPanel('ebook_section_cta_text'),
                    FieldPanel('ebook_section_cta_link'),
                ]),
            ]),
        MultiFieldPanel(
            heading="Related pages",
            classname='collapsible',
            children=[
                HelpPanel(
                    'Required for section to show: title and at least one related page'
                ),
                FieldPanel('how_dit_help_title'),
                FieldRowPanel([
                    MultiFieldPanel([
                        PageChooserPanel(
                            'related_page_one',
                            'great_international.AboutDitServicesPage'),
                    ]),
                    MultiFieldPanel([
                        PageChooserPanel(
                            'related_page_two',
                            'great_international.AboutDitServicesPage'),
                    ]),
                    MultiFieldPanel([
                        PageChooserPanel(
                            'related_page_three',
                            'great_international.AboutDitServicesPage'),
                    ]),
                ]),
            ],
        ),
        MultiFieldPanel(
            heading="Contact Section",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Title, Summary'),
                FieldPanel('contact_us_section_title'),
                FieldPanel('contact_us_section_summary'),
                HelpPanel('CTAs require both text and a link to show '
                          'on page. '),
                FieldPanel('contact_us_section_cta_text'),
                FieldPanel('contact_us_section_cta_link'),
            ],
        ),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('slug'),
    ]

    edit_handler = make_translated_interface(content_panels=content_panels,
                                             settings_panels=settings_panels)
class AboutUkLandingPagePanels:

    image_panels = [
        ImageChooserPanel('hero_image'),
        ImageChooserPanel('why_choose_uk_image'),
        MultiFieldPanel(heading="How we help images",
                        children=[
                            ImageChooserPanel('how_we_help_one_icon'),
                            ImageChooserPanel('how_we_help_two_icon'),
                            ImageChooserPanel('how_we_help_three_icon'),
                            ImageChooserPanel('how_we_help_four_icon'),
                            ImageChooserPanel('how_we_help_five_icon'),
                            ImageChooserPanel('how_we_help_six_icon'),
                        ]),
        ImageChooserPanel('ebook_section_image'),
    ]

    content_panels = [
        FieldPanel('title'),
        FieldPanel('breadcrumbs_label'),
        MultiFieldPanel(
            heading="Hero",
            children=[
                FieldPanel('hero_title'),
            ],
        ),
        FieldPanel('intro'),
        MultiFieldPanel(heading="Why choose the UK section",
                        classname="collapsible",
                        children=[
                            FieldPanel('why_choose_uk_title'),
                            FieldPanel('why_choose_uk_content'),
                            FieldPanel('why_choose_uk_cta_text'),
                            FieldPanel('why_choose_uk_cta_link'),
                        ]),
        MultiFieldPanel(heading="Key Industries section",
                        classname="collapsible",
                        children=[
                            FieldPanel('industries_section_title'),
                            FieldPanel('industries_section_intro'),
                            FieldPanel('industries_section_cta_text'),
                            FieldPanel('industries_section_cta_link')
                        ]),
        MultiFieldPanel(
            heading="UK's regions section",
            classname="collapsible",
            children=[
                FieldPanel('regions_section_title'),
                FieldPanel('regions_section_intro'),
                FieldRowPanel([
                    MultiFieldPanel([
                        PageChooserPanel(
                            'scotland',
                            ['great_international.AboutUkRegionPage']),
                        FieldPanel('scotland_text')
                    ]),
                    MultiFieldPanel([
                        PageChooserPanel(
                            'northern_ireland',
                            ['great_international.AboutUkRegionPage']),
                        FieldPanel('northern_ireland_text')
                    ]),
                    MultiFieldPanel([
                        PageChooserPanel(
                            'north_england',
                            ['great_international.AboutUkRegionPage']),
                        FieldPanel('north_england_text')
                    ]),
                ]),
                FieldRowPanel([
                    MultiFieldPanel([
                        PageChooserPanel(
                            'wales',
                            ['great_international.AboutUkRegionPage']),
                        FieldPanel('wales_text')
                    ]),
                    MultiFieldPanel([
                        PageChooserPanel(
                            'midlands',
                            ['great_international.AboutUkRegionPage']),
                        FieldPanel('midlands_text')
                    ]),
                    MultiFieldPanel([
                        PageChooserPanel(
                            'south_england',
                            ['great_international.AboutUkRegionPage']),
                        FieldPanel('south_england_text')
                    ]),
                ]),
                FieldPanel('regions_section_cta_text'),
                FieldPanel('regions_section_cta_link'),
            ]),
        MultiFieldPanel(heading="How we help section",
                        classname="collapsible",
                        children=[
                            FieldPanel('how_we_help_title'),
                            FieldPanel('how_we_help_intro'),
                            FieldRowPanel([
                                MultiFieldPanel([
                                    FieldPanel('how_we_help_one_title'),
                                    FieldPanel('how_we_help_one_text')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('how_we_help_two_title'),
                                    FieldPanel('how_we_help_two_text')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('how_we_help_three_title'),
                                    FieldPanel('how_we_help_three_text')
                                ]),
                            ]),
                            FieldRowPanel([
                                MultiFieldPanel([
                                    FieldPanel('how_we_help_four_title'),
                                    FieldPanel('how_we_help_four_text')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('how_we_help_five_title'),
                                    FieldPanel('how_we_help_five_text')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('how_we_help_six_title'),
                                    FieldPanel('how_we_help_six_text')
                                ]),
                            ]),
                            FieldPanel('how_we_help_cta_text'),
                            FieldPanel('how_we_help_cta_link')
                        ]),
        MultiFieldPanel(
            heading="EBook section",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: title, body'),
                FieldRowPanel([FieldPanel('ebook_section_image_alt_text')]),
                MultiFieldPanel([
                    FieldPanel('ebook_section_title'),
                    FieldPanel('ebook_section_body'),
                    HelpPanel('CTAs require both text and a link to show '
                              'on page. '),
                    FieldPanel('ebook_section_cta_text'),
                    DocumentChooserPanel('ebook_section_cta_link'),
                ]),
            ]),
        MultiFieldPanel(heading="Contact us section",
                        classname="collapsible",
                        children=[
                            FieldPanel('contact_title'),
                            FieldPanel('contact_text'),
                            FieldPanel('contact_cta_text'),
                            FieldPanel('contact_cta_link'),
                        ]),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('slug'),
    ]

    edit_handler = make_translated_interface(content_panels=content_panels,
                                             settings_panels=settings_panels,
                                             other_panels=[
                                                 ObjectList(image_panels,
                                                            heading='Images'),
                                             ])
class AboutDitServicesPagePanels:

    content_panels = [
        FieldPanel('title'),
        FieldPanel('breadcrumbs_label'),
        MultiFieldPanel(
            heading="Hero",
            children=[
                FieldPanel('hero_title'),
            ],
        ),
        MultiFieldPanel(
            heading="Teaser",
            children=[
                FieldPanel('teaser'),
            ],
        ),
        MultiFieldPanel(
            heading="EBook section",
            classname='collapsible',
            children=[
                FieldRowPanel([FieldPanel('ebook_section_image_alt_text')]),
                MultiFieldPanel([
                    FieldPanel('ebook_section_body'),
                    HelpPanel(
                        'CTAs require both text and a link to show on page. '),
                    FieldPanel('ebook_section_cta_text'),
                    FieldPanel('ebook_section_cta_link'),
                ]),
            ]),
        FieldPanel('featured_description'),
        MultiFieldPanel(heading="Services section",
                        classname='collapsible',
                        children=[
                            InlinePanel('about_dit_services_fields',
                                        label="About DIT services")
                        ]),
        MultiFieldPanel(
            heading="Case study",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Case Study Image, Case Study Title'),
                FieldPanel('case_study_title'),
                FieldPanel('case_study_text'),
                HelpPanel('CTAs require both text and a link to show '
                          'on page. '),
                FieldPanel('case_study_cta_text'),
                FieldPanel('case_study_cta_link'),
            ],
        ),
        MultiFieldPanel(
            heading="Contact Section",
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Title, Summary'),
                FieldPanel('contact_us_section_title'),
                FieldPanel('contact_us_section_summary'),
                HelpPanel('CTAs require both text and a link to show '
                          'on page. '),
                FieldPanel('contact_us_section_cta_text'),
                FieldPanel('contact_us_section_cta_link'),
            ],
        ),
        SearchEngineOptimisationPanel()
    ]

    image_panels = [
        ImageChooserPanel('hero_image'),
        ImageChooserPanel('ebook_section_image'),
        ImageChooserPanel('case_study_image'),
    ]

    settings_panels = [
        FieldPanel('slug'),
    ]

    edit_handler = make_translated_interface(content_panels=content_panels,
                                             settings_panels=settings_panels,
                                             other_panels=[
                                                 ObjectList(image_panels,
                                                            heading='Images'),
                                             ])
class BaseInternationalSectorPagePanels:

    content_panels = [
        FieldPanel('title'),
        MultiFieldPanel(heading='Heading',
                        children=[
                            FieldPanel('heading'),
                            FieldPanel('sub_heading'),
                            ImageChooserPanel('hero_image'),
                            FieldPanel('heading_teaser'),
                            FieldPanel('featured_description')
                        ]),
        MultiFieldPanel(
            heading='Unique selling points',
            children=[
                HelpPanel(
                    'Use H2 (##) markdown for the three subheadings.'
                    ' Required fields for section to show: 3 Unique Selling '
                    'Points Markdown'),
                FieldRowPanel([
                    FieldPanel('section_one_body'),
                    MultiFieldPanel([
                        ImageChooserPanel('section_one_image'),
                        FieldPanel('section_one_image_caption'),
                        FieldPanel('section_one_image_caption_company')
                    ])
                ])
            ]),
        MultiFieldPanel(heading='Statistics',
                        children=[
                            FieldRowPanel([
                                MultiFieldPanel([
                                    FieldPanel('statistic_1_number'),
                                    FieldPanel('statistic_1_heading'),
                                    FieldPanel('statistic_1_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_2_number'),
                                    FieldPanel('statistic_2_heading'),
                                    FieldPanel('statistic_2_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_3_number'),
                                    FieldPanel('statistic_3_heading'),
                                    FieldPanel('statistic_3_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_4_number'),
                                    FieldPanel('statistic_4_heading'),
                                    FieldPanel('statistic_4_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_5_number'),
                                    FieldPanel('statistic_5_heading'),
                                    FieldPanel('statistic_5_smallprint')
                                ]),
                                MultiFieldPanel([
                                    FieldPanel('statistic_6_number'),
                                    FieldPanel('statistic_6_heading'),
                                    FieldPanel('statistic_6_smallprint')
                                ]),
                            ])
                        ]),
        MultiFieldPanel(
            heading='Spotlight',
            children=[
                FieldPanel('section_two_heading'),
                FieldPanel('section_two_teaser'),
                HelpPanel(
                    'Each icon needs a heading for it to show on the page.'),
                FieldRowPanel([
                    MultiFieldPanel([
                        ImageChooserPanel('section_two_subsection_one_icon'),
                        FieldPanel('section_two_subsection_one_heading'),
                        FieldPanel('section_two_subsection_one_body')
                    ]),
                    MultiFieldPanel([
                        ImageChooserPanel('section_two_subsection_two_icon'),
                        FieldPanel('section_two_subsection_two_heading'),
                        FieldPanel('section_two_subsection_two_body')
                    ]),
                    MultiFieldPanel([
                        ImageChooserPanel('section_two_subsection_three_icon'),
                        FieldPanel('section_two_subsection_three_heading'),
                        FieldPanel('section_two_subsection_three_body')
                    ])
                ])
            ]),
        MultiFieldPanel(
            heading='Case Study',
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Case Study Image, Case Study Title'),
                FieldPanel('case_study_title'),
                FieldPanel('case_study_description'),
                FieldPanel('case_study_cta_text'),
                HelpPanel('Cta\'s require both text and a link to show '
                          'on page. '),
                PageChooserPanel('case_study_cta_page', [
                    'great_international.InternationalArticlePage',
                    'great_international.InternationalCampaignPage',
                ]),
                ImageChooserPanel('case_study_image')
            ]),
        MultiFieldPanel(
            heading='Fact Sheets',
            classname='collapsible collapsed',
            children=[
                FieldPanel('section_three_heading'),
                FieldPanel('section_three_teaser'),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('section_three_subsection_one_heading'),
                        FieldPanel('section_three_subsection_one_teaser'),
                        HelpPanel('For accessibility reasons, use only '
                                  '"#### [Your text here]" for subheadings '
                                  'in this markdown field'),
                        FieldPanel('section_three_subsection_one_body')
                    ]),
                    MultiFieldPanel([
                        FieldPanel('section_three_subsection_two_heading'),
                        FieldPanel('section_three_subsection_two_teaser'),
                        HelpPanel('For accessibility reasons, use only '
                                  '"#### [Your text here]" for subheadings '
                                  'in this markdown field'),
                        FieldPanel('section_three_subsection_two_body')
                    ])
                ])
            ]),
        MultiFieldPanel(
            heading='Related articles',
            children=[
                FieldRowPanel([
                    PageChooserPanel('related_page_one', [
                        'great_international.InternationalArticlePage',
                        'great_international.InternationalCampaignPage',
                    ]),
                    PageChooserPanel('related_page_two', [
                        'great_international.InternationalArticlePage',
                        'great_international.InternationalCampaignPage',
                    ]),
                    PageChooserPanel('related_page_three', [
                        'great_international.InternationalArticlePage',
                        'great_international.InternationalCampaignPage',
                    ]),
                ])
            ]),
        MultiFieldPanel(
            heading='Project Opportunities',
            classname='collapsible ',
            children=[
                FieldPanel('project_opportunities_title'),
                HelpPanel('Up to 3 random opportunities that are related '
                          'to this sector will appear here.'),
                FieldPanel('related_opportunities_cta_text'),
                FieldPanel('related_opportunities_cta_link')
            ]),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('slug'),
        FieldPanel('tags', widget=CheckboxSelectMultiple)
    ]

    edit_handler = make_translated_interface(content_panels=content_panels,
                                             settings_panels=settings_panels)
示例#14
0
class LocationPage(JanisBasePage):
    """
    all the relevant details for a specifc location (place!?)
    decide if we want to set null or cascade
    """
    janis_url_page_type = 'location'

    alternate_name = models.CharField(max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="Location alternate name", help_text="Use this field if the building has a second name, or is inside a larger facility")

    physical_street = models.CharField(max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="Street")
    physical_unit = models.CharField(max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="Floor/Suite #")
    physical_city = models.CharField(max_length=DEFAULT_MAX_LENGTH, default='Austin', blank=True, verbose_name="City")
    physical_state = models.CharField(max_length=DEFAULT_MAX_LENGTH, default='TX', blank=True, verbose_name="State")
    physical_country = models.CharField(max_length=DEFAULT_MAX_LENGTH, default='USA', blank=True)
    physical_zip = models.CharField(max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="ZIP")

    physical_location_photo = models.ForeignKey(
        TranslatedImage,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name="Choose a banner image",
        help_text="Use this to show an exterior of the location."
    )

    phone_description = models.CharField(
        max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="Phone description")
    phone_number = PhoneNumberField(blank=True, verbose_name="Phone(only if location has a dedicated number)")
    email = models.EmailField(blank=True, verbose_name="Email address")

    mailing_street = models.CharField(max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="Street or PO box")
    mailing_city = models.CharField(max_length=DEFAULT_MAX_LENGTH, default='Austin', blank=True, verbose_name="City")
    mailing_state = models.CharField(max_length=DEFAULT_MAX_LENGTH, default='TX', blank=True, verbose_name="State")
    mailing_country = models.CharField(max_length=DEFAULT_MAX_LENGTH, default='USA', blank=True)
    mailing_zip = models.CharField(max_length=DEFAULT_MAX_LENGTH, blank=True, verbose_name="ZIP")

    nearest_bus_1 = models.IntegerField(null=True, blank=True)
    nearest_bus_2 = models.IntegerField(null=True, blank=True)
    nearest_bus_3 = models.IntegerField(null=True, blank=True)

    parent_page_types = ['base.HomePage']

    content_panels = [
        FieldPanel('title_en', widget=countMe),
        FieldPanel('title_es', widget=countMe),
        FieldPanel('title_ar'),
        FieldPanel('title_vi'),

        MultiFieldPanel(children=[
            FieldPanel('physical_street'),
            FieldPanel('physical_unit', classname='col2'),
            FieldPanel('physical_city', classname='col5'),
            FieldPanel('physical_state', classname='col4'),
            FieldPanel('physical_zip', classname='col2'),
        ], heading='Location physical address'),
        MultiFieldPanel(
            [
                HelpPanel(physical_location_photo.help_text, classname="coa-helpPanel"),
                ImageChooserPanel('physical_location_photo'),
            ],
            heading=physical_location_photo.verbose_name,
            classname='coa-multiField-nopadding'
        ),

        MultiFieldPanel(children=[
            FieldPanel('mailing_street'),
            FieldPanel('mailing_city', classname='col5'),
            FieldPanel('mailing_state', classname='col4'),
            FieldPanel('mailing_zip', classname='col2'),
        ],
            heading='Location mailing address (if applicable)',
            classname="collapsible"
        ),
        MultiFieldPanel(
            [
                HelpPanel(alternate_name.help_text, classname="coa-helpPanel"),
                FieldPanel('alternate_name'),
            ],
            heading=alternate_name.verbose_name,
            classname='coa-multiField-nopadding'
        ),

        FieldRowPanel(
            children=[
                FieldPanel('phone_number', classname='col6',
                           widget=PhoneNumberInternationalFallbackWidget),
                FieldPanel('phone_description', classname='col6'),
                FieldPanel('email', classname='col6'),
            ],
            heading="Location contact info"
        ),


        FieldRowPanel(
            children=[
                FieldPanel('nearest_bus_1'),
                FieldPanel('nearest_bus_2'),
                FieldPanel('nearest_bus_3'),
            ],
            heading="Location details"
        ),
    ]
示例#15
0
class MapLocation(index.Indexed, ClusterableModel):

    title = models.CharField(max_length=255,
                             help_text="The name as it appears on the map.")
    description = RichTextField(blank=True)

    node_id = models.CharField(blank=True, max_length=255)
    x = models.CharField(blank=True, max_length=255)
    y = models.CharField(blank=True, max_length=255)
    width = models.CharField(blank=True, max_length=255)
    height = models.CharField(blank=True, max_length=255)
    rotate = models.CharField(
        blank=True,
        max_length=10,
        help_text=
        "Rotates the icon/title on the map, in degrees (180, -45, 90, etc)")

    node_html = models.TextField(blank=True)
    node_css = models.TextField(blank=True)

    type = models.CharField(choices=[
        ('continent', 'Continent'),
        ('hidden', 'Hidden'),
        ('ocean', 'Ocean'),
        ('none', 'Not on map'),
        ('standard', 'Standard'),
        ('text', 'Text'),
        ('turtle', 'Turtle'),
    ],
                            null=True,
                            blank=False,
                            default='standard',
                            max_length=255)

    def __str__(self):
        return self.title

    def _title(self):
        return format_html('<b style="min-width: 200px;">{}</b>', self.title)

    def _description(self):
        return format_html('<div style="max-width:500px;">{}</div>',
                           format_html(self.description))

    def _image(self):
        layer = MapLocationImage.objects.filter(location=self).first()
        if layer and layer.image:
            return format_html(
                '<img class="species-thumbnail" src="{}" />',
                layer.image.file.url,
            )
        else:
            return None

    def _overlay(self):
        layers = MapLocationOverlay.objects.filter(location=self)
        if layers:
            html = '<div class="map-overlay-thumbnail">'
            for layer in layers:
                html += format_html(
                    '<img style="max-width:300px; border: 1px solid #333;" src="{}" />',
                    layer.image.file.url,
                )
            html += '</div>'
            return format_html(html)
        else:
            return None

    panels = [
        FieldPanel('title'),
        FieldPanel('type'),
        FieldPanel('description'),
        MultiFieldPanel([
            FieldPanel('node_id'),
            FieldPanel('rotate'),
            FieldPanel('width'),
            FieldPanel('height'),
            FieldPanel('x'),
            FieldPanel('y'),
        ],
                        heading="Positioning"),
        MultiFieldPanel([
            FieldPanel('node_html', classname="code-editor"),
            HelpPanel(
                content=
                'Paste HTML code here to overwrite settings. HTML can be generated <a target="_blank" href="https://www.inabrains.com/tooltip/image-hotspot-creator.html">here</a>.'
            ),
            FieldPanel('node_css', classname="code-editor"),
            HelpPanel(content='Inline styles for this node.'),
        ],
                        heading="Code"),
        MultiFieldPanel([
            InlinePanel('node_image'),
            HelpPanel(
                content='Replace the dot with an image. Can be multiple layers.'
            ),
        ],
                        heading="Node Replacement Image"),
        MultiFieldPanel([
            InlinePanel('overlay_image'),
            HelpPanel(
                content=
                'Overlays for the entire map, activated on hover. Should match the resolution of the map image.'
            ),
        ],
                        heading="Overlay Image"),
    ]

    def save(self):
        # If code exists, overwrite existing coords
        if self.node_html:
            # Extract attrs from div
            soup = BeautifulSoup(self.node_html + "</div>", 'html5lib')
            div = soup.div
            attrs = div.attrs

            self.node_id = attrs.get('id', self.node_id)

            # Extract styles
            rx = re.compile(r'(?:width|height|top|left):[^;]+;?')
            styles = rx.findall(self.node_html)

            # Assign found styles to fields
            for style in styles:
                if 'width' in style:
                    self.width = style.replace(';', '').replace('width:',
                                                                '').strip(' ')
                if 'height' in style:
                    self.height = style.replace(';',
                                                '').replace('height:',
                                                            '').strip(' ')
                if 'left' in style:
                    self.x = style.replace(';', '').replace('left:',
                                                            '').strip(' ')
                if 'top' in style:
                    self.y = style.replace(';', '').replace('top:',
                                                            '').strip(' ')

            self.node_html = ''

        super(MapLocation, self).save()
示例#16
0
class CoderedPage(Page, metaclass=CoderedPageMeta):
    """
    General use page with caching, templating, and SEO functionality.
    All pages should inherit from this.
    """
    class Meta:
        verbose_name = _('CodeRed Page')

    # Do not allow this page type to be created in wagtail admin
    is_creatable = False

    # Templates
    # The page will render the following templates under certain conditions:
    #
    # template = ''
    # amp_template = ''
    # ajax_template = ''
    # search_template = ''

    ###############
    # Content fields
    ###############
    cover_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=_('Cover image'),
    )

    ###############
    # Index fields
    ###############

    # Subclasses can override this to enabled index features by default.
    index_show_subpages_default = False

    # Subclasses can override this to query on a specific
    # page model, rather than the default wagtail Page.
    index_query_pagemodel = 'wagtailcore.Page'

    # Subclasses can override these fields to enable custom
    # ordering based on specific subpage fields.
    index_order_by_default = '-first_published_at'
    index_order_by_choices = (
        ('-first_published_at', _('Date first published, newest to oldest')),
        ('first_published_at', _('Date first published, oldest to newest')),
        ('-last_published_at', _('Date updated, newest to oldest')),
        ('last_published_at', _('Date updated, oldest to newest')),
        ('title', _('Title, alphabetical')),
        ('-title', _('Title, reverse alphabetical')),
    )
    index_show_subpages = models.BooleanField(
        default=index_show_subpages_default,
        verbose_name=_('Show list of child pages'))
    index_order_by = models.CharField(
        max_length=255,
        choices=index_order_by_choices,
        default=index_order_by_default,
        verbose_name=_('Order child pages by'),
    )
    index_num_per_page = models.PositiveIntegerField(
        default=10,
        verbose_name=_('Number per page'),
    )
    tags = ClusterTaggableManager(
        through=CoderedTag,
        verbose_name='Tags',
        blank=True,
        help_text=_('Used to categorize your pages.'))

    ###############
    # Layout fields
    ###############

    custom_template = models.CharField(blank=True,
                                       max_length=255,
                                       choices=None,
                                       verbose_name=_('Template'))

    ###############
    # SEO fields
    ###############

    og_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=_('Open Graph preview image'),
        help_text=
        _('The image shown when linking to this page on social media. If blank, defaults to article cover image, or logo in Settings > Layout > Logo'
          ))
    struct_org_type = models.CharField(
        default='',
        blank=True,
        max_length=255,
        choices=schema.SCHEMA_ORG_CHOICES,
        verbose_name=_('Organization type'),
        help_text=_('If blank, no structured data will be used on this page.'))
    struct_org_name = models.CharField(
        default='',
        blank=True,
        max_length=255,
        verbose_name=_('Organization name'),
        help_text=_('Leave blank to use the site name in Settings > Sites'))
    struct_org_logo = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=_('Organization logo'),
        help_text=_('Leave blank to use the logo in Settings > Layout > Logo'))
    struct_org_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=_('Photo of Organization'),
        help_text=
        _('A photo of the facility. This photo will be cropped to 1:1, 4:3, and 16:9 aspect ratios automatically.'
          ))
    struct_org_phone = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_('Telephone number'),
        help_text=
        _('Include country code for best results. For example: +1-216-555-8000'
          ))
    struct_org_address_street = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_('Street address'),
        help_text=_(
            'House number and street. For example, 55 Public Square Suite 1710'
        ))
    struct_org_address_locality = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_('City'),
        help_text=_('City or locality. For example, Cleveland'))
    struct_org_address_region = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_('State'),
        help_text=_('State, province, county, or region. For example, OH'))
    struct_org_address_postal = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_('Postal code'),
        help_text=_('Zip or postal code. For example, 44113'))
    struct_org_address_country = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_('Country'),
        help_text=
        _('For example, USA. Two-letter ISO 3166-1 alpha-2 country code is also acceptible https://en.wikipedia.org/wiki/ISO_3166-1'
          ))
    struct_org_geo_lat = models.DecimalField(
        blank=True,
        null=True,
        max_digits=10,
        decimal_places=8,
        verbose_name=_('Geographic latitude'))
    struct_org_geo_lng = models.DecimalField(
        blank=True,
        null=True,
        max_digits=10,
        decimal_places=8,
        verbose_name=_('Geographic longitude'))
    struct_org_hours = StreamField([
        ('hours', OpenHoursBlock()),
    ],
                                   blank=True,
                                   verbose_name=_('Hours of operation'))
    struct_org_actions = StreamField(
        [('actions', StructuredDataActionBlock())],
        blank=True,
        verbose_name=_('Actions'))
    struct_org_extra_json = models.TextField(
        blank=True,
        verbose_name=_('Additional Organization markup'),
        help_text=
        _('Additional JSON-LD inserted into the Organization dictionary. Must be properties of https://schema.org/Organization or the selected organization type.'
          ))

    ###############
    # Settings
    ###############

    content_walls = StreamField([('content_wall', ContentWallBlock())],
                                blank=True,
                                verbose_name=_('Content Walls'))

    ###############
    # Search
    ###############

    search_fields = [
        index.SearchField('title', partial_match=True, boost=3),
        index.SearchField('seo_title', partial_match=True, boost=3),
        index.SearchField('search_description', boost=2),
        index.FilterField('title'),
        index.FilterField('id'),
        index.FilterField('live'),
        index.FilterField('owner'),
        index.FilterField('content_type'),
        index.FilterField('path'),
        index.FilterField('depth'),
        index.FilterField('locked'),
        index.FilterField('first_published_at'),
        index.FilterField('last_published_at'),
        index.FilterField('latest_revision_created_at'),
        index.FilterField('index_show_subpages'),
        index.FilterField('index_order_by'),
        index.FilterField('custom_template'),
    ]

    ###############
    # Panels
    ###############

    content_panels = (Page.content_panels + [
        ImageChooserPanel('cover_image'),
    ])

    body_content_panels = []

    bottom_content_panels = [
        FieldPanel('tags'),
    ]

    layout_panels = [
        MultiFieldPanel([FieldPanel('custom_template')],
                        heading=_('Visual Design')),
        MultiFieldPanel([
            FieldPanel('index_show_subpages'),
            FieldPanel('index_num_per_page'),
            FieldPanel('index_order_by'),
        ],
                        heading=_('Show Child Pages'))
    ]

    promote_panels = [
        MultiFieldPanel([
            FieldPanel('slug'),
            FieldPanel('seo_title'),
            FieldPanel('search_description'),
            ImageChooserPanel('og_image'),
        ], _('Page Meta Data')),
        MultiFieldPanel([
            HelpPanel(
                heading=_('About Organization Structured Data'),
                content=
                _("""The fields below help define brand, contact, and storefront
                    information to search engines. This information should be filled out on
                    the site’s root page (Home Page). If your organization has multiple locations,
                    then also fill this info out on each location page using that particular
                    location’s info."""),
            ),
            FieldPanel('struct_org_type'),
            FieldPanel('struct_org_name'),
            ImageChooserPanel('struct_org_logo'),
            ImageChooserPanel('struct_org_image'),
            FieldPanel('struct_org_phone'),
            FieldPanel('struct_org_address_street'),
            FieldPanel('struct_org_address_locality'),
            FieldPanel('struct_org_address_region'),
            FieldPanel('struct_org_address_postal'),
            FieldPanel('struct_org_address_country'),
            FieldPanel('struct_org_geo_lat'),
            FieldPanel('struct_org_geo_lng'),
            StreamFieldPanel('struct_org_hours'),
            StreamFieldPanel('struct_org_actions'),
            FieldPanel('struct_org_extra_json'),
        ], _('Structured Data - Organization')),
    ]

    settings_panels = (Page.settings_panels + [
        StreamFieldPanel('content_walls'),
    ])

    def __init__(self, *args, **kwargs):
        """
        Inject custom choices and defalts into the form fields
        to enable customization by subclasses.
        """
        super().__init__(*args, **kwargs)

        klassname = self.__class__.__name__.lower()
        template_choices = cr_settings['FRONTEND_TEMPLATES_PAGES'].get('*', ()) + \
                           cr_settings['FRONTEND_TEMPLATES_PAGES'].get(klassname, ())

        self._meta.get_field(
            'index_order_by').choices = self.index_order_by_choices
        self._meta.get_field('custom_template').choices = template_choices
        if not self.id:
            self.index_order_by = self.index_order_by_default
            self.index_show_subpages = self.index_show_subpages_default

    @classmethod
    def get_edit_handler(cls):
        """
        Override to "lazy load" the panels overriden by subclasses.
        """
        return TabbedInterface([
            ObjectList(cls.content_panels + cls.body_content_panels +
                       cls.bottom_content_panels,
                       heading='Content'),
            ObjectList(cls.layout_panels, heading='Layout'),
            ObjectList(cls.promote_panels, heading='SEO', classname="seo"),
            ObjectList(cls.settings_panels,
                       heading='Settings',
                       classname="settings"),
        ]).bind_to_model(cls)

    def get_struct_org_name(self):
        """
        Gets org name for sturctured data using a fallback.
        """
        if self.struct_org_name:
            return self.struct_org_name
        return self.get_site().site_name

    def get_struct_org_logo(self):
        """
        Gets logo for structured data using a fallback.
        """
        if self.struct_org_logo:
            return self.struct_org_logo
        else:
            layout_settings = LayoutSettings.for_site(self.get_site())
            if layout_settings.logo:
                return layout_settings.logo
        return None

    def get_template(self, request, *args, **kwargs):
        """
        Override parent to serve different templates based on querystring.
        """
        if 'amp' in request.GET and hasattr(self, 'amp_template'):
            seo_settings = SeoSettings.for_site(request.site)
            if seo_settings.amp_pages:
                if request.is_ajax():
                    return self.ajax_template or self.amp_template
                return self.amp_template

        if self.custom_template:
            return self.custom_template

        return super(CoderedPage, self).get_template(request, args, kwargs)

    def get_index_children(self):
        """
        Override to return query of subpages as defined by `index_` variables.
        """
        if self.index_query_pagemodel:
            querymodel = resolve_model_string(self.index_query_pagemodel,
                                              self._meta.app_label)
            return querymodel.objects.child_of(self).order_by(
                self.index_order_by)

        return super().get_children().live()

    def get_content_walls(self, check_child_setting=True):
        current_content_walls = []
        if check_child_setting:
            for wall in self.content_walls:
                content_wall = wall.value
                if wall.value['show_content_wall_on_children']:
                    current_content_walls.append(wall.value)
        else:
            current_content_walls = self.content_walls

        try:
            return list(current_content_walls) + self.get_parent(
            ).specific.get_content_walls()
        except AttributeError:
            return list(current_content_walls)

    def get_context(self, request, *args, **kwargs):
        """
        Add child pages and paginated child pages to context.
        """
        context = super().get_context(request)

        if self.index_show_subpages:
            all_children = self.get_index_children()
            paginator = Paginator(all_children, self.index_num_per_page)
            page = request.GET.get('p', 1)
            try:
                paged_children = paginator.page(page)
            except:
                paged_children = paginator.page(1)

            context['index_paginated'] = paged_children
            context['index_children'] = all_children
        context['content_walls'] = self.get_content_walls(
            check_child_setting=False)
        return context
示例#17
0
class ArticlePage(Page):
    tags = ClusterTaggableManager(through=ArticlePageTag, blank=True)
    author_image = models.ForeignKey('wagtailimages.Image',
                                     null=True,
                                     blank=True,
                                     on_delete=models.SET_NULL,
                                     related_name='+')
    author_name = models.CharField(max_length=10,
                                   validators=[MinLengthValidator(2)])
    article_datetime = models.DateTimeField()
    article_cover = models.ForeignKey('wagtailimages.Image',
                                      null=True,
                                      blank=True,
                                      on_delete=models.SET_NULL,
                                      related_name='+')
    article_cover_app = models.ForeignKey('wagtailimages.Image',
                                          null=True,
                                          blank=True,
                                          on_delete=models.SET_NULL,
                                          related_name='+')
    description = models.TextField(blank=True)
    liked_count = models.IntegerField(default=0)

    body = StreamField([
        ('Paragraph', blocks.RichTextBlock()),
        ('RawHTML', blocks.RawHTMLBlock()),
        ('DocumentChooser', DocumentChooserBlock()),
    ])

    content_panels = Page.content_panels + [
        HelpPanel('建议文章标题不超过30个字'),
        FieldPanel('tags'),
        HelpPanel('建议标签数量最多2个,标签字数1~5个'),
        FieldPanel('description'),
        ImageChooserPanel('author_image'),
        FieldPanel('author_name'),
        FieldPanel('article_datetime'),
        ImageChooserPanel('article_cover'),
        ImageChooserPanel('article_cover_app'),
        StreamFieldPanel('body'),
    ]

    api_fields = [
        APIField('tags'),
        APIField('author_image'),
        APIField('author_name'),
        APIField('article_datetime',
                 serializer=DateTimeField(format="%Y-%m-%d %H:%M")),
        APIField('article_cover'),
        APIField('article_cover_app'),
        APIField('description'),
        APIField('liked_count'),
        # This will nest the relevant BlogPageAuthor objects in the API response
    ]

    parent_page_types = ['ArticleListPage']
    subpage_types = []

    def get_datetime_format(self):

        return self.article_datetime.strftime("%Y-%m-%d %H:%I")

    @property
    def first_tag(self):
        if self.tags:
            return self.tags.first()
        else:
            return None
示例#18
0
class InvestmentOpportunityPagePanels:

    content_panels = [
        MultiFieldPanel(
            heading='Opportunity Page title, intro and summary',
            classname='collapsible',
            children=[
                FieldPanel('title'),
                FieldPanel('breadcrumbs_label'),
                ImageChooserPanel('hero_image'),
                MediaChooserPanel('hero_video'),
                FieldPanel('strapline'),
                FieldPanel('introduction'),
                ImageChooserPanel('intro_image'),
                FieldPanel('opportunity_summary'),
            ],
        ),
        MultiFieldPanel(
            heading="Key facts",
            classname='collapsible',
            children=[
                FieldRowPanel([
                    FieldPanel('promoter'),
                    FieldPanel('location'),
                    MultiFieldPanel(heading='Scale',
                                    children=[
                                        FieldPanel('scale'),
                                        FieldPanel('scale_value'),
                                    ]),
                ]),
                FieldRowPanel([
                    FieldPanel('planning_status'),
                    FieldPanel('investment_type'),
                    FieldPanel('time_to_investment_decision'),
                ]),
                HelpPanel(
                    'In addition to these, please also set a location in the Location tab'
                ),
            ],
        ),
        MultiFieldPanel(
            heading='Opportunity Contact',
            classname='collapsible',
            children=[
                FieldPanel('contact_name'),
                ImageChooserPanel('contact_avatar'),
                FieldPanel('contact_job_title'),
                FieldPanel('contact_link'),
            ],
        ),
        MultiFieldPanel(
            heading='The Opportunity',
            classname='collapsible',
            children=[
                StreamFieldPanel('main_content'),
                FieldPanel('important_links'),
            ],
        ),
        SearchEngineOptimisationPanel(),
    ]

    related_entities_panels = [
        FieldRowPanel(heading='Location and Relevant Regions',
                      classname='collapsible',
                      children=[
                          StreamFieldPanel('regions_with_locations'),
                      ]),
        FieldRowPanel(
            heading="Sectors and Sub-sectors",
            classname='collapsible collapsed',
            children=[
                InlinePanel('related_sectors', label="Related Sectors"),
                InlinePanel('related_sub_sectors', label="Related Sub-sectors")
            ],
        ),
    ]

    settings_panels = [
        FieldPanel('slug'),
        FieldPanel('priority_weighting'),
    ]

    edit_handler = make_translated_interface(
        content_panels=content_panels,
        other_panels=related_entities_panels,  # These are shown as separate tabs
        settings_panels=settings_panels,
    )
示例#19
0
class SeoDefault(BaseSetting):
    """
    Social media accounts.
    """
    class Meta:
        verbose_name = _("SEO Default Each Page")

    ###############
    # SEO fields
    ###############

    search_description = models.CharField(blank=True, max_length=1023)

    struct_org_type = models.CharField(
        default="",
        blank=True,
        max_length=255,
        choices=schema.SCHEMA_ORG_CHOICES,
        verbose_name=_("Organization type"),
        help_text=_("If blank, no structured data will be used on this page."),
    )
    struct_org_name = models.CharField(
        default="",
        blank=True,
        max_length=255,
        verbose_name=_("Organization name"),
        help_text=_("Leave blank to use the site name in Settings > Sites"),
    )
    struct_org_logo = models.ForeignKey(
        get_image_model_string(),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name=_("Organization logo"),
        help_text=_("Leave blank to use the logo in Settings > Layout > Logo"),
    )
    struct_org_image = models.ForeignKey(
        get_image_model_string(),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name=_("Photo of Organization"),
        help_text=
        _("A photo of the facility. This photo will be cropped to 1:1, 4:3, and 16:9 aspect ratios automatically."
          ),  # noqa
    )
    struct_org_phone = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_("Telephone number"),
        help_text=
        _("Include country code for best results. For example: +1-216-555-8000"
          ),
    )
    struct_org_address_street = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_("Street address"),
        help_text=_(
            "House number and street. For example, 55 Public Square Suite 1710"
        ),
    )
    struct_org_address_locality = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_("City"),
        help_text=_("City or locality. For example, Cleveland"),
    )
    struct_org_address_region = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_("State"),
        help_text=_("State, province, county, or region. For example, OH"),
    )
    struct_org_address_postal = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_("Postal code"),
        help_text=_("Zip or postal code. For example, 44113"),
    )
    struct_org_address_country = models.CharField(
        blank=True,
        max_length=255,
        verbose_name=_("Country"),
        help_text=
        _("For example, USA. Two-letter ISO 3166-1 alpha-2 country code is also acceptible https://en.wikipedia.org/wiki/ISO_3166-1"
          ),  # noqa
    )
    struct_org_geo_lat = models.DecimalField(
        blank=True,
        null=True,
        max_digits=10,
        decimal_places=8,
        verbose_name=_("Geographic latitude"),
    )
    struct_org_geo_lng = models.DecimalField(
        blank=True,
        null=True,
        max_digits=11,
        decimal_places=8,
        verbose_name=_("Geographic longitude"),
    )
    struct_org_hours = StreamField([
        ("hours", OpenHoursBlock()),
    ],
                                   blank=True,
                                   verbose_name=_("Hours of operation"))
    struct_org_actions = StreamField(
        [("actions", StructuredDataActionBlock())],
        blank=True,
        verbose_name=_("Actions"),
    )
    struct_org_extra_json = models.TextField(
        blank=True,
        verbose_name=_("Additional Organization markup"),
        help_text=
        _("Additional JSON-LD inserted into the Organization dictionary. Must be properties of https://schema.org/Organization or the selected organization type."
          ),  # noqa
    )

    panels = [
        MultiFieldPanel(
            [
                FieldPanel("company_name"),
                FieldPanel("email"),
                FieldPanel("telephone_number"),
                FieldPanel("handphone_number_1"),
                FieldPanel("handphone_number_2"),
                FieldPanel("address"),
                FieldPanel("copyright_year"),
            ],
            _("Profile"),
        )
    ]

    panels = [
        MultiFieldPanel(
            [
                FieldPanel("search_description"),
            ],
            _("Page Meta Data"),
        ),
        MultiFieldPanel(
            [
                HelpPanel(
                    heading=_("About Organization Structured Data"),
                    content=
                    _("""The fields below help define brand, contact, and storefront
                    information to search engines. This information should be filled out on
                    the site’s root page (Home Page). If your organization has multiple locations,
                    then also fill this info out on each location page using that particular
                    location’s info."""),
                ),
                FieldPanel("struct_org_type"),
                FieldPanel("struct_org_name"),
                ImageChooserPanel("struct_org_logo"),
                ImageChooserPanel("struct_org_image"),
                FieldPanel("struct_org_phone"),
                FieldPanel("struct_org_address_street"),
                FieldPanel("struct_org_address_locality"),
                FieldPanel("struct_org_address_region"),
                FieldPanel("struct_org_address_postal"),
                FieldPanel("struct_org_address_country"),
                FieldPanel("struct_org_geo_lat"),
                FieldPanel("struct_org_geo_lng"),
                StreamFieldPanel("struct_org_hours"),
                StreamFieldPanel("struct_org_actions"),
                FieldPanel("struct_org_extra_json"),
            ],
            _("Structured Data - Organization"),
        ),
    ]
示例#20
0
class ShortCoursePage(ContactFieldsMixin, BasePage):
    template = "patterns/pages/shortcourses/short_course.html"
    parent_page_types = ["programmes.ProgrammeIndexPage"]
    hero_image = models.ForeignKey(
        "images.CustomImage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    introduction = models.CharField(max_length=500, blank=True)
    introduction_image = models.ForeignKey(
        get_image_model_string(),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    video_caption = models.CharField(
        blank=True,
        max_length=80,
        help_text="The text dipsplayed next to the video play button",
    )
    video = models.URLField(blank=True)
    body = RichTextField(blank=True)
    about = StreamField(
        [("accordion_block", AccordionBlockWithTitle())],
        blank=True,
        verbose_name=_("About the course"),
    )

    access_planit_course_id = models.IntegerField(blank=True, null=True)
    frequently_asked_questions = models.ForeignKey(
        "utils.ShortCourseDetailSnippet",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    terms_and_conditions = models.ForeignKey(
        "utils.ShortCourseDetailSnippet",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    course_details_text = RichTextField(blank=True)
    show_register_link = models.BooleanField(
        default=1,
        help_text="If selected, an automatic 'Register your interest' link will be \
                                                                   visible in the key details section",
    )
    course_details_text = RichTextField(blank=True)
    programme_type = models.ForeignKey(
        ProgrammeType,
        on_delete=models.SET_NULL,
        blank=False,
        null=True,
        related_name="+",
    )
    location = RichTextField(blank=True, features=["link"])
    introduction = models.CharField(max_length=500, blank=True)

    quote_carousel = StreamField(
        [("quote", QuoteBlock())], blank=True, verbose_name=_("Quote carousel")
    )
    staff_title = models.CharField(
        max_length=50,
        blank=True,
        help_text="Heading to display above the short course team members, E.G Programme Team",
    )
    gallery = StreamField(
        [("slide", GalleryBlock())], blank=True, verbose_name="Gallery"
    )
    external_links = StreamField(
        [("link", LinkBlock())], blank=True, verbose_name="External Links"
    )
    application_form_url = models.URLField(
        blank=True,
        help_text="Adding an application form URL will override the Access Planit booking modal",
    )
    manual_registration_url = models.URLField(
        blank=True, help_text="Override the register interest link show in the modal",
    )

    access_planit_and_course_data_panels = [
        MultiFieldPanel(
            [
                FieldPanel("manual_registration_url"),
                HelpPanel(
                    "Defining course details manually will override any Access Planit data configured for this page"
                ),
                InlinePanel("manual_bookings", label="Booking"),
            ],
            heading="Manual course configuration",
        ),
        MultiFieldPanel(
            [FieldPanel("application_form_url")], heading="Application URL"
        ),
        FieldPanel("access_planit_course_id"),
        MultiFieldPanel(
            [
                FieldPanel("course_details_text"),
                SnippetChooserPanel("frequently_asked_questions"),
                SnippetChooserPanel("terms_and_conditions"),
            ],
            heading="course details",
        ),
    ]
    content_panels = BasePage.content_panels + [
        MultiFieldPanel([ImageChooserPanel("hero_image")], heading=_("Hero"),),
        MultiFieldPanel(
            [
                FieldPanel("introduction"),
                ImageChooserPanel("introduction_image"),
                FieldPanel("video"),
                FieldPanel("video_caption"),
                FieldPanel("body"),
            ],
            heading=_("Course Introduction"),
        ),
        StreamFieldPanel("about"),
        FieldPanel("programme_type"),
        StreamFieldPanel("quote_carousel"),
        MultiFieldPanel(
            [FieldPanel("staff_title"), InlinePanel("related_staff", label="Staff")],
            heading="Short course team",
        ),
        StreamFieldPanel("gallery"),
        MultiFieldPanel([*ContactFieldsMixin.panels], heading="Contact information"),
        MultiFieldPanel(
            [InlinePanel("related_programmes", label="Related programmes")],
            heading="Related Programmes",
        ),
        MultiFieldPanel(
            [
                InlinePanel(
                    "related_schools_and_research_pages",
                    label=_("Related Schools and Research centre pages"),
                )
            ],
            heading=_("Related Schools and Research Centre pages"),
        ),
        StreamFieldPanel("external_links"),
    ]
    key_details_panels = [
        InlinePanel("fee_items", label="Fees"),
        FieldPanel("location"),
        FieldPanel("show_register_link"),
        InlinePanel("subjects", label=_("Subjects")),
    ]

    edit_handler = TabbedInterface(
        [
            ObjectList(content_panels, heading="Content"),
            ObjectList(key_details_panels, heading="Key details"),
            ObjectList(
                access_planit_and_course_data_panels, heading="Course configuration"
            ),
            ObjectList(BasePage.promote_panels, heading="Promote"),
            ObjectList(BasePage.settings_panels, heading="Settings"),
        ]
    )

    search_fields = BasePage.search_fields + [
        index.SearchField("introduction", partial_match=True),
        index.AutocompleteField("introduction", partial_match=True),
        index.RelatedFields(
            "programme_type",
            [
                index.SearchField("display_name", partial_match=True),
                index.AutocompleteField("display_name", partial_match=True),
            ],
        ),
        index.RelatedFields(
            "subjects",
            [
                index.RelatedFields(
                    "subject",
                    [
                        index.SearchField("title", partial_match=True),
                        index.AutocompleteField("title", partial_match=True),
                    ],
                )
            ],
        ),
    ]

    api_fields = [
        # Fields for filtering and display, shared with programmes.ProgrammePage.
        APIField("subjects"),
        APIField("programme_type"),
        APIField("related_schools_and_research_pages"),
        APIField("summary", serializer=CharFieldSerializer(source="introduction")),
        APIField(
            name="hero_image_square",
            serializer=ImageRenditionField("fill-580x580", source="hero_image"),
        ),
    ]

    @property
    def get_manual_bookings(self):
        return self.manual_bookings.all()

    def get_access_planit_data(self):
        access_planit_course_data = AccessPlanitXML(
            course_id=self.access_planit_course_id
        )
        return access_planit_course_data.get_data()

    def _format_booking_bar(self, register_interest_link=None, access_planit_data=None):
        """ Booking bar messaging with the next course data available
        Find the next course date marked as status='available' and advertise
        this date in the booking bar. If there are no courses available, add
        a default message."""

        booking_bar = {
            "message": "Bookings not yet open",
            "action": "Register your interest for upcoming dates",
        }
        # If there are no dates the booking link should go to a form, not open
        # a modal, this link is also used as a generic interest link too though.
        booking_bar["link"] = register_interest_link

        # If manual_booking links are defined, format the booking bar and return
        # it before checking access planit
        if self.manual_bookings.first():
            date = self.manual_bookings.first()
            booking_bar["message"] = "Next course starts"
            booking_bar["date"] = date.start_date
            if date.booking_link:
                booking_bar["action"] = (
                    f"Book from \xA3{date.cost}" if date.cost else "Book now"
                )
            booking_bar["modal"] = "booking-details"
            booking_bar["cost"] = date.cost
            return booking_bar

        # If there is access planit data, format the booking bar
        if access_planit_data:
            for date in access_planit_data:
                if date["status"] == "Available":
                    booking_bar["message"] = "Next course starts"
                    booking_bar["date"] = date["start_date"]
                    booking_bar["cost"] = date["cost"]
                    if self.application_form_url:
                        # URL has been provided to override AccessPlanit booking
                        booking_bar["action"] = "Complete form to apply"
                        booking_bar["link"] = self.application_form_url
                        booking_bar["modal"] = None
                    else:
                        # Open AccessPlanit booking modal
                        booking_bar["action"] = f"Book now from \xA3{date['cost']}"
                        booking_bar["link"] = None
                        booking_bar["modal"] = "booking-details"
                    break
            return booking_bar

        # Check for a manual_registration_url if there is no data
        if self.manual_registration_url:
            booking_bar["link"] = self.manual_registration_url
        return booking_bar

    def clean(self):
        super().clean()
        errors = defaultdict(list)
        if (
            self.show_register_link
            and not self.manual_registration_url
            and not self.access_planit_course_id
        ):
            errors["show_register_link"].append(
                "An access planit course ID or manual registration link is needed to show the register links"
            )
        if self.access_planit_course_id:
            try:
                checker = AccessPlanitCourseChecker(
                    course_id=self.access_planit_course_id
                )
                if not checker.course_exists():
                    errors["access_planit_course_id"].append(
                        "Could not find a course with this ID"
                    )
            except AccessPlanitException:
                errors["access_planit_course_id"].append(
                    "Error checking this course ID in Access Planit. Please try again shortly."
                )

        if errors:
            raise ValidationError(errors)

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        access_planit_data = self.get_access_planit_data()
        context[
            "register_interest_link"
        ] = (
            register_interest_link
        ) = f"{settings.ACCESS_PLANIT_REGISTER_INTEREST_BASE}?course_id={self.access_planit_course_id}"
        context["booking_bar"] = self._format_booking_bar(
            register_interest_link, access_planit_data
        )
        context["booking_bar"] = self._format_booking_bar(
            register_interest_link, access_planit_data
        )
        context["access_planit_data"] = access_planit_data
        context["shortcourse_details_fees"] = self.fee_items.values_list(
            "text", flat=True
        )
        context["related_sections"] = [
            {
                "title": "More opportunities to study at the RCA",
                "related_items": [
                    rel.page.specific
                    for rel in self.related_programmes.select_related("page")
                ],
            }
        ]
        context["related_staff"] = self.related_staff.select_related(
            "image"
        ).prefetch_related("page")
        return context
示例#21
0
class HomePage(Page):
    """Model for the websites homepage"""

    # For the header on the homepage.
    header_header = models.CharField(max_length=100, blank=False)
    header_image = models.ForeignKey('wagtailimages.Image',
                                     blank=False,
                                     null=True,
                                     on_delete=models.SET_NULL,
                                     related_name='+')
    header_body = RichTextField(blank=False)

    # These will affect the whole site. See wagtailblog/context_processor.py.
    logo_image = models.ForeignKey('wagtailimages.Image',
                                   blank=False,
                                   null=True,
                                   on_delete=models.SET_NULL,
                                   related_name='+')
    favicon_file = models.ForeignKey('wagtaildocs.Document',
                                     blank=False,
                                     null=True,
                                     on_delete=models.SET_NULL,
                                     related_name='+')
    footer = RichTextField(blank=False)
    instagram = models.URLField(blank=False)

    # HTML meta tags for the homepage.
    keywords = ClusterTaggableManager(through=HomePageKeywords, blank=True)
    description = models.CharField(max_length=160, blank=True, null=True)

    # Instagram widget on the homepage.
    show_widget = models.BooleanField(null=True)
    instagram_widget = models.TextField(blank=True, null=True)

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            HelpPanel(template='help_panel/branding_help.html'),
            ImageChooserPanel('logo_image'),
            DocumentChooserPanel('favicon_file'),
        ],
                        heading="Branding"),
        MultiFieldPanel([
            HelpPanel(template='help_panel/metatag_help.html'),
            FieldPanel('keywords'),
            FieldPanel('description'),
        ],
                        heading="HTML meta tags"),
        MultiFieldPanel([
            FieldPanel('header_header', classname='title'),
            FieldPanel('header_body'),
            ImageChooserPanel('header_image'),
        ],
                        heading="Header"),
        MultiFieldPanel([
            HelpPanel(template='help_panel/widget_help.html'),
            FieldPanel('show_widget', widget=forms.CheckboxInput),
            FieldPanel('instagram_widget'),
        ],
                        heading="Instagram widget"),
        MultiFieldPanel([
            HelpPanel(template='help_panel/footer_help.html'),
            FieldPanel('footer'),
            FieldPanel('instagram'),
        ],
                        heading="Footer"),
    ]

    def latest_posts(self):
        """Get the six latest published posts"""

        posts = BlogPost.objects.live().filter(
            date__lte=timezone.now()).order_by('-date')[:6]

        return posts

    def get_context(self, request):
        """Context variables for the homepage template"""

        context = super().get_context(request)
        context['latest_posts'] = self.latest_posts
        context['show_widget'] = self.show_widget
        context['instagram_widget'] = self.instagram_widget
        context['homepage_header_image'] = self.header_image.file.url

        return context
示例#22
0
class SchoolPage(ContactFieldsMixin, LegacyNewsAndEventsMixin, BasePage):
    template = "patterns/pages/schools/schools.html"
    introduction = RichTextField(blank=False, features=["link"])
    introduction_image = models.ForeignKey(
        get_image_model_string(),
        null=True,
        blank=False,
        on_delete=models.SET_NULL,
        related_name="+",
        help_text=
        "This image appears after the intro copy. If a video is uploaded, this image is required",
    )
    video_caption = models.CharField(
        blank=True,
        max_length=80,
        help_text=_("The text displayed next to the video play button"),
    )
    video = models.URLField(blank=True)
    body = RichTextField()

    school_dean = models.ForeignKey(
        "people.StaffPage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    # location
    location = RichTextField(blank=True, features=["link"])
    next_open_day_date = models.DateField(blank=True, null=True)
    link_to_open_days = models.URLField(blank=True)

    # Get in touch
    get_in_touch = RichTextField(blank=True, features=["link"])
    # Social Links
    social_links = StreamField(StreamBlock([("Link", LinkBlock())], max_num=5),
                               blank=True)
    news_and_events_heading = models.CharField(blank=True, max_length=120)
    collaborators_heading = models.CharField(blank=True, max_length=120)
    collaborators = StreamField(
        StreamBlock([("Collaborator", LinkedImageBlock())], max_num=9),
        blank=True,
        help_text="You can add up to 9 collaborators. Minimum 200 x 200 pixels. \
            Aim for logos that sit on either a white or transparent background.",
    )
    about_external_links = StreamField(
        [("link", InternalExternalLinkBlock())],
        blank=True,
        verbose_name="External links",
    )
    about_cta_block = StreamField(
        StreamBlock(
            [("call_to_action", CallToActionBlock(label=_("text promo")))],
            max_num=1),
        verbose_name="CTA",
        blank=True,
    )

    research_projects_title = models.CharField(max_length=125,
                                               default="Our Research")
    research_projects_text = RichTextField(blank=True, features=["link"])
    external_links_heading = models.CharField(max_length=125, blank=True)

    external_links = StreamField([("link", InternalExternalLinkBlock())],
                                 blank=True)
    research_cta_block = StreamField(
        StreamBlock(
            [("call_to_action", CallToActionBlock(label=_("text promo")))],
            max_num=1,
        ),
        blank=True,
    )
    research_collaborators_heading = models.CharField(blank=True,
                                                      max_length=120)
    research_collaborators = StreamField(
        StreamBlock([("Collaborator", LinkedImageBlock())], max_num=9),
        blank=True,
        help_text="You can add up to 9 collaborators. Minimum 200 x 200 pixels. \
            Aim for logos that sit on either a white or transparent background.",
    )
    related_programmes_title = models.CharField(blank=True, max_length=120)
    related_programmes_summary = models.CharField(blank=True, max_length=500)
    related_short_courses_title = models.CharField(blank=True, max_length=120)
    related_short_courses_summary = models.CharField(blank=True,
                                                     max_length=500)
    programmes_links_heading = models.CharField(max_length=125,
                                                blank=True,
                                                verbose_name="Links heading")
    programmes_external_links = StreamField(
        [("link", InternalExternalLinkBlock())],
        blank=True,
        verbose_name="Links")
    programmes_cta_block = StreamField(
        StreamBlock(
            [("call_to_action", CallToActionBlock(label=_("text promo")))],
            max_num=1,
            verbose_name="Call to action",
        ),
        blank=True,
    )

    # Staff
    staff_title = models.CharField(blank=True,
                                   max_length=120,
                                   verbose_name="Related staff title")
    staff_summary = models.CharField(blank=True,
                                     max_length=500,
                                     verbose_name="Related staff summary text")
    staff_external_links = StreamField([("link", InternalExternalLinkBlock())],
                                       blank=True,
                                       verbose_name="Links")
    staff_external_links_heading = models.CharField(
        max_length=125, blank=True, verbose_name="Related staff links heading")
    staff_cta_block = StreamField(
        StreamBlock(
            [("call_to_action", CallToActionBlock(label=_("text promo")))],
            max_num=1,
            verbose_name="Call to action",
        ),
        blank=True,
    )
    staff_link = models.URLField(blank=True)
    staff_link_text = models.CharField(max_length=125,
                                       blank=True,
                                       help_text="E.g. 'See all staff'")

    search_fields = BasePage.search_fields + [
        index.SearchField("introduction")
    ]
    api_fields = [APIField("introduction")]

    # Admin panel configuration
    content_panels = [
        *BasePage.content_panels,
        InlinePanel(
            "hero_items",
            max_num=6,
            label="Hero Items",
            help_text="You can add up to 6 hero images",
        ),
        FieldPanel("introduction"),
        ImageChooserPanel("introduction_image"),
        MultiFieldPanel([FieldPanel("video"),
                         FieldPanel("video_caption")],
                        heading="Video"),
        FieldPanel("body"),
    ]
    key_details_panels = [
        PageChooserPanel("school_dean"),
        MultiFieldPanel(
            [
                FieldPanel("next_open_day_date"),
                FieldPanel("link_to_open_days")
            ],
            heading="Next open day",
        ),
        FieldPanel("location"),
        FieldPanel("get_in_touch"),
        StreamFieldPanel("social_links"),
    ]
    about_panel = [
        InlinePanel("page_teasers", max_num=1, label="Page teasers"),
        MultiFieldPanel(
            [
                FieldPanel("collaborators_heading"),
                StreamFieldPanel("collaborators")
            ],
            heading="Collaborators",
        ),
        InlinePanel("stats_block", label="Statistics", max_num=1),
        StreamFieldPanel("about_external_links"),
        StreamFieldPanel("about_cta_block"),
    ]
    news_and_events_panels = [
        FieldPanel("news_and_events_heading"),
        InlinePanel("student_stories", label="Student Stories", max_num=1),
        FieldPanel("legacy_news_and_event_tags"),
    ]
    research_panels = [
        MultiFieldPanel(
            [
                FieldPanel("research_projects_title"),
                FieldPanel("research_projects_text"),
                HelpPanel(
                    content="Projects related to this School are automatically \
                        listed, this can be overriden by defining projects manually"
                ),
                InlinePanel("manually_related_project_pages",
                            max_num=5,
                            label="Project"),
            ],
            heading="Research projects",
        ),
        MultiFieldPanel(
            [
                InlinePanel(
                    "student_research", label="Student research", max_num=1)
            ],
            heading="Student research",
        ),
        MultiFieldPanel(
            [
                FieldPanel("research_collaborators_heading"),
                StreamFieldPanel("research_collaborators"),
            ],
            heading="Collaborators",
        ),
        MultiFieldPanel(
            [
                FieldPanel("external_links_heading"),
                StreamFieldPanel("external_links")
            ],
            heading="Links",
        ),
        MultiFieldPanel([StreamFieldPanel("research_cta_block")],
                        heading="Call To Action"),
    ]
    programmes_panels = [
        FieldPanel("related_programmes_title"),
        FieldPanel("related_programmes_summary"),
    ]
    short_course_panels = [
        FieldPanel("related_short_courses_title"),
        FieldPanel("related_short_courses_summary"),
        InlinePanel("related_short_courses", label="Short Course Pages"),
        MultiFieldPanel(
            [
                FieldPanel("programmes_links_heading"),
                StreamFieldPanel("programmes_external_links"),
            ],
            heading="Links",
        ),
        MultiFieldPanel([StreamFieldPanel("programmes_cta_block")],
                        heading="Call To Action"),
    ]
    staff_panels = [
        FieldPanel("staff_title"),
        FieldPanel("staff_summary"),
        InlinePanel("related_staff", label="Related staff"),
        HelpPanel(
            content=
            "By default, related staff will be automatically listed. This \
                can be overriden by adding staff pages here."),
        MultiFieldPanel(
            [FieldPanel("staff_link_text"),
             FieldPanel("staff_link")],
            heading="View more staff link",
        ),
        MultiFieldPanel(
            [
                FieldPanel("staff_external_links_heading"),
                StreamFieldPanel("staff_external_links", heading="Links"),
            ],
            heading="Links",
        ),
        StreamFieldPanel("staff_cta_block", heading="Call to action"),
    ]
    contact_panels = [
        MultiFieldPanel([*ContactFieldsMixin.panels],
                        heading="Contact information"),
    ]
    edit_handler = TabbedInterface([
        ObjectList(content_panels, heading="Introduction"),
        ObjectList(key_details_panels, heading="Key details"),
        ObjectList(about_panel, heading="About"),
        ObjectList(news_and_events_panels, heading="News and Events"),
        ObjectList(research_panels, heading="Our research"),
        ObjectList(programmes_panels, heading="Programmes"),
        ObjectList(short_course_panels, heading="Short Courses"),
        ObjectList(staff_panels, heading="Staff"),
        ObjectList(contact_panels, heading="Contact"),
        ObjectList(BasePage.promote_panels, heading="Promote"),
        ObjectList(BasePage.settings_panels, heading="Settings"),
    ])

    def get_hero_image(self):
        # Select a random image from the set of hero items added
        hero_items = self.hero_items.all()
        if not hero_items:
            return
        selected_item = random.choice(hero_items)
        return {
            "image": selected_item.hero_image,
        }

    def clean(self):
        errors = defaultdict(list)
        super().clean()
        if self.staff_link and not self.staff_link_text:
            errors["staff_link_text"].append(
                _("Missing text value for the link"))
        if self.staff_link_text and not self.staff_link:
            errors["staff_link"].append(_("Missing url value for the link"))
        if errors:
            raise ValidationError(errors)

    def page_nav(self):
        # If these are updated, the id in the template's FE will need to be updated to match
        # TODO conditionally set/remove depending on fields
        return [
            {
                "title": "Overview"
            },
            {
                "title": "Research"
            },
            {
                "title": "Study"
            },
            {
                "title": "Staff"
            },
            {
                "title": "Contact"
            },
        ]

    def get_related_projects(self):
        """
        Displays latest projects related to this school page.
        Returns:
            List of:
                filtered and formatted manually related ProjectPages
                or automatically fetch project pages from project > school relationship
        """
        from rca.projects.models import ProjectPage

        manual_related_projects = [
            i.page.id
            for i in self.manually_related_project_pages.select_related("page")
        ]
        auto_related_projects = ProjectPage.objects.filter(
            related_school_pages__page_id=self.id)[:6]
        if manual_related_projects:
            return format_projects_for_gallery(
                ProjectPage.objects.filter(id__in=manual_related_projects))
        elif auto_related_projects:
            return format_projects_for_gallery(auto_related_projects)

    def get_student_research(self, student_research, request):
        if not student_research:
            return {}
        if student_research.link_page:
            link = student_research.link_page.get_url(request)
        else:
            link = student_research.link_url

        return {
            "title": student_research.title,
            "link_url": link,
            "link_text": student_research.link_text
            or student_research.link_page,
            "slides": related_list_block_slideshow(student_research.slides),
        }

    def get_student_stories(self, student_stories, request):
        if not student_stories:
            return {}
        return {
            "title": student_stories.title,
            "slides": related_list_block_slideshow(student_stories.slides),
        }

    def get_related_programmes(self):
        """
        Get programme pages from the programme_page__school relationship.
        Returns:
            List -- of filtered and formatted Programme Pages.
        """
        ProgrammePage = apps.get_model("programmes", "ProgrammePage")

        all_programmes = ProgrammePage.objects.live().public()
        return all_programmes.filter(
            related_schools_and_research_pages__page_id=self.id)

    def get_programme_index_link(self):
        ProgrammeIndexPage = apps.get_model("programmes", "ProgrammeIndexPage")
        programme_index = ProgrammeIndexPage.objects.live().first()
        if programme_index:
            return programme_index.get_url()

    def get_short_courses_index_link(self):
        """Returns a link to the programme index page filtered by the
        Short Course ProgrammeType
        """
        ProgrammeType = apps.get_model("programmes", "ProgrammeType")
        short_course_type = ProgrammeType.objects.filter(
            display_name="Short course").first()
        if short_course_type:
            return (
                f"{self.get_programme_index_link()}?category=programme_type&"
                f"value={short_course_type.id}-{slugify(short_course_type.display_name)}"
            )

    def get_related_staff(self):
        """Method to return a related staff.
        The default behaviour should be to find related staff via the relationship
        from StaffPage > SchoolPage. This also needs to offer the option to
        manually add related staff to the school page, this helps solve issues
        of custom ordering that's needed with large (>25) staff items.
        """

        from rca.people.models import StaffPage

        related_staff = self.related_staff.select_related("image")
        if related_staff:
            return related_staff

        # For any automatially related staff, adjust the list so we don't have
        # to make edits to the template shared by other page models.
        staff = []
        for item in (StaffPage.objects.filter(
                related_schools__page=self).live().order_by("last_name")):
            staff.append({"page": item})
        return staff

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        hero_image = self.get_hero_image()
        if hero_image:
            context["hero_image"] = hero_image["image"]
        context["page_teasers"] = format_page_teasers(
            self.page_teasers.first())
        context["stats_block"] = self.stats_block.select_related(
            "background_image").first()
        context["featured_research"] = self.get_related_projects()
        context["student_research"] = self.get_student_research(
            self.student_research.first(), request)
        context["student_stories"] = self.get_student_stories(
            self.student_stories.first(), request)
        context["staff"] = self.get_related_staff()
        # Set the page tab titles for the jump menu
        context["related_programmes"] = [
            {
                "related_items":
                [page.specific for page in self.get_related_programmes()],
                "link": {
                    "url": self.get_programme_index_link,
                    "title": "Browse all RCA programmes",
                },
            },
        ]

        context["related_short_courses"] = [{
            "related_items": [
                rel.page.specific
                for rel in self.related_short_courses.select_related("page")
            ],
            "link": {
                "url": self.get_short_courses_index_link(),
                "title": "Browse all RCA short courses",
            },
        }]
        # Set the page tab titles for the jump menu
        context["tabs"] = self.page_nav()
        return context
示例#23
0
文件: models.py 项目: janun/janunde
class JobOfferIndexPage(BasePage):
    subpage_types = ["JobOfferPage"]
    max_count_per_parent = 1

    heading = models.CharField("Überschrift", max_length=255, blank=True)
    highlight_in_heading = models.CharField(
        "Hervorhebungen in der Überschrift",
        help_text="Wiederhole Text aus der Überschrift der farblich hervorgehoben werden soll",
        blank=True,
        max_length=255,
    )
    subtitle = models.CharField("Untertitel", max_length=255, blank=True)

    before_jobs = StreamField(
        StandardStreamBlock,
        blank=True,
        verbose_name="Intro-Text (wenn Jobs vorhanden)",
        help_text="Wird als Text vor der Liste der Stellenanzeigen angezeigt. Aber nur wenn es auch Stellenanzeigen gibt.",
    )

    after_jobs = StreamField(
        StandardStreamBlock,
        blank=True,
        verbose_name="Outro-Text (wenn Jobs vorhanden)",
        help_text="Wird als Text nach der Liste der Stellenanzeigen angezeigt. Aber nur wenn es auch Stellenanzeigen gibt.",
    )

    empty = StreamField(
        StandardStreamBlock(),
        blank=True,
        null=True,
        verbose_name="Wenn keine Jobs",
        help_text="Wird angezeigt, wenn es keine Stellenanzeigen gibt.",
    )

    def get_context(self, request):
        context = super().get_context(request)
        context["jobs"] = JobOfferPage.objects.all().live()
        return context

    search_fields = BasePage.search_fields + [
        index.SearchField("heading"),
        index.SearchField("subtitle"),
        index.SearchField("before_jobs"),
        index.SearchField("after_jobs"),
    ]

    content_panels = [
        MultiFieldPanel(
            [
                FieldPanel("title"),
                FieldPanel("heading"),
                FieldPanel("highlight_in_heading"),
                FieldPanel("subtitle"),
            ],
            "Kopf",
        ),
        StreamFieldPanel("before_jobs"),
        HelpPanel(
            template="jobs/admin_add_job_button.html",
            heading="Stellenauschreibung erstellen",
        ),
        StreamFieldPanel("after_jobs"),
        StreamFieldPanel("empty"),
    ]

    class Meta:
        verbose_name = "Auflistung von Stellenausschreibungen"
        verbose_name_plural = "Auflistungen von Stellenausschreibungen"
示例#24
0
class InvestHomePage(ExclusivePageMixin, ServiceHomepageMixin, BaseInvestPage):
    slug_identity = slugs.INVEST_HOME_PAGE
    view_path = ''

    breadcrumbs_label = models.CharField(max_length=50)
    heading = models.CharField(max_length=255)
    sub_heading = models.CharField(max_length=255)
    hero_call_to_action_text = models.CharField(max_length=255, blank=True)
    hero_call_to_action_url = models.CharField(max_length=255, blank=True)
    hero_image = models.ForeignKey('wagtailimages.Image',
                                   blank=True,
                                   null=True,
                                   on_delete=models.SET_NULL,
                                   related_name='+')

    benefits_section_title = models.CharField(max_length=255, blank=True)
    benefits_section_intro = models.TextField(max_length=255, blank=True)
    benefits_section_content = MarkdownField(blank=True)
    benefits_section_img = models.ForeignKey(
        'wagtailimages.Image',
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name="Benefits section image")

    eu_exit_section_title = models.CharField(
        max_length=255, blank=True, verbose_name="EU exit section title")

    eu_exit_section_content = MarkdownField(
        blank=True, verbose_name="EU exit section content")

    eu_exit_section_call_to_action_text = models.CharField(
        max_length=255, blank=True, verbose_name="EU exit section button text")

    eu_exit_section_call_to_action_url = models.CharField(
        max_length=255, blank=True, verbose_name="EU exit section button url")

    eu_exit_section_img = models.ForeignKey(
        'wagtailimages.Image',
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name="EU exit section image")

    sector_title = models.TextField(default="Discover UK Industries",
                                    max_length=255,
                                    blank=True)

    sector_button_text = models.TextField(default="See more industries",
                                          max_length=255,
                                          blank=True)

    sector_button_url = models.CharField(max_length=255, blank=True)

    sector_intro = models.TextField(max_length=255, blank=True)

    hpo_title = models.CharField(
        max_length=255,
        verbose_name="High potential opportunity section title",
        blank=True)
    hpo_intro = models.TextField(
        max_length=255,
        blank=True,
        verbose_name="High potential opportunity section intro")

    capital_invest_section_title = models.CharField(max_length=255, blank=True)
    capital_invest_section_content = MarkdownField(blank=True)
    capital_invest_section_image = models.ForeignKey('wagtailimages.Image',
                                                     blank=True,
                                                     null=True,
                                                     on_delete=models.SET_NULL,
                                                     related_name='+')

    setup_guide_title = models.CharField(
        default='Set up an overseas business in the UK',
        max_length=255,
        blank=True)

    setup_guide_lead_in = models.TextField(blank=True, null=True)

    setup_guide_content = MarkdownField(blank=True)
    setup_guide_img = models.ForeignKey('wagtailimages.Image',
                                        blank=True,
                                        null=True,
                                        on_delete=models.SET_NULL,
                                        related_name='+',
                                        verbose_name="Setup guide image")
    setup_guide_call_to_action_url = models.CharField(max_length=255,
                                                      blank=True)

    isd_section_image = models.ForeignKey(
        'wagtailimages.Image',
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Investment Support Directory section image')
    isd_section_title = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Investment Support Directory section title')
    isd_section_text = MarkdownField(
        max_length=255,
        blank=True,
        verbose_name='Investment Support Directory section text')

    featured_card_one_image = models.ForeignKey(
        'wagtailimages.Image',
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    featured_card_one_title = models.CharField(blank=True, max_length=255)
    featured_card_one_summary = MarkdownField(blank=True)
    featured_card_one_cta_link = models.CharField(max_length=255, blank=True)

    featured_card_two_image = models.ForeignKey(
        'wagtailimages.Image',
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    featured_card_two_title = models.CharField(
        max_length=255,
        blank=True,
    )
    featured_card_two_summary = MarkdownField(
        max_length=255,
        blank=True,
    )
    featured_card_two_cta_link = models.CharField(max_length=255, blank=True)

    featured_card_three_image = models.ForeignKey('wagtailimages.Image',
                                                  blank=True,
                                                  null=True,
                                                  on_delete=models.SET_NULL,
                                                  related_name='+')
    featured_card_three_title = models.CharField(max_length=255, blank=True)
    featured_card_three_summary = MarkdownField(blank=True)
    featured_card_three_cta_link = models.CharField(max_length=255, blank=True)

    how_we_help_title = models.CharField(default='How we help',
                                         max_length=255,
                                         blank=True)
    how_we_help_lead_in = models.TextField(blank=True, null=True)
    # how we help
    how_we_help_text_one = models.CharField(max_length=255, blank=True)
    how_we_help_icon_one = models.ForeignKey('wagtailimages.Image',
                                             null=True,
                                             blank=True,
                                             on_delete=models.SET_NULL,
                                             related_name='+')
    how_we_help_text_two = models.CharField(max_length=255, blank=True)
    how_we_help_icon_two = models.ForeignKey('wagtailimages.Image',
                                             null=True,
                                             blank=True,
                                             on_delete=models.SET_NULL,
                                             related_name='+')
    how_we_help_text_three = models.CharField(max_length=255, blank=True)
    how_we_help_icon_three = models.ForeignKey('wagtailimages.Image',
                                               null=True,
                                               blank=True,
                                               on_delete=models.SET_NULL,
                                               related_name='+')
    how_we_help_text_four = models.CharField(max_length=255, blank=True)
    how_we_help_icon_four = models.ForeignKey('wagtailimages.Image',
                                              null=True,
                                              blank=True,
                                              on_delete=models.SET_NULL,
                                              related_name='+')
    how_we_help_text_five = models.CharField(max_length=255, blank=True)
    how_we_help_icon_five = models.ForeignKey('wagtailimages.Image',
                                              null=True,
                                              blank=True,
                                              on_delete=models.SET_NULL,
                                              related_name='+')
    how_we_help_text_six = models.CharField(max_length=255, blank=True)

    contact_section_title = models.CharField(max_length=255, blank=True)
    contact_section_content = models.TextField(max_length=255, blank=True)
    contact_section_call_to_action_text = models.CharField(max_length=255,
                                                           blank=True)
    contact_section_call_to_action_url = models.CharField(max_length=255,
                                                          blank=True)

    image_panels = [
        ImageChooserPanel('hero_image'),
    ]

    content_panels = [
        MultiFieldPanel(
            heading='Hero',
            classname='collapsible',
            children=[
                FieldPanel('breadcrumbs_label'),
                FieldPanel('heading'),
                FieldPanel('sub_heading'),
                FieldPanel('hero_call_to_action_text'),
                FieldPanel('hero_call_to_action_url'),
            ],
        ),
        MultiFieldPanel(
            heading='Benefits section',
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Benefits Section Title, Benefits Section Content'),
                FieldPanel('benefits_section_title'),
                FieldPanel('benefits_section_intro'),
                FieldPanel('benefits_section_content'),
                ImageChooserPanel('benefits_section_img'),
            ],
        ),
        MultiFieldPanel(
            heading='EU Exit section',
            classname='collapsible collapsed',
            children=[
                FieldPanel('eu_exit_section_title'),
                FieldPanel('eu_exit_section_content'),
                FieldPanel('eu_exit_section_call_to_action_text'),
                FieldPanel('eu_exit_section_call_to_action_url'),
                ImageChooserPanel('eu_exit_section_img'),
            ],
        ),
        MultiFieldPanel(
            heading='Old featured card links',
            classname='collapsible collapsed',
            children=[
                FieldRowPanel([
                    MultiFieldPanel([
                        ImageChooserPanel('setup_guide_img'),
                        FieldPanel('setup_guide_title'),
                        FieldPanel('setup_guide_content'),
                        FieldPanel('setup_guide_call_to_action_url'),
                    ], ),
                    MultiFieldPanel([
                        ImageChooserPanel('isd_section_image'),
                        FieldPanel('isd_section_title'),
                        FieldPanel('isd_section_text')
                    ], ),
                    MultiFieldPanel([
                        ImageChooserPanel('capital_invest_section_image'),
                        FieldPanel('capital_invest_section_title'),
                        FieldPanel('capital_invest_section_content'),
                    ]),
                ]),
            ],
        ),
        MultiFieldPanel(
            heading='Featured card links ',
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'All images, titles and summaries'),
                FieldRowPanel([
                    MultiFieldPanel([
                        ImageChooserPanel('featured_card_one_image'),
                        FieldPanel('featured_card_one_title'),
                        FieldPanel('featured_card_one_summary'),
                        FieldPanel('featured_card_one_cta_link'),
                    ], ),
                    MultiFieldPanel([
                        ImageChooserPanel('featured_card_two_image'),
                        FieldPanel('featured_card_two_title'),
                        FieldPanel('featured_card_two_summary'),
                        FieldPanel('featured_card_two_cta_link'),
                    ], ),
                    MultiFieldPanel([
                        ImageChooserPanel('featured_card_three_image'),
                        FieldPanel('featured_card_three_title'),
                        FieldPanel('featured_card_three_summary'),
                        FieldPanel('featured_card_three_cta_link'),
                    ]),
                ]),
            ],
        ),
        MultiFieldPanel(
            heading='Industries section',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Sector Title, Sector Content'),
                FieldPanel('sector_title'),
                FieldPanel('sector_intro'),
                FieldPanel('sector_button_text'),
                FieldPanel('sector_button_url'),
            ],
        ),
        MultiFieldPanel(
            heading='High Potential Opportunities',
            children=[
                HelpPanel('Required fields for section to show: '
                          'HPO title, 1 HPO in active language'),
                FieldPanel('hpo_title'),
                FieldPanel('hpo_intro')
            ],
        ),
        MultiFieldPanel(
            heading='How we help section',
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'How We Help Title, How We Help Lead In'),
                FieldPanel('how_we_help_title'),
                FieldPanel('how_we_help_lead_in'),
                HelpPanel('Each icon requires the corresponding text to '
                          'show on the page'),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('how_we_help_text_one'),
                        ImageChooserPanel('how_we_help_icon_one')
                    ], ),
                    MultiFieldPanel([
                        FieldPanel('how_we_help_text_two'),
                        ImageChooserPanel('how_we_help_icon_two')
                    ], ),
                    MultiFieldPanel([
                        FieldPanel('how_we_help_text_three'),
                        ImageChooserPanel('how_we_help_icon_three')
                    ], ),
                ], ),
                FieldRowPanel([
                    MultiFieldPanel([
                        FieldPanel('how_we_help_text_four'),
                        ImageChooserPanel('how_we_help_icon_four')
                    ], ),
                    MultiFieldPanel([
                        FieldPanel('how_we_help_text_five'),
                        ImageChooserPanel('how_we_help_icon_five')
                    ], )
                ], ),
            ],
        ),
        MultiFieldPanel(
            heading='Contact Section',
            classname='collapsible',
            children=[
                HelpPanel('Required fields for section to show: '
                          'Contact Title, Contact Content'),
                FieldPanel('contact_section_title'),
                FieldPanel('contact_section_content'),
                HelpPanel('Cta\'s require both text and a link to show '
                          'on page. '),
                FieldPanel('contact_section_call_to_action_text'),
                FieldPanel('contact_section_call_to_action_url'),
            ],
        ),
        SearchEngineOptimisationPanel()
    ]

    settings_panels = [
        FieldPanel('title_en_gb'),
        FieldPanel('slug'),
    ]

    edit_handler = make_translated_interface(content_panels=content_panels,
                                             settings_panels=settings_panels,
                                             other_panels=[
                                                 ObjectList(image_panels,
                                                            heading='Images'),
                                             ])
class NavbarSection(models.Model):
    """
    Navbar Section
    """
    navbar_layout_scheme = models.CharField(
        max_length=50,
        choices=cr_settings['NAVBAR_LAYOUT_SCHEME_CHOICES'],
        default=cr_settings['NAVBAR_LAYOUT_SCHEME_CHOICES_DEFAULT'],
        verbose_name=('Layout Scheme'),
    )
    navbar_color_scheme = models.CharField(
        max_length=50,
        choices=cr_settings['NAVBAR_COLOR_SCHEME_CHOICES'],
        default=cr_settings['NAVBAR_COLOR_SCHEME_CHOICES_DEFAULT'],
        verbose_name=('Color type'),
    )
    navbar_background_type = models.CharField(
        blank=True,
        null=True,
        choices=cr_settings['NAVBAR_BACKGROUND_TYPE_CHOICES'],
        verbose_name='Type',
        max_length=100,
    )
    navbar_background_color = ColorField(
        blank=True,
        null=True,
        verbose_name=('Color 1'),
    )
    navbar_background_color_2 = ColorField(
        blank=True,
        null=True,
        verbose_name=('Color 2'),
    )
    navbar_font_color = ColorField(
        blank=True,
        null=True,
        verbose_name=('Font color'),
    )
    navbar_fixed = models.BooleanField(
        default=False,
        verbose_name=('Fixed'),
    )
    navbar_transparent = models.BooleanField(
        default=False,
        verbose_name=('Transparent'),
    )
    navbar_height = models.CharField(
        null=True,
        blank=True,
        max_length=50,
        choices=cr_settings['NAVBAR_HEIGHT_CHOICES'],
        default=cr_settings['NAVBAR_HEIGHT_CHOICES_DEFAULT'],
        verbose_name='Height',
    )
    navbar_top_bottom_padding = models.CharField(
        null=True,
        blank=True,
        max_length=50,
        choices=cr_settings['NAVBAR_TOP_BOTTOM_PADDING_CHOICES'],
        default=cr_settings['NAVBAR_TOP_BOTTOM_PADDING_CHOICES_DEFAULT'],
        verbose_name='Padding',
    )
    navbar_container_width = models.CharField(
        null=True,
        blank=True,
        max_length=50,
        choices=cr_settings['NAVBAR_CONTAINER_WIDTH_CHOICES'],
        default=cr_settings['NAVBAR_CONTAINER_WIDTH_CHOICES_DEFAULT'],
        verbose_name='Width',
    )

    # Panels
    navbar_panels = (

        # NAVBAR
        HelpPanel(template='panels/custom_help_panel_heading.html',
                  content='Navbar'),
        MultiFieldPanel(
            (
                FieldRowPanel(children=(FieldPanel('navbar_transparent',
                                                   classname="col6"), ), ),
                FieldRowPanel(children=(FieldPanel('navbar_color_scheme',
                                                   classname="col6"), ), ),
                FieldRowPanel(children=(
                    FieldPanel('navbar_background_type', classname="col6"), )),
                FieldRowPanel(children=(
                    NativeColorPanel('navbar_background_color',
                                     classname="col6"),
                    NativeColorPanel('navbar_background_color_2',
                                     classname="col6"),
                ), ),
            ),
            heading='Design',
            classname='collapsible collapsed',
        ),
        MultiFieldPanel(
            (
                FieldRowPanel(children=(FieldPanel('navbar_fixed',
                                                   classname="col6"), ), ),
                FieldRowPanel(children=(
                    FieldPanel('navbar_layout_scheme', classname="col6"),
                    FieldPanel('navbar_height', classname="col6"),
                    FieldPanel('navbar_container_width', classname="col6"),
                    FieldPanel('navbar_top_bottom_padding', classname="col6"),
                ), ),
            ),
            heading='Layout',
            classname='collapsible collapsed',
        ),
        HelpPanel(template='panels/custom_help_panel_heading.html',
                  content=''),
    )

    class Meta:
        abstract = True