🦜

Wagtailブログを試してみた。

2023/04/16に公開

Wagtailブログを試してみた

Djangoでブログを作るのは形だけなら意外に簡単ですが、操作性やデザイン性を考えれば、全くWordPressに勝てない・・・しかし、バグが多いWordPressを使い続けるのももう嫌だ・・・と調べていたところ、Djangoと同じPythonで作られた(というか、Djangoをベースに作られらている)「Wagtaile」というCMSを発見しました。

Youtubeでは絶賛されて(?)いますが、英語の解説動画しかないので、理解するのにかなりしんどいので、こちらの記事にまとめておきます。

おすすめ動画

Wagitalって何?

Wagtailは、Pythonで作られたオープンソースのCMS(コンテンツ管理システム)で、ブログやウェブサイトの構築に便利です。Wagtailを使ってブログを作りたい場合は、以下の手順に従って導入することができます。

基本的には、公式サイトの通りに試しています。
というわけで、詳細は公式サイトのチュートリアルをご覧ください。

Pythonのインストール

WagtailはPythonで作られているため、まずはPythonをインストールする必要があります。Pythonの公式サイトから、最新バージョンをダウンロードしてインストールしてください。

仮想環境の作成

(※仮想環境を作らなくても動きますが、バグのチェックや、複数人開発を考えれば、仮想環境を構築しておいた方がいいです)
Pythonの仮想環境を作成することで、Wagtailの導入をより簡単にすることができます。仮想環境を作成するには、以下のコマンドを実行します

On Windows (cmd.exe):

py -m venv mysite\env
mysite\env\Scripts\activate.bat
or:
mysite\env\Scripts\activate

On GNU/Linux or MacOS (bash):

python -m venv mysite/env
source mysite/env/bin/activate

Wagtailのインストール

Wagtailをインストールするには、以下のコマンドを実行します。

pip install wagtail

プロジェクトを作る

プロジェクトとアプリケーションの概念は、Djangoに慣れている方なら、そのまんまです。
Djangoに慣れていない方は、「そんなものを作るんだ。へぇ~」ぐらいで流してもいい気がします。ただし、理解が浅いまま進めば後でurl.pyviews.pyを編集する際に、プロジェクト側のPYファイルを編集するのか、アプリケーション側のファイルを編集すればいいのか混乱するかもしれないので、いったんDjangoでブログを作ってからWagtaileに触れた方がいいかもしれません。

wagtail start mysite mysite

プロジェクトの依存関係をインストールする

requirements.txtファイルには、プロジェクトを実行するために必要なすべての依存関係が含まれています。

cd mysite
pip install -r requirements.txt

データベースを作成する

自動でSQliteが設定されます。
新しく設定したデータベースの初期値が空白だったり、model.pyで組んだモデルがマイグレートしたデータベースと噛み合わなかったりと、色々な理由でエラーが発生します。
そんな時は、「DB Browser for SQLite」(公式サイト)を使いましょう。ダイレクトにデータベースを操作できます。

python manage.py migrate

管理者(スーパーユーザー)を作成する。

これは、Djangoの機能ですね。BASH(もしくは、コマンドライン)上で管理者権限を作成します。メールアドレスは空欄でも作れます。

python manage.py createsuperuser

仮想サーバーを立ち上げる

下のコマンドを走らせば、下の画像のような画面がブラウザ上にでてきます。
すべてうまくいった場合、http://127.0.0.1:8000にウェルカムページが表示されます。

python manage.py runserver

ちなみに、別なアプリケーションでポート8000を使っているときは、

python manage.py runserver 8001

などで、別なポート番号で開きましょう。

http://127.0.0.1:8000/adminで管理画面を開いてみましょう。

HomePageモデルを編集する

home/models.pyファイルを編集して、HomePageモデルを作ります。

home/models.py
from django.db import models

from wagtail.models import Page
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel


class HomePage(Page):
    body = RichTextField(blank=True) 

    content_panels = Page.content_panels + [
        FieldPanel('body'),
    ]

class HomePage(Page):でadmin画面からHomePageを編集できるようになります。
body = RichTextField(blank=True)でリッチテキストエディタ(貧弱)が挿入できるようになります。
このリッチテキストブロックだけだと、デザイン性が全く足りないので、例えばコード挿入をしたければ、別なブロックを設定する必要があります。

さて、models.pyを編集したら、必ずマイグレーションを都度行いましょう。

python manage.py makemigrations migrate

ホームページ画面を編集する

HomePageモデルを作れば、コンテンツを管理画面から編集できるようになりますが、外側、つまりデザイン部分はHTMLで設定する必要があります。

home/templates/home/home_page.htmlというファイル名でHTMLファイルを作って下さい。
ディレクトリが無いときは、ディレクトリから作って下さい。

home/templates/home/home_page.html
{% extends "base.html" %}

{% load wagtailcore_tags %}

{% block body_class %}template-homepage{% endblock %}

