python Mac OS High Siera に wagtail puput をインストールする


wagtail/wagtail: A Django content management system focused on flexibility and user experience は、インストール初期状態だと、Template のモデル等は用意されていますが、一から作成していく必要があります。

この状態だと、すぐに Blog 等は始められないので、APSL/puput: A Django blog app implemented in Wagtail をインストールしてみます。


参考


前提

以下の環境で作業は実施しています。

  • OS

    % sw_vers
    ProductName:    Mac OS X
    ProductVersion: 10.13.1
    BuildVersion:   17B1003
    

  • Python の Version

    % python3 -V
    Python 3.6.2
    

  • wagtail の Version

    % python3 -m pip list --format=columns | grep wagtail
    wagtail                           1.13.1  
    

  • wagtail の Porject の作成
    あらかじめ、wagtail のプロジェクトを作成しておきます。

    wagtail start mysite
    ----------------------------------------------------------
    Creating a Wagtail project called mysite
    Success! mysite has been created
    ----------------------------------------------------------
    

  • django-compressorのインストール
    puput は、django-compressor に依存しているので、django-compressor のインストールが必要です。

    python3 -m pip install django_compressor --user
    
    インストールしていないと、template 内で以下のエラーが出力されます。
    'compress' is not a registered tag library. Must be one of:
    


インストール、設定

  • pip でインストール

    python3 -m pip install puput --user
    

  • INSTALLED_APPS に追加 puput の template 内で、wagtail.contrib.wagtailroutablepage のタグと、django-compressor のタグ使用しています。
    追加していなければ、wagtail.contrib.wagtailroutablepage と、compressor も追加します。
    画面表示時でエラーになることはありませんでしたが、sitemap の生成に、wagtail.contrib.wagtailsitemaps を使っているので、そちらも追加しておきます。

    INSTALLED_APPS = (
        ....
        'puput',
        ....
        'wagtail.contrib.wagtailsitemaps', #追加
        'wagtail.contrib.wagtailroutablepage', #追加
        'compressor', #追加
    )
    

  • Puput を plugin として動かす
    settings.py に以下記述を追加します。

    # Puput As Plugin
    PUPUT_AS_PLUGIN = True
    

  • Url を追加
    Plugin として動作させる場合は、wagtail の URL の直上に、puput の URL を追加します。

    urlpatterns = [
        ...
        url(r'', include('puput.urls')),
        url(r'', include(wagtail_urls)),
        ...
    ]
    

  • Migrate コマンドの実行

    python3 manage.py migrate
    

  • 初期データの投入

    python3 manage.py puput_initial_data
    

  • 管理者権限ユーザーの作成

    python3 manage.py createsuperuser
    


編集画面を確認

http://127.0.0.1:8000/admin にアクセスして、編集画面を確認します。

  • ページ構成
    Root ページ下に、Blog ページが追加されています。
    "Page Tree"
    初期設定では、http://127.0.0.1:8000/home で、wagtail のデフォルトの home ページ、http://127.0.0.1:8000/blog で blog ページにアクセスできます。

  • Blog ページの編集 コンテンツ
    ブログページの編集画面に移動します。
    コンテンツタブでは、タイトル、Descripttion、ヘッダイメージ を編集、設定することができます。
    "Blog Content"

  • Blog ページの編集 プロモート
    プロモートタブでは、スラッグ、ページタイトル、メニューに表示するか否か、ページの概要を編集することができます。
    ページの種類にかかわらずこの項目は編集できるので、デフォルトで設定可能な項目になります。
    "Blog Promoto"

  • Blog ページの編集 設定
    設定タブでは、ページング、Widgets の表示設定等を変更可能です。
    Comments は、Disqus が使用できるようです。
    "Blog Settings 1"
    "Blog Settings 2"
    "Blog Settings 3"

  • Blog Entry の追加
    Blog ページの子ページとして、記事を追加できます。
    Excerpt で本文の抜粋が設定できます。
    設定がない場合は、本文が抜粋されますが、設定されていると、Excerpt が優先で使用されます。
    タグ、カテゴリー、関連記事が設定できます。
    カテゴリー は、スニペットメニューから登録して、登録したカテゴリを紐づけて設定します。
    "Blog Entry 1"
    "Blog Entry 2"


