從本篇開始,我們以之前具備的Python技能建構各種應用系統,包括內容管理系統(Content Management System, CMS)、儀表板(Dashboard)...等,本文先研究【內容管理系統】(CMS)。
內容管理系統(CMS)可以是一個部落格(Blog)、新聞網站(News)、商品推薦文或人物誌(Biography),是每個企業都需要的應用系統,因應以上各種用途或使用者觀點,會有各種版面(Layout)的需求,因此,典型的CMS套件都會提供自訂模板(Templates)功能,而Jinja套件正好是製作模板最佳的工具,Django、Flask都支援Jinja,本系列以多次介紹Django,所以,就來比較【Django CMS】相關套件,如下圖:
圖一. 【Django CMS】比較表
依照官方文件說明,步驟如下:
pip install wagtail
wagtail start mysite
cd mysite
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
http://localhost:8000/
依照上節建立的專案,進行頁面模板設計。
http://localhost:8000/admin
設定首頁:點選下圖紅框按鈕。
只能輸入標題(Title):
確認輸入沒問題即可發行(Publish)到網站上:
開啟瀏覽器測試,輸入URL:
http://localhost:8000/
from django.db import models
from wagtail.models import Page
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel
class HomePage(Page):
# 定義 Rich Text Field, not mandatory
body = RichTextField(blank=True)
# 加入 body
content_panels = Page.content_panels + [
FieldPanel('body'),
]
python manage.py makemigrations
python manage.py migrate
{% extends "base.html" %}
{% load static %}
{% load wagtailcore_tags %}
{% block body_class %}template-homepage{% endblock %}
{% block content %}
{{ page.body|richtext }}
{% endblock content %}
再重新設定首頁除了標題(Title),還可以輸入內文(body):
內文的編輯器可設定字體大小,並加入超連結、影像...等。
切換至上方的【Promote】頁籤,可輸入slug、tag及頁面資訊,作為搜尋引擎的SEO,其中slug為URL以【/】隔開的最後一段字串。
確認輸入沒問題即可發行(Publish)到網站上:
開啟瀏覽器測試,輸入URL:
http://localhost:8000/
作到這裡,我們就可完成一個單頁的網站,展示外部的新聞列表。
接下來,我們建置一個多頁的網站,Wagtail是以子頁(Child page)排列在主頁內。
python manage.py startapp blog
INSTALLED_APPS = [
"home",
"blog",
from django.db import models
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')
]
{% 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 %}
from wagtail.search import index
...
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'),
]
{% 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 %}
python manage.py makemigrations
python manage.py migrate
http://localhost:8000/admin
加入主頁:
加入子頁:
指定子頁模板:Blog page。
開啟瀏覽器測試,輸入URL:
http://localhost:8000/blog
作到這裡,完成一個部落格(Blog)建置。
以上只是Wagtail入門的教學,更多的功能可參閱官方文件說明,不過對於筆者而言,最大的收穫是利用Model/Template對應一種網頁佈局(Layout),可以讓開發者自訂佈局,如果要進一步讓使用者自訂佈局,可以將Model變成兩個資料表,一個是主表定義Template檔名,另一個子表對應Template內的欄位,就不需要每次增加一種佈局,就必須更新資料庫。
本系列的程式碼會統一放在GitHub,本篇的程式放在src/27資料夾,歡迎讀者下載測試,如有錯誤或疏漏,請不吝指正。