Wagtail 使用 Django 的模板语言。对于刚接触 Django 的开发人员,请从 Django 自己的模板文档开始: Templates

刚接触 Django / Wagtail 的 Python 程序员可能更喜欢更多技术文档: The Django template language: for Python programmers

在继续阅读本文档之前,您应该熟悉 Django 模板基础知识。

模板

Wagtail 中的每种类型的页面或“内容类型”都被定义为名为 models.py 的文件中的“模型”。如果您的网站有博客,您可能有一个 BlogPage 型号和另一个名为 BlogPageListing 的型号。模型的名称由 Django 开发人员决定。

对于 models.py 中的每个页面模型, Wagtail 假定存在(几乎)相同名称的 HTML 模板文件。前端开发人员可能需要通过参考 models.py 从其中定义的模型推断模板名称来自己创建这些模板。

为了找到合适的模板, Wagtail 将 CamelCase 名称转换为 Snake_case。因此,对于 BlogPage 来说,预计会出现模板 blog_page.html 。如有必要,可以根据模型覆盖模板文件的名称。

假设模板文件存在于此处:

name_of_project/
    name_of_app/
        templates/
            name_of_app/
                blog_page.html
        models.py

有关更多信息,请参阅 application directories template loader 的 Django 文档。

页面内容

输入到每个页面的数据/内容是通过 Django 的 {{ double-brace }} 表示法访问/输出的。模型中的每个字段都必须通过前缀 page.. 进行访问。例如页面标题 {{ page.title }} 或其他字段 {{ page.author }}

可以在型号 wagtail.models.Page.context_object_name 页面上配置自定义变量名称。如果定义了自定义名称, page 仍可在共享模板中使用。

此外, request. 可用并且包含 Django 的请求对象。

静态资源

Static 文件(例如 CSS、JS 和图像)通常存储在这里:

name_of_project/
    name_of_app/
        static/
            name_of_app/
                css/
                js/
                images/
        models.py

(名称“css”、“js”等并不重要,重要的是它们在树中的位置。)

static 文件夹中的任何文件都应使用 {% static %} 标记插入到 HTML 中。更多信息: Static files (tag) 。

用户图片

由用户上传到 Wagtail 站点的图像(与上面提到的开发人员的 static 文件相反)进入图像 library ,并从那里通过页面编辑器界面添加到页面。

与其他 CMS 不同,向页面添加图像不需要选择要使用的图像“版本”。 Wagtail 没有预定义的图像“格式”或“尺寸”。相反,模板开发人员通过模板中的特殊语法定义在请求图像时动态发生的图像操作。

来自 library 的图像必须使用此语法请求,但开发人员的 static 图像可以通过 img 标签等传统方式添加。只能动态操作来自 library 的图像。

在这里阅读有关图像处理语法的更多信息: How to use images in templates 。

模板标签和过滤器 (Template tags & filters)

除了 Django 的标准标签和过滤器之外, Wagtail 还提供了一些自己的标签和过滤器,可以是 load-ed just like any other 。

图像 (tag)

image 标记将 XHTML 兼容的 img 元素插入页面中,设置其 srcwidthheightalt 。另请参见 More control over the img tag 。

image 标签的语法如下:

{% image [image] [resize-rule] %}

示例:

{% load wagtailimages_tags %}
...

{% image page.photo width-400 %}

<!-- or a square thumbnail: -->
{% image page.photo fill-80x80 %}

请参阅 How to use images in templates 了解完整文档。

多种格式的图像

picture 标签的工作方式与 image 类似,但它允许指定多种格式来生成一个带有 <source> 元素和一个备用 <img> 元素的 <picture> 元素。

例如:

{% load wagtailimages_tags %}
...

{% picture page.photo format-{avif,webp,jpeg} width-400 %}

有关完整文档,请参阅多种格式。

多种尺寸的图像

srcset_image 标签的工作方式与 image 类似,但允许指定多个大小来生成 srcset 属性并利用响应式图像规则。

示例:

{% load wagtailimages_tags %}
...

