Wagtailチュートリアル 11 トップページに表示させよう

#Wagtailチュートリアル 11
<=[10 カードを表示しよう](https://qiita.com/tagawahirotaka/items/9fef73345fe2c88486d2)
=>[12 DB Browserを使おう](https://qiita.com/tagawahirotaka/items/aa0bbc341ec73ea5fcf5)

##トップページに表示させよう


25

```python:streams/blocks.py

from wagtail.core import blocks

# 23 追加
from wagtail.images.blocks import ImageChooserBlock


# 18 TitleAndTextBlockを定義
class TitleAndTextBlock(blocks.StructBlock):

    title = blocks.CharBlock(required=True, help_text="Add your title")
    text = blocks.TextBlock(required=True, help_text="Add additional text")

    class Meta:
        template = "streams/title_and_text_block.html" # 18 テンプレートの場所
        icon = "edit" # 18 admin画面のアイコン
        label = "Title & Text" # 18 admin画面の表示

# 23 追加
class CardBlock(blocks.StructBlock):

    title = blocks.CharBlock(required=True, help_text="Add your title")

    cards = blocks.ListBlock(
        blocks.StructBlock(
            [
                ("image",ImageChooserBlock(required=True)),
                ("title",blocks.CharBlock(required=True, max_length=40)),
                ("text",blocks.TextBlock(required=True, max_length=200)),
                ("button_page",blocks.PageChooserBlock(required=False)),
                ("button_url",blocks.URLBlock(required=False,help_text="If the button page above is selected, that will be used first.")),
            ]
        )
    )

    class Meta:
        template = "streams/card_block.html"
        icon = "placeholder"
        label = "Poke Cards"



# 20 追加
class RichtextBlock(blocks.RichTextBlock):

    class Meta:
        template = "streams/richtext_block.html"
        icon = "doc-full"
        label = "Full RichText"

# 22 追加
class SimpleRichtextBlock(blocks.RichTextBlock):

    # 22 field_block.pyからオーバーライド
    def __init__(self, required=True, help_text=None, editor='default', features=None, **kwargs):
        super().__init__(**kwargs)
        self.features = [
            "bold",
            "italic",
            "link",
        ]


    class Meta:
        template = "streams/richtext_block.html"
        icon = "edit"
        label = "Simple RichText"

# 25 追加
class CTABlock(blocks.StructBlock):

    title = blocks.CharBlock(required=True, max_length=60)
    text = blocks.RichTextBlock(required=True, features=["bold", "italic"])
    button_page = blocks.PageChooserBlock(required=False)
    button_url = blocks.URLBlock(required=False)
    button_text = blocks.CharBlock(required=True, default='Learn More', max_length=40)

    class Meta:
        template = "streams/cta_block.html"
        icon = "placeholder"
        label = "Call to Action"
```

25


```python:flex/models.py

from django.db import models

# 16 18 モデルに必要なものをインポート
from wagtail.admin.edit_handlers import FieldPanel,StreamFieldPanel
from wagtail.core.models import Page
# 18 モデルに必要なものをインポート
from wagtail.core.fields import StreamField

from streams import blocks # 18 streams/blocks.pyをインポート

# 16 モデルを定義
class FlexPage(Page):

    template = "flex/flex_page.html"

    # 18 追加
    content = StreamField(
        [
            ("title_and_text", blocks.TitleAndTextBlock()),# 18 strams/blocks.pyに定義されている
            ("full_richtext", blocks.RichtextBlock()),# 20 追加
            ("simple_richtext", blocks.SimpleRichtextBlock()),# 22 追加
            ("cards",blocks.CardBlock()), # 23 追加
            ("cta",blocks.CTABlock()) # 25 追加
        ],
        null=True,
        blank=True,
    )

    subtitle = models.CharField(max_length=100, null=True, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("subtitle"),
        StreamFieldPanel("content"),
    ]

    class Meta:
        verbose_name = "Flex Page"
        verbose_name_plural = "Flex Pages"
```

26

```html:wagtailtutrial/templates/streams/cta_block.html

{# 26 CTABlockを表示 #}

<div class="container">
    <div class="row">
        <div class="col-lg-6">
            <h1>{{self.title}}</h1>
            {{ self.text}}

            {% if self.button_page%}
                <a href="{{ self.button_page.url}}">{{self.button_text}}</a>
            {% elif self.button_url %}
                <a href="{{ self.button_url}}">
            {% endif %}
        </div>
    </div>
</div>
```

27

```python:home/models.py

from django.db import models #⓪ モデルをインポート

from wagtail.core.models import Page #⓪ページをインポート
from wagtail.core.fields import RichTextField #⑧ RichTextFieldをインポート
from wagtail.admin.edit_handlers import FieldPanel,PageChooserPanel #④ FieldPanelをインポート 11 必要なものをインポート
from wagtail.images.edit_handlers import ImageChooserPanel #11 必要なものをインポート
# 27 インポート
from wagtail.admin.edit_handlers import FieldPanel,StreamFieldPanel
from wagtail.core.fields import StreamField
from streams import blocks 


class HomePage(Page):#⓪ページを引数に

    templates = "home/home_page.html" #① wagtailtutorial/templates/home/homepage.html

    max_count = 1 #⑥ ADD CHILD PAGEを制限

    banner_title = models.CharField(max_length=100, blank=False, null=True) #③ banner_titleを定義

    banner_subtitle = RichTextField(features=["bold", "italic"]) #⑧banner_subtitleを定義

    banner_image = models.ForeignKey( #⑨banner_imageを定義
        "wagtailimages.Image",
        null=True,
        blank=False,
        on_delete=models.SET_NULL,
        related_name="+"
    )

    banner_cta = models.ForeignKey( #⑩banner_ctaを定義
        "wagtailcore.Page",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+"
   )
   
   # 27 flex/models.py のcontentをコピーして必要なctaだけ残す
    content = StreamField(
        [
            ("cta", blocks.CTABlock()),
        ],
        null=True,
        blank=True,
    )

    content_panels = Page.content_panels + [ #④ 11 admin画面に追加
        FieldPanel("banner_title"),
        FieldPanel("banner_subtitle"),
        ImageChooserPanel("banner_image"),
        PageChooserPanel("banner_cta"),
        StreamFieldPanel("content"), # 27 flex/models.py のcontentをコピー
    ]

    class Meta:

        #verbose_name = "OH HELLO WORLD" ⑦ ADD CHILD PAGEでの表記
        verbose_name = "Home Page"
        verbose_name_plural = "Home Pages"
```

28

```wagtailtutrial/tamplates/home/home_page.html

{# 13 bootstrapを読み込む#}
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}

{% block content %} {#② base.htmlから引っ張り出す#}

  {% image self.banner_image fill-900x400 as img %}{# 13 画像を読み込む#}

{# 13 bootstrapからコピペしてmodels.pyで定義したやつを埋める #}
 <div class="jumbotron" style="background-image: url('{{ img.url }}'); background-size: contain; color: #fff !important">
        <h1 class="display-4">{{ self.banner_title }}</h1>
        <div class="lead">{{ self.banner_subtitle|richtext }}</div>
        {% if self.banner_cta %}
            <a class="btn btn-primary btn-lg" href="#" role="button">@todo</a>
        {% endif %}
</div>

{# 28 追加 wagtailtutrial/templates/flex/flex_page.htmlからコピー#}
{% for block in page.content %}
      {% include_block block%} {# 19 streams/block.pyのcontentをループする#}
   {% endfor %}


{% endblock %}
```

25
<img width="1440" alt="スクリーンショット 2019-08-27 18.44.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/f1e62cb9-864e-f3cb-39eb-7d803e8f963e.png">

26
<img width="1440" alt="スクリーンショット 2019-08-27 18.55.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/f8899c54-ed91-afa2-5a12-b6d7575112b4.png">

27
<img width="1440" alt="スクリーンショット 2019-08-27 19.20.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/4e3408dd-43f6-456c-9173-b5ec990d5355.png">

28
<img width="1440" alt="スクリーンショット 2019-08-27 19.25.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/d8f514e5-cb26-3853-4e43-0417df5ae7d6.png">