{% block content %}
    <p><b>Welcome</b> to our new site!</p>
    {{ page.body|richtext }}
{% endblock %}

このHTMLファイルを作ると、http://127.0.0.1:8000に、真っ白な画面が出てきます。

みぎしたのWagtail君(セキレイ)は、管理者にしか見えない妖精です。クリックすれば管理画面への移動等ができます。

ようやくブログを作り始める

さきほどは、プロジェクトを作りましたが、今度はアプリケーションを作ります。

python manage.py startapp blog

これでblogアプリケーションができました。

setting/base.py(昔のバージョンならsettings.py)の中に、INSTALLED_APPSと書かれているところを見つけて、'blog',という一文を追加して下さい。
(※アプリケーションを作ったり、ライブラリと追加した際は、INSTALLED_APPSへの登録が必須です)
ついでに、basy.pyの中のLANGAGEを"ja"に、TIME_ZONEを"Asia/Tokyo"に変えておくと、管理画面が日本語、日本時間対応になります。

ブログのモデルを作る

さきほどは、homeディレクトリ内のmodels.pyを編集しましたが、次はblogディレクトリ内のmodels.pyを編集します。(慣れないうちは混乱します)

home/models.py
from wagtail.models import Page
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel


class BlogIndexPage(Page):
    intro = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('intro')
    ]

モデルを編集したら、マイグレーションは忘れずに。

python manage.py makemigrations
python manage.py migrate

ブログのトップページを作る

blogアプリケーションの中に、templatesフォルダを作り、更にその中にblogフォルダを作ります。
つまり、mysite/blog/templates/blogフォルダの中にblog_index_page.htmlというHTMLファイルを作成しましょう。

blog_index_page.html
{% extends "base.html" %}

{% load wagtailcore_tags %}

{% block body_class %}template-blogindexpage{% endblock %}

{% block content %}
    <h1>{{ page.title }}</h1>

    <div class="intro">{{ page.intro|richtext }}</div>

    {% for post in page.get_children %}
        <h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
        {{ post.specific.intro }}
        {{ post.specific.body|richtext }}
    {% endfor %}

{% endblock %}

http://127.0.0.1:8000/blogへアクセスすればこのHTMLが見れます。

ブログ投稿用のモデルを作る

さきほどは、HomePageを編集するモデルを作りましたが、次はブログを投稿するためのモデルを作ります。

blog/models.py
from django.db import models

from wagtail.models import Page
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel
from wagtail.search import index


class BlogIndexPage(Page):
    intro = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('intro')
    ]

class BlogPage(Page):
    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)
    body = RichTextField(blank=True)

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

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('intro'),
        FieldPanel('body'),
    ]

モデルを編集したら、マイグレーションは忘れずに。

python manage.py makemigrations
python manage.py migrate

ブログ記事表示用ページを作る

記事投稿モデルを作ったら、次は表示用ページをHTMLで作ります。
blog/templates/blog/blog_page.htmlを作って下さい。

blog_page.html
{% extends "base.html" %}

{% load wagtailcore_tags %}

{% block body_class %}template-blogpage{% endblock %}

{% block content %}
    <h1>{{ page.title }}</h1>
    <p class="meta">{{ page.date }}</p>

    <div class="intro">{{ page.intro }}</div>

    {{ page.body|richtext }}

    <p><a href="{{ page.get_parent.url }}">Return to blog</a></p>

{% endblock %}

記事一覧を表示できるようにする

blog_index_page.htmlを再度開いて下さい。
先程作った、class BlogPage(Page)にtitleフィールドが無いのに、HTML側では<h1>{{ page.title }}</h1>でtitleを表示しようとしています。
これはDjangoの初期設定にあるフィールドを読み込んでいるので、

変更前
{% for post in page.get_children %}
        <h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
        {{ post.specific.intro }}
        {{ post.specific.body|richtext }}
    {% endfor %}

この部分を下記のように変えて下さい。

変更後
{% for post in page.get_children %}
    {% with post=post.specific %}
        <h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
        <p>{{ post.intro }}</p>
        {{ post.body|richtext }}
    {% endwith %}
{% endfor %}

また、記事一覧を最新記事から順に表示するため、BlogIndexPageモデルも編集します。

blog/models.py
from django.db import models

from wagtail.models import Page
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel
from wagtail.search import index


class BlogIndexPage(Page)://ここを変えたよ
    intro = RichTextField(blank=True)

    def get_context(self, request):
        # Update context to include only published posts, ordered by reverse-chron
        context = super().get_context(request)
        blogpages = self.get_children().live().order_by('-first_published_at')
        context['blogpages'] = blogpages
        return context

class BlogPage(Page):
    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)
    body = RichTextField(blank=True)

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

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('intro'),
        FieldPanel('body'),
    ]

とりあえず、これでブログ記事の一覧が表示されるようになりました。
アイキャッチ画像やタグの設定は次回にしたいと思います。
お読み頂きありがとうございました。

Discussion