{% srcset_image page.photo width-{400,800} sizes="(max-width: 600px) 400px, 80vw" %}

这也可以用图片来完成,一次生成多种格式和大小:

{% picture page.photo format-{avif,webp,jpeg} width-{400,800} sizes="80vw" %}

有关完整文档,请参阅响应式图像。

富文本(过滤器)

此过滤器获取一块 HTML 内容并将其呈现为页面中的安全 HTML。重要的是,它还将对嵌入图像的内部速记引用以及 Wagtail 编辑器中创建的链接扩展为可供显示的完全烘焙的 HTML。

只有使用 RichTextField 的字段才需要在模板中应用此功能。

{% load wagtailcore_tags %}
...
{{ page.body|richtext }}

响应式嵌入 (Responsive Embeds)

由于 Wagtail 不会在模板上强加任何自己的样式,因此图像和嵌入媒体将以 HTML 确定的固定宽度显示。可以使用 CSS 规则调整图像大小以适合其容器,如下所示:

.body img {
    max-width: 100%;
    height: auto;
}

其中 body 是模板中围绕图像的容器元素。

使嵌入式媒体可调整大小也是可能的,但通常需要与媒体的宽高比相匹配的自定义样式规则。为了帮助实现这一点, Wagtail 提供了对响应式嵌入的内置支持,可以通过在项目设置中设置 WAGTAILEMBEDS_RESPONSIVE_HTML = True 来启用该支持。这会向嵌入添加 responsive-object 的 CSS 类和内联 padding-bottom 样式,以便与以下 CSS 结合使用:

.responsive-object {
    position: relative;
}

.responsive-object iframe,
.responsive-object object,
.responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

pageurl

