- Wagtail 是一个用 Python 编写的开源 CMS,基于 Django 框架构建。 它优雅、强大、敏捷,专注于灵活性和用户体验,为开发人员提供一个快速有吸引力的界面,可以直观地创建和组织内容。
- Wagtail 教程系列 记录了基于 Wagtail 搭建博客站点的整个过程,当前站点 所呈现的即是搭建过程的最新效果。
关于
圆形带阴影图片效果。
<div class="card text-center mb-2">
<div class="card-body">
<div>
<a href="/">
<img class="shadow p-2 mb-2 bg-white rounded-circle"
style="width:120px; height:120px; border-radius:50%; overflow:hidden;"
src="{% static 'media/slowread-120x120.png' %}" alt="Logo - 站点Log" />
</a>
</div>
<h5 class="card-title"><a href="https://slowread.net">慢读 慢生活</a></h5>
<p class="card-text">Slow Rhythm of Life.</p>
</div>
</div>
图片轮播
图片滚动播放基于 bootstrap 4。
修改 /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]
# tags = Tag.objects.all().order_by('name')
wallpapers = Image.objects.filter(tags__name="壁纸").order_by('-created_at')[:3]
context['blogpages'] = blogpages
context['wallpapers'] = wallpapers
# context['tags'] = tags
return context
content_panels = Page.content_panels + [
FieldPanel('body', classname="full"),
]
在 /slowread/home/templates/home/home_page.html 页面中,用 django 模板语法中的 forloop.first,实现第一张图片为活动状态,其他图片为非活动状态,具体内容如下:
{% for wallpaper in wallpapers %}
{% image wallpaper max-800x600 as wallpaper_800x600 %}
{% image wallpaper original as wallpaper_original %}
<div {% if forloop.first %} class="carousel-item active"{% else %} class="carousel-item"{% endif %}>
<a href="{{ wallpaper_original.url }}">
<img class="d-block w-100 " src="{{ wallpaper_800x600.url }}">
</a>
</div>
{% endfor %}
完整内容如下:
{% extends "base.html" %}
{% load static wagtailcore_tags wagtailimages_tags %}
{% block body_class %}template-homepage{% endblock %}
{% block content %}
<div class="row mb-2 mt-3">
<div class="col-lg-8 mb-2">
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
</ol>
<div class="carousel-inner rounded">
{% for wallpaper in wallpapers %}
{% image wallpaper max-800x600 as wallpaper_800x600 %}
{% image wallpaper original as wallpaper_original %}
{{ first|add:1 }}
<div {% if forloop.first %} class="carousel-item active"{% else %} class="carousel-item"{% endif %}>
<a href="{{ wallpaper_original.url }}">
<img class="d-block w-100 " src="{{ wallpaper_800x600.url }}">
</a>
</div>
{% endfor %}
</div>
<a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
<div class="col-lg-4">
<div class="card text-center mb-2">
<div class="card-body">
<div>
<a href="/">
<img class="shadow p-2 mb-2 bg-white rounded-circle"
style="width:120px; height:120px; border-radius:50%; overflow:hidden;"
src="{% static 'media/slowread-120x120.png' %}" alt="Logo - 站点Log" />
</a>
</div>
<h5 class="card-title"><a href="https://slowread.net">慢读 慢生活</a></h5>
<p class="card-text">Slow Rhythm of Life.</p>
</div>
</div>
<div class="card text-center mb-2">
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
</div>
</div>
</div>
</div>
<div class="card-deck mb-2">
{% for post in blogpages %}
{% with post=post.specific %}
<div class="card">
{% 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 %}
标签
在 Wagtail 实践 2:简单博客实现 中已经实现了标签列表的初步功能,现在增加首页标签链接和标签列表分页功能。
标签链接
编辑 /slowread/home/templates/home/home_page.html ,增加如下内容:
<div class="card text-center mb-2">
<div class="card-body">
<a href="{% slugurl 'tags' %}?tag=django" class="mr-2">django</a>
<a href="{% slugurl 'tags' %}?tag=Linux" class="mr-2">Linux</a>
<a href="{% slugurl 'tags' %}?tag=Python" class="mr-2">Python</a>
<a href="{% slugurl 'tags' %}?tag=VPS" class="mr-2">VPS</a>
<a href="{% slugurl 'tags' %}?tag=Wagtail" class="mr-2">Wagtail</a>
</div>
</div>
标签检索结果分页
点击某个标签,会进入标签列表页面,如果标签对应的内容比较多,就需要对内容列表进行分页。
编辑 /slowread/blog/models.py ,修改内容如下:
class BlogTagIndexPage(Page):
def get_context(self, request):
# Filter by tag
tag = request.GET.get('tag')
blogpages = BlogPage.objects.filter(tags__name=tag).order_by('-first_published_at')
paginator = Paginator(blogpages, 6) # Show 6 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)
# Update template context
context = super().get_context(request)
context['tag'] = tag
context['blogpages'] = blogpages
return context
编辑 /slowread/blog/templates/blog/blog_tag_index_page.html ,增加如下内容:
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if blogpages.has_previous %}
<li class="page-item">
<a class="page-link" href="?tag={{ tag }}&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="?tag={{ tag }}&page={{ page_num }}">{{ page_num }}</a>
</li>
{% endfor %}
{% if blogpages.has_next %}
<li class="page-item">
<a class="page-link" href="?tag={{ tag }}&page={{ blogpages.next_page_number }}">»</a>
</li>
{% endif %}
</ul>
</nav>
图片标签
之前的标签操作都是针对文章所属的标签,下面针对标签为壁纸的图片进行独立的标签操作。
编辑 /slowread/blog/models.py ,增加壁纸滚动播放页面模型 WallpaperCarouselPage 内容如下:
class WallpaperCarouselPage(Page):
def get_context(self, request):
wallpapers = Image.objects.filter(tags__name="壁纸").order_by('-created_at')[:10]
# Update template context
context = super().get_context(request)
context['wallpapers'] = wallpapers
return context
进入后台管理,在 Home 页面下增加类型为 Wallpaper carousel page 子页面,标题为壁纸,推荐中的缩略名为 wallpaper 。
新建壁纸滚动播放页面模板文件 /slowread/blog/templates/blog/wallpaper_carousel_page.html,内容如下:
{% load static %}
{% load wagtailcore_tags wagtailimages_tags %}
<!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 href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet" type="text/css">
<link href="{% static 'css/all.min.css' %}" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="{% static 'css/slowread.css' %}">
</head>
<body class="{% block body_class %}{% endblock %}">
<div class="container-fluid">
<div class="row">
<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for wallpaper in wallpapers %}
{% image wallpaper original as wallpaper_original %}
<div {% if forloop.first %} class="carousel-item active"{% else %} class="carousel-item"{% endif %}>
<img class="d-block w-100" src="{{ wallpaper_original.url }}">
</div>
{% empty %}
No Wallpaper found.
{% endfor %}
</div>
<a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
{# 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>
由于不需要页头/页脚样式,壁纸轮播页面模板没有基于 base.html 母板页面扩展,而是全新创建一个模板文件。