Blog の本文編集欄をMarkdown Field に変更する

Blog の 本文編集欄を Markdown Filed に変更できないか調べたところ、Extending Entry Page — puput 0.9 documentation で、記事の Model をカスタマイズできることがわかりました。

やり方としては、以下 2通りあります。
* EntryPage を拡張し、サブタイプとして子ページを追加する。
* EntryAbstract を置き換えて、EntryPage が継承するクラスを変更する。

今回、本文欄を、Markdown Field に変更したかったので、EntryAbstract を継承して、Model を作成しました。

  • models.py
from __future__ import absolute_import, unicode_literals
import datetime
from django.utils.translation import ugettext_lazy as _

from wagtail.wagtailadmin.edit_handlers import FieldPanel, InlinePanel, MultiFieldPanel, PageChooserPanel
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel

from modelcluster.contrib.taggit import ClusterTaggableManager

from django.db import models
from wagtail.wagtailcore.models import Page
from wagtailmarkdown.edit_handlers import MarkdownPanel
from wagtailmarkdown.fields import MarkdownField

def get_image_model_path():
    from django.conf import settings
    return getattr(settings, 'WAGTAILIMAGES_IMAGE_MODEL', 'wagtailimages.Image')

class HomePage(Page):
    pass

class EntryAbstract(models.Model):
    body = MarkdownField(verbose_name=_('body'))
    tags = ClusterTaggableManager(through='puput.TagEntryPage', blank=True)
    date = models.DateTimeField(verbose_name=_("Post date"), default=datetime.datetime.today)
    header_image = models.ForeignKey(get_image_model_path(), verbose_name=_('Header image'), null=True, blank=True,
                                     on_delete=models.SET_NULL, related_name='+', )
    categories = models.ManyToManyField('puput.Category', through='puput.CategoryEntryPage', blank=True)
    excerpt = MarkdownField(verbose_name=_('excerpt'), blank=True,
                            help_text=_("Entry excerpt to be displayed on entries list. "
                                        "If this field is not filled, a truncate version of body text will be used."))
    num_comments = models.IntegerField(default=0, editable=False)

    content_panels = [
        MultiFieldPanel([
            FieldPanel('title', classname="title"),
            ImageChooserPanel('header_image'),
            MarkdownPanel('body', classname="full"),
            MarkdownPanel('excerpt', classname="full"),
        ], heading=_("Content")),
        MultiFieldPanel([
            FieldPanel('tags'),
            InlinePanel('entry_categories', label=_("Categories")),
            InlinePanel('related_entrypage_from', label=_("Related Entries"),
                        panels=[PageChooserPanel('entrypage_to')]),
        ], heading=_("Metadata")),
    ]

    class Meta:
        abstract = True

Model 作成を行うと、管理画面は、MarkdownField に切り替わりますが、Template 側は、RichTextFiled を処理する記述になっているので、対象箇所を Markdown Filter に切り替える必要があります。
対象箇所を抜粋して以下に記載します。

<section class="article">
    {% if entry.excerpt %}
        {{ entry.excerpt|richtext }}
    {% else %}
        {{ entry.body|richtext|truncatewords_html:70 }}
    {% endif %}
    <a class="blog_btn continue" href="{% entry_url entry blog_page %}">{% trans 'Continue reading' %} &raquo;</a>
</section>

オペレーションしてみた感想

  • 一通りのBlog としての機能は使用可能
    最低限の機能は保持しているため、問題なく使えると思いました。

  • Markdown は使用できない
    個人的には、Markdown で編集したいのですが、記事のMarkdwon 編集はできないようです。

  • 承認フローが回せるのは、個人ユースではない時に便利
    承認フローが回せるので、複数人で編集を行う場合、便利かもしれません。

個人的には、Markdown が使いたいので、Markdown が使える他の plugin を探す、もしくは Model を拡張して Markdown を使えるようにしようかと思います。

以上です。

コメント