Wagtail 教程 3:引入 Bootstrap 4,Font
Wagtail 教程系列 记录了基于 Wagtail 搭建博客站点的整个过程,博客站点 所呈现的即是搭建过程的最新效果。
更多 Wagtail 内容:https://slowread.net/wagtail-tutorials
此部分属于通用内容,非 Wagtail
必需内容,是为了完善/优化基于 Wagtail
搭建的博客。
引入 Bootstrap 4
http://getbootstrap.com/
https://code.z01.com/v4/
打开上面网址,下载以下文件并放置到相应项目目录下:
/slowread/static/css/bootstrap.min.css
/slowread/static/js/jquery-3.3.1.slim.min.js
/slowread/static/js/popper.min.js
/slowread/static/js/bootstrap.min.js
修改 /slowread/templates/base.html
,加入以下内容:
{# Global stylesheets #}
...
<link rel="stylesheet" type="text/css" href="{% static 'css/slowread.css' %}">
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet" type="text/css">
...
{# Global javascript #}
...
<script src="{% static 'js/jquery-3.3.1.slim.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/popper.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/bootstrap.min.js' %}" type="text/javascript"></script>
引入 Font Awesome
https://fontawesome.com/
https://fontawesome.com/how-to-use/on-the-web/setup/hosting-font-awesome-yourself
下载文件,然后拷贝 /webfonts
和 /css/all.css
到 /slowread/static
目录下,结果如下:
/slowread/static/webfonts/fa-*.*
多个文件
/slowread/static/css/all.min.css
一个文件
修改 /slowread/templates/base.html
,加入以下内容:
{# Global stylesheets #}
...
<link href="{% static 'css/all.min.css' %}" rel="stylesheet" type="text/css">
页头
新建 /slowread/templates/header.html
,内容如下:
<!-- 定义导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<!-- 导航栏标识 -->
<a class="navbar-brand" href="/">慢读 慢生活</a>
<!-- 导航入口 -->
<div>
<ul class="navbar-nav">
<!-- 条目 -->
<li class="nav-item">
<a class="nav-link" href="/blog">博客文章</a>
</li>
</ul>
</div>
</div>
</nav>
页脚
新建 /slowread/templates/footer.html
,内容如下:
<!-- Footer -->
<footer class="py-3 bg-primary">
<div class="container">
<p class="m-0 text-center text-white">Copyright © <a class="m-0 text-center text-white" href="https://slowread.net">SlowRead.net</a> 2018</p>
</div>
</footer>
base.html
编辑页面模板文件 /slowread/templates/base.html
,内容如下:
{% load static wagtailuserbar %}
<!DOCTYPE html>
<html lang="zh_cn">
<head>
<meta charset="utf-8" />
<title>
{% block title %}
{% if self.seo_title %}{{ self.seo_title }}{% else %}{{ self.title }}{% endif %}
{% endblock %}
{% block title_suffix %}
{% with self.get_site.site_name as site_name %}
{% if site_name %}- {{ site_name }}{% endif %}
{% endwith %}
{% endblock %}
</title>
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'media/slowread-32x32.ico' %}">
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'media/slowread-16x16.ico' %}">
{# Global stylesheets #}
<link rel="stylesheet" type="text/css" href="{% static 'css/slowread.css' %}">
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet" type="text/css">
<link href="{% static 'css/all.min.css' %}" rel="stylesheet" type="text/css">
{% block extra_css %}
{# Override this in templates to add extra stylesheets #}
{% endblock %}
</head>
<body class="{% block body_class %}{% endblock %}">
<!-- 引入导航栏 -->
{% include 'header.html' %}
{% wagtailuserbar %}
<div class="container">
{% block content %}
{% endblock %}
</div>
<!-- 引入注脚 -->
{% include "footer.html" %}
{# Global javascript #}
<script type="text/javascript" src="{% static 'js/slowread.js' %}"></script>
<script src="{% static 'js/jquery-3.3.1.slim.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/popper.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/bootstrap.min.js' %}" type="text/javascript"></script>
{% block extra_js %}
{# Override this in templates to add extra javascript #}
{% endblock %}
</body>
</html>
首页布局
编辑 /slowread/home/models.py
,内容如下:
class HomePage(Page):
body = RichTextField(blank=True)
def get_context(self, request):
# Update context to include only published posts, ordered by reverse-chron
context = super().get_context(request)
page = Page.objects.get(title="文章列表")
blogpages = page.get_children().live().order_by('-first_published_at')[:3]
context['blogpages'] = blogpages
return context
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
编辑 /slowread/home/templates/home/home_page.html
,内容如下:
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block body_class %}template-homepage{% endblock %}
{% block content %}
<h1 class="mt-2">{{ self.title }}</h1>
{{ page.body|richtext }}
<hr>
<div class="card-deck mb-2">
{% for post in blogpages %}
{% with post=post.specific %}
<div class="card" style="width: 18em;">
{% with post.main_image as main_image %}
{% if main_image %}
{% image main_image fill-320x240 as header_image %}
<a href="{% pageurl post %}">
<img src="{{ header_image.url }}" class="card-img-top" />
</a>
{% endif %}
{% endwith %}
<div class="card-body">
<h5 class="card-title"><a href="{% pageurl post %}">{{ post.title }}</a></h5>
<p class="card-text">
{% if post.intro %}
{{ post.intro|richtext }}
{% else %}
{{ post.body|richtext|truncatewords_html:80 }}
{% endif %}
</p>
</div>
<div class="card-footer">
<small class="text-muted"><a href="{% pageurl post %}" class="btn btn-primary">阅读全文</a></small>
</div>
</div>
{% endwith %}
{% endfor %}
</div>
<hr>
<a class="nav-link text-center" href="/blog">更多文章</a>
<hr>
{% endblock %}
文章列表页分页
编辑 /slowread/blog/models.py
,修改 BlogIndexPage
内容如下:
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')
paginator = Paginator(blogpages, 3) # Show 3 resources per page
page = request.GET.get('page')
try:
blogpages = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
blogpages = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
blogpages = paginator.page(paginator.num_pages)
# make the variable 'resources' available on the template
context['blogpages'] = blogpages
return context
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
采用Boostrap 4
的分页 Pagination
导航样式,编辑 /slowread/blog/templates/blog/blog_index_page.html
,内容如下:
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block body_class %}template-blogindexpage{% endblock %}
{% block content %}
<h1 class="mt-2">{{ page.title }}</h1>
<!-- <div class="intro">{{ page.intro|richtext }}</div> -->
{% for post in blogpages %}
{% with post=post.specific %}
<div class="card mb-2">
<h4 class="card-header"><a href="{% pageurl post %}">{{ post.title }}</a></h4>
<div class="card-body">
<div class="row">
<div class="col-auto mr-auto">
{% if post.intro %}
{{ post.intro|richtext }}
{% else %}
{{ post.body|richtext|truncatewords_html:80 }}
{% endif %}
<a href="{% pageurl post %}" class="btn btn-primary mt-2 mb-2">阅读全文</a>
</div>
<div class="col-auto">
{% with post.main_image as main_image %}
{% if main_image %}
<a href="{% pageurl post %}">
{% image main_image fill-160x100 %}
</a>
{% endif %}
{% endwith %}
</div>
</div>
</div>
</div>
{% endwith %}
{% endfor %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if blogpages.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ blogpages.previous_page_number }}">«</a>
</li>
{% endif %}
{% for page_num in blogpages.paginator.page_range %}
<li {% if page_num == blogpages.number %} class="active page-item"{% endif %}>
<a class="page-link" href="?page={{ page_num }}">{{ page_num }}</a>
</li>
{% endfor %}
{% if blogpages.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ blogpages.next_page_number }}">»</a>
</li>
{% endif %}
</ul>
</nav>
<hr>
{% endblock %}