class PortfolioPageJobCareer(GraphQLEnabledModel, Orderable):
    portfolio = ParentalKey(PortfolioPage,
                            on_delete=models.CASCADE,
                            related_name='job_career',
                            verbose_name=u'職務経歴')
    title = models.CharField(verbose_name=u'タイトル', max_length=50)
    start_date = models.DateField(u'開始日', auto_now=False, auto_now_add=False)
    end_date = models.DateField(u'終了日',
                                auto_now=False,
                                auto_now_add=False,
                                blank=True,
                                null=True)
    job_role = models.CharField(u'役割', max_length=50, blank=True, null=True)
    description = MarkdownField(verbose_name=u'説明', blank=True, null=True)

    panels = [
        FieldPanel('title'),
        FieldPanel('start_date'),
        FieldPanel('end_date'),
        FieldPanel('job_role'),
        MarkdownPanel('description')
    ]

    graphql_fields = [
        GraphQLField('title'),
        GraphQLField('start_date'),
        GraphQLField('end_date'),
        GraphQLField('job_role'),
        GraphQLField('description'),
    ]
Exemple #2
0
class StandardPage(GraphQLEnabledModel, Page):
    """
    A generic content page. On this demo site we use it for an about page but
    it could be used for any type of page content that only needs a title,
    image, introduction and body field
    """

    introduction = models.TextField(help_text='Text to describe the page',
                                    blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')
    body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
    content_panels = Page.content_panels + [
        FieldPanel('introduction', classname="full"),
        StreamFieldPanel('body'),
        ImageChooserPanel('image'),
    ]

    graphql_fields = [
        GraphQLField('introduction'),
        GraphQLField('image'),
        GraphQLField('body'),
    ]
Exemple #3
0
class People(GraphQLEnabledModel, index.Indexed, ClusterableModel):
    """
    A Django model to store People objects.
    It uses the `@register_snippet` decorator to allow it to be accessible
    via the Snippets UI (e.g. /admin/snippets/base/people/)

    `People` uses the `ClusterableModel`, which allows the relationship with
    another model to be stored locally to the 'parent' model (e.g. a PageModel)
    until the parent is explicitly saved. This allows the editor to use the
    'Preview' button, to preview the content, without saving the relationships
    to the database.
    https://github.com/wagtail/django-modelcluster
    """
    first_name = models.CharField("First name", max_length=254)
    last_name = models.CharField("Last name", max_length=254)
    job_title = models.CharField("Job title", max_length=254)

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

    panels = [
        MultiFieldPanel([
            FieldRowPanel([
                FieldPanel('first_name', classname="col6"),
                FieldPanel('last_name', classname="col6"),
            ])
        ], "Name"),
        FieldPanel('job_title'),
        ImageChooserPanel('image')
    ]

    search_fields = [
        index.SearchField('first_name'),
        index.SearchField('last_name'),
    ]
    graphql_fields = [
        GraphQLField('first_name'),
        GraphQLField('last_name'),
        GraphQLField('job_title'),
        GraphQLField('image'),
    ]

    @property
    def thumb_image(self):
        # Returns an empty string if there is no profile pic or the rendition
        # file can't be found.
        try:
            return self.image.get_rendition('fill-50x50').img_tag()
        except:
            return ''

    def __str__(self):
        return '{} {}'.format(self.first_name, self.last_name)

    class Meta:
        verbose_name = 'Person'
        verbose_name_plural = 'People'
Exemple #4
0
class ArticlePageRelatedLink(GraphQLEnabledModel, Orderable):
    page = ParentalKey(ArticlePage,
                       on_delete=models.CASCADE,
                       related_name='related_links')
    name = models.CharField(max_length=255)
    url = models.URLField()

    panels = [
        FieldPanel('name'),
        FieldPanel('url'),
    ]

    graphql_fields = [GraphQLField('name'), GraphQLField('url')]
Exemple #5
0
class AuthorPageSnsLink(GraphQLEnabledModel, Orderable):
    Author = ParentalKey(AuthorPage,
                         on_delete=models.CASCADE,
                         related_name='sns_links',
                         verbose_name=u'SNSなどのURL')
    name = models.CharField(verbose_name=u'名前', max_length=255)
    url = models.URLField(verbose_name=u'URL', )

    panels = [
        FieldPanel('name'),
        FieldPanel('url'),
    ]

    graphql_fields = [GraphQLField('name'), GraphQLField('url')]
Exemple #6
0
class AuthorPageAmazonWishList(GraphQLEnabledModel, Orderable):
    Author = ParentalKey(AuthorPage,
                         on_delete=models.CASCADE,
                         related_name='amazon_wish_list_links',
                         verbose_name=u'AmazonのほしいものリストのURL')
    name = models.CharField(verbose_name=u'名前', max_length=255)
    url = models.URLField(verbose_name=u'URL', )

    panels = [
        FieldPanel('name'),
        FieldPanel('url'),
    ]

    graphql_fields = [GraphQLField('name'), GraphQLField('url')]
    def resolve_model_fields_for(self, model):
        """
        Discover GraphQL fields definition for a particular model.
        """
        assert model not in self._model_fields, (
            f"{model}'s fields have been already registered."
        )
        raw_fields = tuple(getattr(model, 'graphql_fields', tuple()))

        fields = collections.OrderedDict()

        for raw_field in raw_fields:
            if not isinstance(raw_field, GraphQLField):
                raise ValueError(
                    'Field must be a GraphQLField instance, not '
                    f'{type(raw_field)}'
                )
            assert raw_field.name not in fields, (
                f'{raw_field.name} for {model} is duplicated.'
            )
            fields[raw_field.name] = raw_field

        # Add an ID field if it is not defined.
        if not any(
            f for f in fields.keys() if f in (model._meta.pk.name, 'pk')
        ):
            fields[model._meta.pk.name] = GraphQLField(model._meta.pk.name)

        self._model_fields[model] = tuple(fields.values())
Exemple #8
0
class GalleryPage(GraphQLEnabledModel, Page):
    """
    This is a page to list locations from the selected Collection. We use a Q
    object to list any Collection created (/admin/collections/) even if they
    contain no items. In this demo we use it for a GalleryPage,
    and is intended to show the extensibility of this aspect of Wagtail
    """

    introduction = models.TextField(help_text='Text to describe the page',
                                    blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='Landscape mode only; horizontal width between 1000px and '
        '3000px.')
    body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
    collection = models.ForeignKey(
        Collection,
        limit_choices_to=~models.Q(name__in=['Root']),
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        help_text='Select the image collection for this gallery.')

    content_panels = Page.content_panels + [
        FieldPanel('introduction', classname="full"),
        StreamFieldPanel('body'),
        ImageChooserPanel('image'),
        FieldPanel('collection'),
    ]

    # Defining what content type can sit under the parent. Since it's a blank
    # array no subpage can be added
    subpage_types = []

    graphql_fields = [
        GraphQLField('introduction'),
        GraphQLField('body'),
        GraphQLField('image'),
        GraphQLField('collection'),
    ]
Exemple #9
0
class CharacterPage(GraphQLEnabledModel, Page):
    """A page of character list."""
    nickname = models.CharField(u"称号", max_length=15, null=True)
    name = models.CharField(u"名前", max_length=35, null=True)
    character_id = models.CharField(u"キャラクターID", max_length=6, null=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'画像',
    )
    description = models.CharField(u'概要', max_length=255, null=True)
    introduction = MarkdownField(verbose_name=u"説明", null=True)
    game_name = models.CharField(u"登録されているゲーム", max_length=20, null=True)
    character_page_url = models.CharField(u"キャラクターのページ", max_length=255, null=True)

    content_panels = Page.content_panels + [
        FieldPanel('nickname'),
        FieldPanel('name'),
        FieldPanel('character_id'),
        ImageChooserPanel('image'),
        FieldPanel('description'),
        MarkdownPanel('introduction'),
        FieldPanel('game_name'),
        FieldPanel('character_page_url'),
    ]

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

    graphql_fields = [
        GraphQLField("nickname"),
        GraphQLField("name"),
        GraphQLField("character_id"),
        GraphQLField("image"),
        GraphQLField("description"),
        GraphQLField("introduction"),
        GraphQLField("game_name"),
        GraphQLField("character_page_url"),
    ]

    def clean(self):
        super().clean()
        new_title = '%s(%s)' % (self.name, self.character_id)
        new_slug = '%s' % self.character_id
        self.title = new_title
        self.slug = slugify(new_slug)
class SitePolicyPage(GraphQLEnabledModel, Page):
    body = MarkdownField(verbose_name=u'本文', blank=True)

    content_panels = Page.content_panels + [
        MarkdownPanel("body", classname="full"),
    ]

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

    graphql_fields = [
        GraphQLField('body'),
    ]
class BookIndexPage(GraphQLEnabledModel, Page):
    intro = MarkdownField(null=True)

    def child_pages(self):
        return BookPage.objects.live().child_of(self)

    content_panels = Page.content_panels + [
        MarkdownPanel('intro', classname='full')
    ]

    graphql_fields = [
        GraphQLField('intro'),
    ]

    subpage_types = ['BookPage']
class HappinessPage(GraphQLEnabledModel, Page):

    date = models.DateField(u"投稿日")
    first = models.CharField(u"一つ目のよいこと", max_length=25)
    second = models.CharField(u"二つ目のよいこと", max_length=25)
    third = models.CharField(u"三つ目のよいこと", max_length=25)
    feed_image = models.ForeignKey('wagtailimages.Image',
                                   null=True,
                                   blank=True,
                                   on_delete=models.SET_NULL,
                                   related_name='+',
                                   verbose_name=u'画像')
    author = models.ForeignKey(
        'author.AuthorPage',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'著者',
    )

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('first'),
        FieldPanel('second'),
        FieldPanel('third'),
        PageChooserPanel('author', 'author.AuthorPage'),
        ImageChooserPanel('feed_image'),
    ]

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

    graphql_fields = [
        GraphQLField('author'),
        GraphQLField('date'),
        GraphQLField('slug'),
        GraphQLField('first'),
        GraphQLField('second'),
        GraphQLField('third'),
        GraphQLField('feed_image')
    ]

    def clean(self):
        super().clean()
        new_title = '%s の3つのよいこと' % self.date
        new_slug = '3 good things in %s' % self.date
        self.title = new_title
        self.slug = slugify(new_slug)
