Wagtailでページの親子関係を制限する[parent_page_types / subpage_types]

Wagtailでページ階層の親子関係を制限する方法を紹介します。

Wagtailでページの親子関係を制限する[parent_page_types / subpage_types]

Wagtailでは、役割ごとにページのタイプを設定し、新規のページを追加する際にはまずページタイプを選択してからコンテンツを追加していきます。

たとえば、記事一覧ページと記事ページの構成は異なるため、ArticleListingPageとArticleDetailPageのような形で別のページタイプを作成し、それぞれにテンプレートや与えるデータの設定をしていくことになります。その後、トップページの下にArticleListingPageのコンテンツを追加して記事一覧ページとし、そのさらに下の階層にArticleDetailPageのコンテンツである記事ページを複数追加していくイメージです。

記事の親子関係_正解

この仕組みにより、同じ役割を持ったページの構成をテンプレート化することができ、効率的なコンテンツの追加ができるようになります。

一方でWagtailのデフォルトの設定では、あらゆるページタイプがどのページ階層にも追加できるようになっています。つまり先ほどの例だと、記事ページを作成した後に、その下の階層にさらに記事ページや記事一覧ページを追加することもできてしまいます。

記事の親子関係_不正解

これは望ましくない操作であり、メディア運営でもミスにつながる可能性があります。本来は、『記事ページ直下の階層にはページを追加できない』といった制限を設定できると便利です。

この問題を解決するために、Wagtailにはページの親子関係を制限する仕組みがあります。

parent_page_typesとsubpage_typesで制限をかける

ページの親子関係は簡単に制限できます。WagtailのPageタイプの実装にparent_page_typessubpage_typesをリストの形で指定するだけです。

  • parent_page_types: リストで指定したページタイプ直下の階層にのみページを追加できる
  • subpage_types: リストで指定したページタイプのみを直下の階層に追加できる

リストにはapp_name.ModelNameの文字列型を指定します。

以下の例では、記事一覧ページと記事ページの関係性を制限しています。

# articles/models.py

class ArticleListingPage(Page):
    """記事一覧ページ"""
    ...
    subpage_types = ['articles.ArticleDetailPage'] # 記事ページのみを下の階層に追加できる


class ArticleDetailPage(Page):
    """記事ページ"""
    ...
    parent_page_types = ['articles.ArticleListingPage'] # 記事一覧ページの直下にのみ記事ページを追加できる
    subpage_types = [] # 記事ページの直下の階層にはどんなページも追加できないようにする

お問い合わせページや利用規約など、トップページ直下にのみ追加できるようにしたい場合は以下のように記述します。

# contact/models.py

class ContactPage(Page):
    """お問い合わせページ"""
    ...
    parent_page_types = ['home.HomePage'] # トップページの直下にのみお問い合わせページを追加できる
    subpage_types = [] # お問い合わせページの直下の階層にはどんなページも追加できないようにする

ページ階層のミスを防ぐためにも、この制限は絶対に指定しておくべきです。管理画面上でも、不要なページへのページ追加のリンクが減るので操作がしやすくなります。

メディア運営を考えると、どんなページ階層にも追加できるようなページタイプはほとんど存在しないはずなので、メディアの構成をしっかりと考えるようにしましょう。