前面的章节中,我们选择了使用iris.Django作为我们前端使用的模板引擎,因此我们这里只介绍它的相关语法。

iris.Django模板语法和使用

iris.Django模板引擎的模板解析器是pongo2,它是一个类似于 Django 模板语法的模板引擎。Django 是一个开放源代码Python编写的Web应用框架。它的模板引擎语法相对简单,清晰,使用起来也非常方便。因此我们就使用它做为我们的博客的前端模板引擎了。

模板的嵌套引用

往往制作模板的时候,我们会将一些公共部分,比如header、footer、aside等部分,抽离出来独立存放,不需要在每一个页面都重复编写,只需要在每一个页面引入它们即可。这个时候,我们可以使用include标签。

{% include "partial/header.html" %}
{% include "partial/footer.html" %}

include可以将一个拆分出来的代码片段(fragment)嵌入到完整的文档中。使用形式是{% include "模板文件" %}

模板的继承

模板的继承有点像ppt中的母版一样,我们定义好一个骨架,将一个页面都写好,大部分不用变动,需要变动的部分使用block标签包裹起来:

{% block title %}
    <title>basetitle>  
{% endblock %}

这样定义的好处是,可以在继承它的模板中,重写这个block,不重写就按母版来显示。 比如我们定义了一个base.html

html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block title %}
        <title>basetitle>  
    {% endblock %}
    
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .header {
            width: 100%;
            height: 50px;
            background-color: #369;
        }
    style>
head>
<body>

<div class="header">div>

<div class="container">
    <div class="row">
        <div class="col-md-3">
            {% include 'aside.html' %}
        div>
        <div class="col-md-9">
            {% block content %}
                <h4>contenth4>
            {% endblock %}
        div>
    div>
div>
body>
html>

然后在index.html中继承这个base.html

{% extends 'base.html' %}

{% block title %}
    <title>indextitle>
{% endblock %}


{% block content %}
    <div class="col-md-9">
        <h3>indexh3>
        <p>index contentp>
    div>

{% endblock %}

这样就是使用base.html作为母版,并在index.html 中重写了title、content两个部分。

注意:如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。

在使用继承的情况下,尽可能将可能会变动的数据,都包裹在block中,因为block即使在后续的页面不重写,也不影响模板的解析,而需要重写的时候就更方便。

同样地,如果后续写到某一块,发现多个页面都需要使用到,那么这时候,就把添加到base.html中去,让它成为母版的一部分。

变量的输出

Django 模板中遍历复杂数据结构的关键是句点字符.,变量输出边界定义是双大括号。有一个对象是people,它有Name、Gender、Level属性,在模板中输出就是:

<ul>
  <li>网站:{{siteName}}li>
  <li>名字:{{people.Name}}li>
  <li>性别:{{people.Gender}}li>
  <li>等级:{{people.Level}}li>
ul>

同时,输出变量的时候,还支持使用过滤器,来对数据进行初级过滤,格式是:

{{obj|filter__name:param}}

比如一个变量,当它有值的时候,就输出当前值,没有值的时候,就输出默认值: 使用default设置默认值:

{{ userName|default:"大侠匿名"}}

使用length输出长度:

{{ value|length }}

如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。

date 可以格式化时间:

{{ value|date:``"2006-01-02 15:04"}}

注意,这个value必须是time.Time类型,不是时间戳,如果是时间戳它会报错的。时间戳要么在控制器将它转成time.Time类型,要么就使用我们自定义的模板函数:

{{stampToDate(nowStamp, "2006-01-02 15:04")}}

truncatechars 字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾:

{{ value|truncatechars:9}}
{{ value|truncatewords:9}}

截断除了字符串截断truncatechars,还支持按单词截断truncatewords

upperlower 可以对单字进行大小写转换:

{{ value|upper}}
{{ value|lower}}

safe Django的模板中会对HTML标签和JS等语法标签进行自动转义,这样是为了安全,防止xss攻击。如果不想用转义,就使用safe

{{ article.Content|safe}}

后端传递变量到模板

实际网站开发中,我们在控制器中的变量,需要使用特定的函数ctx.ViewData("article", article)注入到view中,才能在模板中使用这个变量,比如,我们在IndexPage()控制器中定义一个article,然后将它传递到模板中,用来输出。

我们先在index.go 中的 IndexPage() 函数中添加如下代码

func IndexPage(ctx iris.Context) {
	nowStamp := time.Now().Unix()
	ctx.ViewData("nowStamp", nowStamp)

	article := model.Article{
		Id:          1,
		Title:       "这是一篇文章",
		Keywords:    "这是关键词",
		Description: "这是描述",
		CategoryId:  1,
		Views:       1,
		Category:    model.Category{
			Title: "这是分类名称",
		},
		ArticleData: model.ArticleData{
			ArticleId: 1,
			Content: "
内容在此
"
, }, } ctx.ViewData("article", article) ctx.View("index.html") }

然后在index.html模板中输出:

html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello Worldtitle>
head>
<body>
Hello World!<br>
{{stampToDate(nowStamp, "2006-01-02 15:04:05")}}<br>
<div>文章标题:{{article.Title}}div>
<div>文章分类:{{article.Category.Title}}div>
<div>文章Id:{{article.Id}}div>
<div>发布时间:{{stampToDate(article.CreatedTime)}}div>
<div>文章关键词:{{article.Keywords}}div>
<div>文章描述:{{article.Description}}div>
<div>文章内容:{{article.ArticleData.Content|safe}}div>
body>
html>

这样,就模板就获得了article变量,然后通过模板语法,将article的成员都输出了。

完整的项目示例代码托管在GitHub上,需要查看完整的项目代码可以到github.com/fesiong/goblog 上查看,也可以直接fork一份来在上面做修改。