Exemple #13
0
class ArticlePage(GraphQLEnabledModel, Page):
    """Article Pages"""

    date = models.DateTimeField(u"投稿日")
    tags = ClusterTaggableManager(verbose_name=u'タグ',
                                  through=ArticlePageTag,
                                  blank=True)
    body = MarkdownField(verbose_name=u'本文', blank=True)
    feed_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'画像',
    )
    author = models.ForeignKey(
        'author.AuthorPage',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'著者',
    )

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('tags'),
        MarkdownPanel("body", classname="full"),
        ImageChooserPanel('feed_image'),
        PageChooserPanel('author', 'author.AuthorPage'),
        InlinePanel('related_links', label=u'関連リンク'),
    ]

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

    graphql_fields = [
        GraphQLField('author'),
        GraphQLField('date'),
        GraphQLField('tags'),
        GraphQLField('slug'),
        GraphQLField('body'),
        GraphQLField('feed_image'),
        GraphQLField('related_links')
    ]
class BookPage(GraphQLEnabledModel, Page):

    price = models.IntegerField()
    published_date = models.DateField()
    published_event = models.CharField(max_length=50)
    description = MarkdownField(verbose_name=u'説明')
    booth_url = models.URLField(max_length=255, null=True)
    bookwalker_url = models.URLField(max_length=255, null=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )

    content_panels = Page.content_panels + [
        FieldPanel('price'),
        FieldPanel('published_date'),
        FieldPanel('published_event'),
        MarkdownPanel('description'),
        FieldPanel('booth_url'),
        FieldPanel('bookwalker_url'),
        ImageChooserPanel('image'),
    ]

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

    graphql_fields = [
        GraphQLField('price'),
        GraphQLField('published_date'),
        GraphQLField('published_event'),
        GraphQLField('description'),
        GraphQLField('booth_url'),
        GraphQLField('bookwalker_url'),
        GraphQLField('image'),
        GraphQLField('slug')
    ]