获取一个 Page 对象,如果与当前页面位于同一站点内,则返回相对 URL ( /foo/bar/ ),如果不在同一站点内,则返回绝对 URL ( http://example.com/foo/bar/ )。

{% load wagtailcore_tags %}
...
<a href="{% pageurl page.get_parent %}">Back to index</a>

可以提供 fallback 关键字参数 - 这可以是 URL 字符串、可以不带参数解析的命名 URL 路由或具有 get_absolute_url 方法的对象,并且当传递的页面为 None 时将用作替代 URL。

{% load wagtailcore_tags %}

{% for publication in page.related_publications.all %}
    <li>
        <a href="{% pageurl publication.detail_page fallback='coming_soon' %}">
            {{ publication.title }}
        </a>
    </li>
{% endfor %}

fullpageurl

接受一个 Page 对象并返回它的绝对URL (http://example.com/foo/bar/)。

{% load wagtailcore_tags %}
…
<meta property="og:url" content="{% fullpageurl page %}" />

pageurl 非常相似,可以提供一个 fallback 关键字参数。

slugurl

获取页面“Promote”选项卡中定义的任何 slug ,并返回匹配页面的 URL。如果存在具有相同 slug 的多个页面,则所选择的页面是不确定的。

pageurl 一样,如果可能,这将尝试提供相对链接,但如果页面位于不同的站点上,则默认为绝对链接。这在创建共享页面功能(例如顶级导航或站点范围链接)时非常有用。

{% load wagtailcore_tags %}
...
<a href="{% slugurl 'news' %}">News index</a>

Static 文件(tag)

用于从 static 文件目录加载任何内容。使用此标签可以避免在托管安排发生变化时重写所有 static 路径,因为它们可能在开发环境和实时环境之间发生变化。

{% load static %}
...
<img src="{% static "name_of_app/myimage.jpg" %}" alt="My image"/>

请注意,完整路径不是必需的 - 此处给出的路径是相对于应用程序的 static 目录的。为了避免与其他应用程序(包括 Wagtail 本身)的 static 文件发生冲突,建议将 static 文件放置在与应用程序同名的 static 子目录中。

多站点支持

wagtail_site

返回当前请求对应的 Site 对象。

{% load wagtailcore_tags %}

{% wagtail_site as current_site %}

Wagtail 用户栏

此标签为登录用户提供上下文弹出菜单。除了在 Wagtail 页面浏览器中显示页面或跳转到 Wagtail 管理仪表板的选项之外,该菜单还使编辑者能够编辑当前页面或添加子页面。作为内容审核的一部分,审核者还可以接受或拒绝正在预览的页面。

该标签可用于标准 Django 视图,无需页面对象。用户栏将包含一项指向管理员的项目。

我们建议将标签放置在 <body> 元素顶部附近,以便键盘用户可以触及它。您应该考虑将该标签放在任何 skip links 之后,但在页面的导航和主要内容之前。

{% load wagtailuserbar %}
...
<body>
    <a id="#content">Skip to content</a>
    {% wagtailuserbar %} {# 这是用户栏的好地方#}
    <nav>
    ...
    </nav>
    <main id="content">
    ...
    </main>
</body>

默认情况下,用户栏显示在浏览器窗口的右下角,从边缘插入。如果这与您的设计冲突,可以通过将参数传递给模板标记来移动它。这些示例向您展示如何将用户栏放置在屏幕的每个角落:

...
{% wagtailuserbar 'top-left' %}
{% wagtailuserbar 'top-right' %}
{% wagtailuserbar 'bottom-left' %}
{% wagtailuserbar 'bottom-right' %}
...

用户栏可以放置在最适合您的设计的位置。或者,您可以使用自己的 CSS 文件中的 CSS 规则来定位它,例如:

wagtail-userbar::part(userbar) {
    bottom: 30px;
}

要自定义用户栏中显示的项,可以使用 construct_wagtail_userbar 钩子。

预览和实时之间的输出不同

有时您可能希望根据页面是否正在预览或实时查看来改变模板输出。例如,如果您的网站上有访客跟踪代码(例如 Google Analytics),则最好在预览时将其忽略,这样编辑器活动就不会出现在您的分析报告中。 Wagtail 提供了一个 request.is_preview 变量来区分预览和实时:

{% if not request.is_preview %}
    <script>
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
        ...
    </script>
{% endif %}

如果正在预览页面,如果页面支持 multiple preview modes ,则可以使用 request.preview_mode 来确定正在使用的特定预览模式。

模板片段缓存

Django 支持模板片段缓存,它允许缓存模板的某些部分。在 Wagtail 中使用 Django 的 {% cache %} 标签可能是危险的,因为它可能会导致预览内容被显示给最终用户。相反,Wagtail 提供了 2 个额外的模板标签,可以从 wagtail_cache 加载:

预览感知缓存

{% wagtailcache %} 标签的功能类似于 Django 的 {% cache %} 标签,但在 Wagtail 中预览页面(或其他模型)时,既不会缓存也不会提供缓存的内容。

{% load wagtail_cache %}

{% wagtailcache 500 "sidebar" %}
    <!-- sidebar -->
{% endwagtailcache %}

{% cache %} 类似,您可以使用 make_template_fragment_key 获取缓存键值。

页面感知缓存

{% wagtailpagecache %}{% wagtailcache %} 的扩展,但也可以感知当前 pagesite ,并将其作为缓存键的一部分。这使得可以轻松地围绕页面的部分添加缓存,而不必担心它所在的页面。{% wagtailpagecache %} 故意做了一些假设 - 对于更多的定制,建议使用 {% wagtailcache %}

{% load wagtail_cache %}

{% wagtailpagecache 500 "hero" %}
    <!-- hero -->
{% endwagtailcache %}

这等同于:

{% wagtail_site as current_site %}

{% wagtailcache 500 "hero" page.cache_key current_site.id %}
    <!-- hero -->
{% endwagtailcache %}

注意要使用页面缓存键值,它确保当页面更新时,缓存自动失效。

如果你想获取缓存键值,你可以使用 make_wagtail_template_fragment_key (基于 Django 的 make_template_fragment_key ):

from django.core.cache import cache
from wagtail.coreutils import make_wagtail_template_fragment_key

key = make_wagtail_template_fragment_key("hero", page, site)
cache.delete(key)  # invalidates cached template fragment