基础配置篇:博客模板的格式语法和后端如何传递数据到模板逻辑
iris.Django
Djangoiris.Django
iris.Django
iris.Django
include
往往制作模板的时候,我们会将一些公共部分,比如header、footer、aside等部分,抽离出来独立存放,不需要在每一个页面都重复编写,只需要在每一个页面引入它们即可。这个时候,我们可以使用include标签。
{% include "partial/header.html" %}
{% include "partial/footer.html" %}
{% include "模板文件" %}
if_exists
{% include "partial/header.html" if_exists %}
这样如果header.html模板存在的话,则会引入,即使不存在,也不会报错,只是被忽略掉了。
with
{% include "partial/header.html" with title="这是声明给header使用的title" %}
这样就给include引入的模板定义了title变量,当前模板的其他变量它同样也可以继续使用了。
key=value
{% include "partial/header.html" with title="这是声明给header使用的title" keywords="这是声明给header使用的keywords" %}
如果只想让include引入的模板使用指定的几个变量,而不是当前模板的所有变量,可以使用only来做限制:
{% include "partial/header.html" with title="这是声明给header使用的title" keywords="这是声明给header使用的keywords" only %}
然后在header.html中使用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{title}}</title>
<meta name="keywords" content="{{keywords}}">
</head>
macro
iris.Djangomacro
定义一个宏函数
{% macro article_detail(article) %}
<li class="item">
<a href="/article/{{article.Id}}" class="link">
<h5 class="title">{{article.Title}}</h5>
</a>
</li>
{% endmacro %}
使用定义的宏函数
{% for item in articles %}
{{ article_detail(item) }}
{% endfor %}
,
保存宏函数到 article.helper
{% macro article_detail(article) %}
<li class="item">
<a href="/article/{{article.Id}}" class="link">
<h5 class="title">{{article.Title}}</h5>
</a>
</li>
{% endmacro %}
{% macro article_detail2(article) %}
<li class="item">
<a href="/article/{{article.Id}}" class="link">
<h5 class="title">{{article.Title}}</h5>
</a>
</li>
{% endmacro %}
在index.html中引入:
用import引入:
{% import "article.helper" article_detail, article_detail2 as article_detail_new, article_detail as new_item %}
调用:
{% for item in articles %}
{{ article_detail(item) }}
{{ article_detail_new(item) }}
{{ new_item(item) }}
{% endfor %}
extends
模板的继承有点像ppt中的母版一样,我们定义好一个骨架,将一个页面都写好,大部分不用变动,需要变动的部分使用block标签包裹起来:
{% block title %}
<title>base</title> <!-- 如果扩写了就是扩写的,不扩写就还是用base -->
{% endblock %}
这样定义的好处是,可以在继承它的模板中,重写这个block,不重写就按母版来显示。
比如我们定义了一个base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block title %}
<title>base</title> <!-- 如果扩写了就是扩写的,不扩写就还是用base -->
{% endblock %}
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<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>content</h4>
{% endblock %}
</div>
</div>
</div>
</body>
</html>
然后在index.html中继承这个base.html
{% extends 'base.html' %}
{% block title %}
<title>index</title>
{% endblock %}
{% block content %}
<div class="col-md-9">
<h3>index</h3>
<p>index content</p>
</div>
{% endblock %}
这样就是使用base.html作为母版,并在index.html 中重写了title、content两个部分。
注意:如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
在使用继承的情况下,尽可能将可能会变动的数据,都包裹在block中,因为block即使在后续的页面不重写,也不影响模板的解析,而需要重写的时候就更方便。
同样地,如果后续写到某一块,发现多个页面都需要使用到,那么这时候,就把添加到base.html中去,让它成为母版的一部分。
变量的输出
.
<ul>
<li>网站:{{siteName}}</li>
<li>名字:{{people.Name}}</li>
<li>性别:{{people.Gender}}</li>
<li>等级:{{people.Level}}</li>
</ul>
变量的过滤
同时,输出变量的时候,还支持使用过滤器,来对数据进行初级过滤,格式是:
{{obj|filter__name:param}}
default
{{ userName|default:"大侠匿名"}}
default_if_none
{{ userName|default_if_none:"大侠匿名"}}
{{ ""|default_if_none:"n/a" }}
{{ nil|default_if_none:"n/a" }}
get_digit
{{ 1234567890|get_digit:0 }}
{{ 1234567890|get_digit }}
{{ 1234567890|get_digit:2 }}
{{ 1234567890|get_digit:"4" }}
{{ 1234567890|get_digit:10 }}
{{ 1234567890|get_digit:15 }}
length
{{ value|length }}
如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。
divisibleby
{{ 21|divisibleby:3 }}
{{ 21|divisibleby:"3" }}
{{ 21|float|divisibleby:"3" }}
{{ 22|divisibleby:"3" }}
{{ 85|divisibleby:simple.number }}
{{ 84|divisibleby:simple.number }}
date
{{ value|date:``"2006-01-02 15:04"}}
注意,这个value必须是time.Time类型,不是时间戳,如果是时间戳它会报错的。时间戳要么在控制器将它转成time.Time类型,要么就使用我们自定义的模板函数:
{{stampToDate(nowStamp, "2006-01-02 15:04")}}
truncatecharstruncatewords
{{ value|truncatechars:9}}
{{ value|truncatewords:9}}
truncatecharstruncatewords
truncatechars_htmltruncatewords_htmltruncatecharstruncatewords
{{ "This is a long test which will be cutted after some chars."|truncatechars_html:25 }}
{{ "This is a long test which will be cutted after some words."|truncatewords_html:5|safe }}
upperlower
{{ value|upper}}
{{ value|lower}}
capfirst
{{ "hello there!"|capfirst }}
cut
{{ 15|cut:"5" }}
{{ "Hello world"|cut: " " }}
add+
{{ 5|add:6 }}
{{ 5|add:nothing }}
{{ 5|add:"test" }}
{{ "hello "|add:"john doe" }}
addslashes
{{ "plain' text"|addslashes }}
{{ "plain' text"|addslashes|safe }}
title
{{ "hello there!"|title }}
{{ "HELLO THERE!"|title }}
{{ "HELLO tHERE!"|title }}
yesno,
{{ article.Status|yesno}}
{{ article.Status|yesno:"validated,not validated,unknown validation status"}}
striptags
{{"<title>Hello World</title>"|striptags}}
{{"<title>Hello World</title>"|striptags|safe}}
removetags
{{ "<strong><i>Hello!</i></strong>"|removetags:"i"|safe }}
pluralize
customer{{ 0|pluralize }}
customer{{ 1|pluralize }}
customer{{ 2|pluralize }}
cherr{{ 0|pluralize:"y,ies" }}
cherr{{ 1|pluralize:"y,ies" }}
cherr{{ 2|pluralize:"y,ies" }}
walrus{{ 0|pluralize:"es" }}
walrus{{ 1|pluralize:"es" }}
walrus{{ simple.number|pluralize:"es" }}
random
<p>{{ intList|random }}</p>
firstlast
{{ "Test"|first }}
{{ "Test"|last }}
urlencode
{{ "/?category_id=1"|urlencode }}
linebreaksbrlinebreaks
nl2br
{{ article.Description|linebreaksbr }}
{{ article.Description|linebreaks }}
{{ article.Description|linebreaksbr|safe }}
{{ article.Description|linebreaks|safe }}
length_is
{{ "hello"|length_is:5 }}
integerfloat
{{ "foobar"|integer }}
{{ "5.4"|float|integer }}
{{ "foobar"|float }}
{{ "5.5"|float }}
{{ "5.6"|integer|float }}
floatformat
{{ 34.23234|floatformat }}
{{ 34.00000|floatformat }}
{{ 34.23234|floatformat:3 }}
{{ 34.00000|floatformat:3 }}
{{ "34.23234"|floatformat }}
{{ "34.00000"|floatformat }}
{{ "34.23234"|floatformat:3 }}
{{ "34.00000"|floatformat:3 }}
join
{{intList|join:", "}}
splitjoin
{{ "Hello, 99, 3.140000, good"|split:", "|join:", " }}
stringformatfmt.Sprintf()
{{ 0.55555|stringformat:"%.2f" }}
{{ 888|stringformat:"Test: %d" }}
{{ "你好"|stringformat:"Chinese: %s" }}
make_list[]rune("你好啊")
{{ "你好啊"|make_list|join:", " }}
{% for char in "你好啊"|make_list %}{{ char }},{% endfor %}
center
'{{ "test"|center:3 }}'
'{{ "test"|center:20 }}'
{{ "test"|center:20|length }}
ljustrjustcenterljustrjust
'{{ "test"|ljust:"20" }}'
{{ "test"|ljust:"20"|length }}
'{{ "test"|rjust:"20" }}'
{{ "test"|rjust:"20"|length }}
wordcount
{{ ""|wordcount }}
{% filter wordcount %}{% lorem 25 w %}{% endfilter %}
wordwrap
{{ "hello world"|wordwrap:2 }}
<pre>{% filter wordwrap:5 %}{% lorem 26 w %}{% endfilter %}</pre>
{{ "Lorem ipsum dolor sit amet, consectetur adipisici elit."|wordwrap:2|linebreaksbr|safe }}
urlize
<p>{{ ""|urlize|safe }}</p>
<p>{{ "www.kandaoni.com"|urlize|safe }}</p>
<p>{{ "kandaoni.com"|urlize|safe }}</p>
<p>{% filter urlize:true|safe %}</p>
<p>Please mail me at demo@example.com or visit mit on:</p>
<p>- lorem ipsum http://www.kandaoni.com lorem ipsum</p>
<p>- lorem ipsum lorem ipsum</p>
<p>- lorem ipsum lorem ipsum</p>
<p>- lorem ipsum www.kandaoni.com lorem ipsum</p>
<p>- lorem ipsum www.kandaoni.com/test="test" lorem ipsum</p>
<p>{% endfilter %}</p>
<p>{% filter urlize:false|safe %}</p>
<p>- lorem ipsum www.kandaoni.com/test="test" lorem ipsum</p>
<p>{% endfilter %}</p>
urlizetruncurlize...
<p>{% filter urlizetrunc:15|safe %}</p>
<p>Please mail me at demo@example.com or visit mit on:</p>
<p>- lorem ipsum http://www.kandaoni.com lorem ipsum</p>
<p>- lorem ipsum lorem ipsum</p>
<p>- lorem ipsum lorem ipsum</p>
<p>- lorem ipsum www.kandaoni.com lorem ipsum</p>
<p>- lorem ipsum www.kandaoni.com/test="test" lorem ipsum</p>
<p>{% endfilter %}</p>
escapejs\uxxxx
{{ "<p>aaa</p><script>alert('xss');</script><p>bbbb</p>"|escapejs|safe }}
slice
{{ "Test"|slice:"1:" }}
{{ "Test"|slice:":3" }}
{{ "Test"|slice:"1:3"|join:"," }}
{{ intList|slice:"1:5"|join:"," }}
safe
safeautoescape
用safe关闭自动转义
{{ "<script>alert('xss');</script>"|safe}}
强制开启自动转义
{% autoescape on %}
{{ "<script>alert('xss');</script>" }}
{% endautoescape %}
强制关闭自动转义,相当于使用了safe
{% autoescape off %}
{{ "<script>alert('xss');</script>" }}
{% endautoescape %}
escapeautoescape off
{{ "<script>alert('xss');</script>" }}
相当于
{% autoescape off %}
{{ "<script>alert('xss');</script>"|escape }}
{% endautoescape %}
{% filter 标签名 %}内容{% endfilter %}
{% filter lower %}This is a nice test; let's see whether it works. Foobar. {{ simple.xss }}{% endfilter %}
{% filter truncatechars:10|lower|length %}This is a nice test; let's see whether it works. Foobar. {{ simple.number }}{% endfilter %}
<p>{% filter urlize:false|safe %}</p>
<p>- lorem ipsum www.kandaoni.com/test="test" lorem ipsum</p>
<p>{% endfilter %}</p>
for
for
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% endfor %}
pluralize
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">第{{ forloop.Counter }}篇,剩余{{ forloop.Revcounter}}篇,{{ forloop.Revcounter|pluralize:"多于1篇" }}:{{item.Title}}</h5>
</a>
</li>
{% endfor %}
forreversedsorted
{% for item in articles reversed %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% endfor %}
{% for item in articles sorted %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% endfor %}
{% for item in articles reversed sorted %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% endfor %}
forempty
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% empty %}
<div>没有内容</div>
{% endfor %}
它等价于使用if判断,但是这样写可以更简洁:
{% if articles %}
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% endfor %}
{% else %}
<div>没有内容</div>
{% endif %}
cyclecycle
cycle
此标记在循环中特别有用。如:
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<h5 class="title">Title,Id 逐个出现:{% cycle item.Title item.Id %}</h5>
</a>
</li>
{% endfor %}
as
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
{% cycle item.Title item.Id as cycleitem %}
<h5 class="title">Title,Id 逐个出现:{{ cycleitem }}</h5>
</a>
</li>
{% endfor %}
在模板中使用数学算术计算
整数和复数表达式 integers and complex expressions
{{ 10-100 }}
{{ -(10-100) }}
{{ -(-(10-100)) }}
{{ -1 * (-(-(10-100))) }}
{{ -1 * (-(-(10-100)) ^ 2) ^ 3 + 3 * (5 - 17) + 1 + 2 }}
浮点数 floats
{{ 5.5 }}
{{ 5.172841 }}
{{ 5.5 - 1.5 == 4 }}
{{ 5.5 - 1.5 == 4.0 }}
乘法、除法、整除 mul/div
{{ 2 * 5 }}
{{ 2 * 5.0 }}
{{ 2 * 0 }}
{{ 2.5 * 5.3 }}
{{ 1/2 }}
{{ 1/2.0 }}
{{ 1/0.000001 }}
逻辑表达式 logic expressions
{{ !true }}
{{ !(true || false) }}
{{ true || false }}
{{ true or false }}
{{ false or false }}
{{ false || false }}
{{ true && (true && (true && (true && (1 == 1 || false)))) }}
浮点数比较 float comparison
{{ 5.5 <= 5.5 }}
{{ 5.5 < 5.5 }}
{{ 5.5 > 5.5 }}
{{ 5.5 >= 5.5 }}
取模、取余 remainders
{{ (simple.number+7)%7 }}
{{ (simple.number+7)%7 == 0 }}
{{ (simple.number+7)%6 }}
判断一个变量是否在另一个结果集中 in/not in
{{ 5 in simple.intmap }}
{{ 2 in simple.intmap }}
{{ 7 in simple.intmap }}
{{ !(5 in simple.intmap) }}
{{ not(7 in simple.intmap) }}
{{ 1 in simple.multiple_item_list }}
{{ 4 in simple.multiple_item_list }}
{{ !(4 in simple.multiple_item_list) }}
{{ "Hello" in simple.misc_list }}
{{ "Hello2" in simple.misc_list }}
{{ 99 in simple.misc_list }}
{{ False in simple.misc_list }}
associativity for infix operators
{{ 34/3*3 }}
{{ 10 + 24 / 6 / 2 }}
{{ 6 - 4 - 2 }}
int const与uint比较 uint comparison with int const
{{ simple.uint }}
{{ simple.uint == 8 }}
{{ simple.uint == 9 }}
{{ simple.uint >= 8 }}
{{ simple.uint <= 8 }}
{{ simple.uint < 8 }}
{{ simple.uint > 8 }}
移除模板逻辑标签占用的行
-
{%- if false %}
1st choice
{%- elif false %}
2nd choice
{%- elif true %}
3rd choice
{%- endif %}
正常下
{% for item in articles %}
{{ item.Id }}
{% endfor %}
紧凑:
{% for item in articles %}
{{- item.Id }}
{% endfor %}
不带换行
{% for item in articles -%}
{{ item.Id }}
{%- endfor %}
在模板中使用struct结构体内置方法
func (article *Article) GetThumb()
{% for item in articles %}
<li class="item">
<a href="/article/{{item.Id}}" class="link">
<img src="{{item.GetThumb()}}" alt="{{item.Title}}" />
<h5 class="title">{{item.Title}}</h5>
</a>
</li>
{% endfor %}
{{item.GetThumb()}}article.GetThumb()
在模板中定义变量并赋值
iris.Djangowithwith
{% with title="这是声明给header使用的title" keywords="这是声明给header使用的keywords" %} %}标题:{{title}},关键词:{{keywords}}。{% endwith %}
{% include "partial/header.html" with title="这是声明给header使用的title" keywords="这是声明给header使用的keywords" %}
withendwith
iris.Djangoset
{% set new_var = "hello" %}{{ new_var }}
{% block content %}{% set new_var = "world" %}{{ new_var }}{% endblock %}
{{ new_var }}{% for item in simple.misc_list %}
{% set new_var = item %}{{ new_var }}{% endfor %}
{{ new_var }}
{% set car=someUndefinedVar %}{{ car.Drive }}No Panic
在模板中输出当前时间
now
{% now "Mon Jan 2 15:04:05 -0700 MST 2006" fake %}
{% now "2006-01-02 15:04" %}
lorem
显示随机的“ lorem ipsum”拉丁文本。 这对于在模板中提供样本数据很有用。也就是占位内容。在开发模板没有真实数据的时候,使用这个标签可以快速填充足够多的随机数据。如:
-----
{% lorem %}
-----
{% lorem 10 %}
-----
{% lorem 3 p %}
-----
{% lorem 100 w %}
-----
模板的注释
iris.Django{# 注释内容 #}
{# 这只能注释单行 #}{% comment %}这里注释很多行{% endcomment %}
示例:
空单行注释
{# #}
单行注释
{# testing single line comment #}
用有效标签填充单行注释
{# testing single line comment {% if thing %}{% endif %} #}
用无效标签填充单行注释
{# testing single line comment {% if thing %} #}
用无效语法填充单行注释
{# testing single line comment {% if thing('') %}wow{% endif %} #}
空块注释
{% comment %}{% endcomment %}
填充文本单行块注释
{% comment %}filled block comment {% endcomment %}
空多行块注释
{% comment %}
{% endcomment %}
阻止带有其他标签的注释
{% comment %}
{{ thing_goes_here }}
{% if stuff %}do stuff{% endif %}
{% endcomment %}
阻止其中带有无效标签的注释
{% comment %}
{% if thing %}
{% endcomment %}
使用无效语法阻止注释
{% comment %}
{% thing('') %}
{% endcomment %}
注释之间的常规标签,以确保其在词法分析器中不会中断
{% if hello %}
{% endif %}
after if
{% comment %}All done{% endcomment %}
后端传递变量到模板
ctx.ViewData("article", 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: "<div>内容在此</div>",
},
}
ctx.ViewData("article", article)
ctx.View("index.html")
}
然后在index.html模板中输出:
这样,就模板就获得了article变量,然后通过模板语法,将article的成员都输出了。
完整的项目示例代码托管在GitHub上,需要查看完整的项目代码可以到github.com/fesiong/goblog 上查看,也可以直接fork一份来在上面做修改。