class PortfolioPage(GraphQLEnabledModel, Page):
    update_date = models.DateField(u"更新日")
    tech = ClusterTaggableManager(verbose_name=u'経験または興味のある技術',
                                  through=PortfolioPageTechnology,
                                  blank=True)
    github_url = models.URLField(u'GitHubの個人ページ', max_length=200, blank=True)
    author = models.ForeignKey(
        'author.AuthorPage',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'著者',
    )

    content_panels = Page.content_panels + [
        FieldPanel('update_date'),
        FieldPanel('tech'),
        FieldPanel('github_url'),
        InlinePanel('job_career', label=u'職務経歴'),
        InlinePanel('related_links', label=u'関連リンク'),
        PageChooserPanel('author', 'author.AuthorPage'),
    ]

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

    graphql_fields = [
        GraphQLField('author'),
        GraphQLField('update_date'),
        GraphQLField('tech'),
        GraphQLField('github_url'),
        GraphQLField('job_career'),
        GraphQLField('related_links'),
        GraphQLField('slug'),
    ]

    def clean(self):
        super().clean()
        new_title = '%s のポートフォリオ' % self.author.name
        new_slug = self.author.slug
        self.title = new_title
        self.slug = slugify(new_slug)
Exemple #16
0
class FooterText(GraphQLEnabledModel, models.Model):
    """
    This provides editable text for the site footer. Again it uses the decorator
    `register_snippet` to allow it to be accessible via the admin. It is made
    accessible on the template via a template tag defined in base/templatetags/
    navigation_tags.py
    """
    body = RichTextField()

    panels = [
        FieldPanel('body'),
    ]

    graphql_fields = [
        GraphQLField('body'),
    ]

    def __str__(self):
        return "Footer text"

    class Meta:
        verbose_name_plural = 'Footer Text'
Exemple #17
0
class BlogIndexPage(GraphQLEnabledModel, RoutablePageMixin, Page):
    """
    Index page for blogs.
    We need to alter the page model's context to return the child page objects,
    the BlogPage objects, so that it works as an index page

    RoutablePageMixin is used to allow for a custom sub-URL for the tag views
    defined above.
    """
    introduction = models.TextField(help_text='Text to describe the page',
                                    blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')

    graphql_fields = [
        GraphQLField('introduction'),
        GraphQLField('image'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
    ]

    # Speficies that only BlogPage objects can live under this index page
    subpage_types = ['BlogPage']

    # Defines a method to access the children of the page (e.g. BlogPage
    # objects). On the demo site we use this on the HomePage
    def children(self):
        return self.get_children().specific().live()

    # Overrides the context to list all child items, that are live, by the
    # date that they were published
    # http://docs.wagtail.io/en/latest/getting_started/tutorial.html#overriding-context
    def get_context(self, request):
        context = super(BlogIndexPage, self).get_context(request)
        context['posts'] = BlogPage.objects.descendant_of(
            self).live().order_by('-date_published')
        return context

    # This defines a Custom view that utilizes Tags. This view will return all
    # related BlogPages for a given Tag or redirect back to the BlogIndexPage.
    # More information on RoutablePages is at
    # http://docs.wagtail.io/en/latest/reference/contrib/routablepage.html
    @route('^tags/$', name='tag_archive')
    @route('^tags/([\w-]+)/$', name='tag_archive')
    def tag_archive(self, request, tag=None):

        try:
            tag = Tag.objects.get(slug=tag)
        except Tag.DoesNotExist:
            if tag:
                msg = 'There are no blog posts tagged with "{}"'.format(tag)
                messages.add_message(request, messages.INFO, msg)
            return redirect(self.url)

        posts = self.get_posts(tag=tag)
        context = {'tag': tag, 'posts': posts}
        return render(request, 'blog/blog_index_page.html', context)

    def serve_preview(self, request, mode_name):
        # Needed for previews to work
        return self.serve(request)

    # Returns the child BlogPage objects for this BlogPageIndex.
    # If a tag is used then it will filter the posts by tag.
    def get_posts(self, tag=None):
        posts = BlogPage.objects.live().descendant_of(self)
        if tag:
            posts = posts.filter(tags=tag)
        return posts

    # Returns the list of Tags for all child posts of this BlogPage.
    def get_child_tags(self):
        tags = []
        for post in self.get_posts():
            # Not tags.append() because we don't want a list of lists
            tags += post.get_tags
        tags = sorted(set(tags))
        return tags
Exemple #18
0
class BlogPage(GraphQLEnabledModel, Page):
    """
    A Blog Page

    We access the People object with an inline panel that references the
    ParentalKey's related_name in BlogPeopleRelationship. More docs:
    http://docs.wagtail.io/en/latest/topics/pages.html#inline-models
    """
    introduction = models.TextField(help_text='Text to describe the page',
                                    blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=
        'Landscape mode only; horizontal width between 1000px and 3000px.')
    body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
    subtitle = models.CharField(blank=True, max_length=255)
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
    date_published = models.DateField("Date article published",
                                      blank=True,
                                      null=True)

    content_panels = Page.content_panels + [
        FieldPanel('subtitle', classname="full"),
        FieldPanel('introduction', classname="full"),
        ImageChooserPanel('image'),
        StreamFieldPanel('body'),
        FieldPanel('date_published'),
        InlinePanel('blog_person_relationship',
                    label="Author(s)",
                    panels=None,
                    min_num=1),
        FieldPanel('tags'),
    ]

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

    graphql_fields = [
        GraphQLField('introduction'),
        GraphQLField('image'),
        GraphQLField('body'),
        GraphQLField('tags'),
        GraphQLField('subtitle'),
        GraphQLField('date_published'),
        GraphQLField('authors',
                     graphql_type=graphene.Field(
                         lazy_queryset_list('base.People')),
                     resolve_func=lambda self, info, **kwargs: self.authors()),
    ]

    def authors(self):
        """
        Returns the BlogPage's related People. Again note that we are using
        the ParentalKey's related_name from the BlogPeopleRelationship model
        to access these objects. This allows us to access the People objects
        with a loop on the template. If we tried to access the blog_person_
        relationship directly we'd print `blog.BlogPeopleRelationship.None`
        """
        authors = [n.people for n in self.blog_person_relationship.all()]

        return authors

    @property
    def get_tags(self):
        """
        Similar to the authors function above we're returning all the tags that
        are related to the blog post into a list we can access on the template.
        We're additionally adding a URL to access BlogPage objects with that tag
        """
        tags = self.tags.all()
        for tag in tags:
            tag.url = '/' + '/'.join(
                s.strip('/')
                for s in [self.get_parent().url, 'tags', tag.slug])
        return tags

    # Specifies parent to BlogPage as being BlogIndexPages
    parent_page_types = ['BlogIndexPage']

    # Specifies what content types can exist as children of BlogPage.
    # Empty list means that no child content types are allowed.
    subpage_types = []
Exemple #19
0
class AuthorPage(GraphQLEnabledModel, Page):
    profile = MarkdownField(verbose_name=u'プロフィール')
    nickname = models.CharField(verbose_name=u'ニックネーム',
                                max_length=25,
                                null=True,
                                blank=True)
    first_name = models.CharField(verbose_name=u'名',
                                  max_length=10,
                                  null=True,
                                  blank=True)
    middle_name = models.CharField(verbose_name=u'ミドルネーム',
                                   max_length=10,
                                   null=True,
                                   blank=True)
    family_name = models.CharField(verbose_name=u'姓',
                                   max_length=10,
                                   null=True,
                                   blank=True)
    name = models.CharField(verbose_name=u'表示名',
                            max_length=80,
                            null=True,
                            blank=True)
    is_surname_first = models.BooleanField(verbose_name=u'姓が先の表記',
                                           null=True,
                                           blank=True)
    use_nickname = models.BooleanField(verbose_name=u'ニックネームの使用',
                                       null=True,
                                       blank=True)
    portrait = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'画像',
    )
    interest = ClusterTaggableManager(verbose_name=u'興味を持っていること',
                                      through=AuthorPageInterest,
                                      blank=True)

    content_panels = Page.content_panels + [
        MarkdownPanel('profile'),
        ImageChooserPanel('portrait'),
        FieldPanel('interest'),
        FieldPanel('nickname'),
        FieldPanel('first_name'),
        FieldPanel('middle_name'),
        FieldPanel('family_name'),
        FieldPanel('name'),
        FieldPanel('is_surname_first'),
        FieldPanel('use_nickname'),
        InlinePanel('portfolio_links', label=u'ポートフォリオ'),
        InlinePanel('amazon_wish_list_links', label=u'Amazonのほしいものリスト'),
        InlinePanel('sns_links', label=u'SNSなどのリンク'),
    ]

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

    graphql_fields = [
        GraphQLField('name'),
        GraphQLField('profile'),
        GraphQLField('portrait'),
        GraphQLField('interest'),
        GraphQLField('portfolio_links'),
        GraphQLField('amazon_wish_list_links'),
        GraphQLField('sns_links'),
    ]

    def clean(self):
        """Rename title when posted."""
        if self.nickname is not None and self.use_nickname is True:
            self.name = self.nickname
        elif self.is_surname_first is True:
            if self.middle_name is None:
                self.name = self.family_name + u' ' + self.first_name
            else:
                self.name = (self.family_name + u' ' + self.middle_name +
                             u' ' + self.first_name)
        else:
            if self.middle_name is None:
                self.name = self.first_name + u' ' + self.family_name
            else:
                self.name = (self.first_name + u' ' + self.middle_name + u' ' +
                             self.family_name)

        self.title = '%s のプロフィール' % self.name
Exemple #20
0
class HomePage(GraphQLEnabledModel, Page):
    """
    The Home Page. This looks slightly more complicated than it is. You can
    see if you visit your site and edit the homepage that it is split between
    a:
    - Hero area
    - Body area
    - A promotional area
    - Moveable featured site sections
    """

    # Hero section of HomePage
    image = models.ForeignKey('wagtailimages.Image',
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name='+',
                              help_text='Homepage image')
    hero_text = models.CharField(
        max_length=255, help_text='Write an introduction for the bakery')
    hero_cta = models.CharField(verbose_name='Hero CTA',
                                max_length=255,
                                help_text='Text to display on Call to Action')
    hero_cta_link = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Hero CTA link',
        help_text='Choose a page to link to for the Call to Action')

    # Body section of the HomePage
    body = StreamField(BaseStreamBlock(),
                       verbose_name="Home content block",
                       blank=True)

    # Promo section of the HomePage
    promo_image = models.ForeignKey('wagtailimages.Image',
                                    null=True,
                                    blank=True,
                                    on_delete=models.SET_NULL,
                                    related_name='+',
                                    help_text='Promo image')
    promo_title = models.CharField(
        null=True,
        blank=True,
        max_length=255,
        help_text='Title to display above the promo copy')
    promo_text = RichTextField(null=True,
                               blank=True,
                               help_text='Write some promotional copy')

    # Featured sections on the HomePage
    # You will see on templates/base/home_page.html that these are treated
    # in different ways, and displayed in different areas of the page.
    # Each list their children items that we access via the children function
    # that we define on the individual Page models e.g. BlogIndexPage
    featured_section_1_title = models.CharField(
        null=True,
        blank=True,
        max_length=255,
        help_text='Title to display above the promo copy')
    featured_section_1 = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='First featured section for the homepage. Will display up to '
        'three child items.',
        verbose_name='Featured section 1')

    featured_section_2_title = models.CharField(
        null=True,
        blank=True,
        max_length=255,
        help_text='Title to display above the promo copy')
    featured_section_2 = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='Second featured section for the homepage. Will display up to '
        'three child items.',
        verbose_name='Featured section 2')

    featured_section_3_title = models.CharField(
        null=True,
        blank=True,
        max_length=255,
        help_text='Title to display above the promo copy')
    featured_section_3 = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='Third featured section for the homepage. Will display up to '
        'six child items.',
        verbose_name='Featured section 3')

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            ImageChooserPanel('image'),
            FieldPanel('hero_text', classname="full"),
            MultiFieldPanel([
                FieldPanel('hero_cta'),
                PageChooserPanel('hero_cta_link'),
            ])
        ],
                        heading="Hero section"),
        MultiFieldPanel([
            ImageChooserPanel('promo_image'),
            FieldPanel('promo_title'),
            FieldPanel('promo_text'),
        ],
                        heading="Promo section"),
        StreamFieldPanel('body'),
        MultiFieldPanel([
            MultiFieldPanel([
                FieldPanel('featured_section_1_title'),
                PageChooserPanel('featured_section_1'),
            ]),
            MultiFieldPanel([
                FieldPanel('featured_section_2_title'),
                PageChooserPanel('featured_section_2'),
            ]),
            MultiFieldPanel([
                FieldPanel('featured_section_3_title'),
                PageChooserPanel('featured_section_3'),
            ])
        ],
                        heading="Featured homepage sections",
                        classname="collapsible")
    ]

    graphql_fields = [
        GraphQLField('image'),
        GraphQLField('hero_text'),
        GraphQLField('hero_cta'),
        GraphQLField('hero_cta_link'),
        GraphQLField('promo_image'),
        GraphQLField('promo_title'),
        GraphQLField('promo_text'),
        GraphQLField('body'),
        GraphQLField('featured_section_1_title'),
        GraphQLField('featured_section_1'),
        GraphQLField('featured_section_2_title'),
        GraphQLField('featured_section_2'),
        GraphQLField('featured_section_3_title'),
        GraphQLField('featured_section_3'),
    ]

    def __str__(self):
        return self.title