模版渲染 - 模板标签和过滤器基础
6.2 模板标签和过滤器基础
我们已经提到模板系统使用内建的标签和过滤器,这里我们看看常见的。
6.2.1 if/else
{% if %}
标签计算一个变量值,如果是 true,即它存在、不为空并且不是 false 的布尔值
系统则会显示 {% if %}
和 {% endif %}
间的所有内容:
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% else %}
<p>Get back to work.</p>
{% endif %}
{% if %}
标签接受 and
、or
或者 not
来测试多个变量值或者否定一个给定的变量,例如:
{% if athlete_list and coach_list %}
Both athletes and coaches are available.
{% endif %}
{% if not athlete_list %}
There are no athletes.
{% endif %}
{% if athlete_list or coach_list %}
There are some athletes or some coaches.
{% endif %}
{% if not athlete_list or coach_list %}
There are no athletes or there are some coaches.
{% endif %}
{% if athlete_list and not coach_list %}
There are some athletes and absolutely no coaches.
{% endif %}
{% if %}
标签 &&
等同于 and
,||
等同于 or
:
{% if user.is_moderator && (user.moderation_level > 2 || user.moderation_level <= 0) %}
...
{% else %}
...
{% endif %}
如果你想结合 and
和 or
来做高级逻辑,只需使用嵌套的 {% if %}
标签即可:
{% if athlete_list %}
{% if coach_list or cheerleader_list %}
We have athletes, and either coaches or cheerleaders!
{% endif %}
{% endif %}
多次使用同一个逻辑符号是合法的:
{% if athlete_list or coach_list or parent_list or teacher_list %}
没有 {% elif %}
标签,使用嵌套的 {% if %}
标签可以做到同样的事情:
{% if athlete_list %}
<p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
<p>No athletes are available.</p>
{% if coach_list %}
<p>Here are the coaches: {{ coach_list }}.</p>
{% endif %}
{% endif %}
注: 必须使用 {% endif %}
来关闭 {% if %}
标签。
6.2.2 for
{% for %}
标签允许你按顺序遍历一个序列中的各个元素
Go的for语句语法为 for X in Y
,X 是用来遍历 Y 的变量
每次循环模板系统都会渲染 {% for %}
和 {% endfor %}
之间的所有内容
例如,显示给定athlete_list变量来显示athlete列表:
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
在标签里添加 reversed
来反序循环列表:
{% for athlete in athlete_list reversed %}
...
{% endfor %}
{% for %}
标签可以嵌套:
{% for country in countries %}
<h1>{{ country.name }}</h1>
<ul>
{% for city in country.city_list %}
<li>{{ city }}</li>
{% endfor %}
</ul>
{% endfor %}
{% for key, val in data %}
标签可以获取到map的key值:
{% for k, v in list %}
<ul>
<li>{{ v.name }}: This key is {{ k }}</li>
</ul>
{% endfor %}
系统不支持中断循环,如果你想这样,你可以改变你想遍历的变量来使得变量只包含你想遍历的值
类似的,系统也不支持continue语句
{% for %}
标签内置了一个forloop模板变量,这个变量含有一些属性可以提供给你一些关于循环的信息
1、forloop.Counter
表示循环的次数,它从1开始计数,第一次循环设为1,例如:
{% for item in todo_list %}
<p>{{ forloop.Counter }}: {{ item }}</p>
{% endfor %}
2、forloop.Counter0
类似于 forloop.Counter
,但它是从0开始计数,第一次循环设为0
3、forloop.Revcounter
表示循环中剩下的items数量,第一次循环时设为items总数,最后一次设为1
4、forloop.Revcounter0
类似于 forloop.Revcounter
,但它是表示的数量少一个,即最后一次循环时设为0
5、forloop.First
当第一次循环时值为 true,在特别情况下很有用:
{% for object in objects %}
{% if forloop.First %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}
6、forloop.Last
当最后一次循环时值为true
{% for link in links %}{{ link }}{% if not forloop.Last %} | {% endif %}{% endfor %}
7、forloop.Parentloop
在嵌套循环中表示父循环的forloop:
{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.Parentloop.Counter }} </td>
<td>City #{{ forloop.Counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
富有魔性的 forloop
变量:
- 在for标签作用域中被自动创建为临时变量
- for标签内不要使用自定义的
forloop
变量,它会被自动创建的同名的临时变量覆盖 - for标签之外,名称为
forloop
的变量仍然可用
6.2.3 ifequal/ifnotequal
模板系统并不是一个严格意义上的编程语言,所以它并不允许我们执行Go语句
然而在模板语言里比较两个值并且在他们一致的时候显示一些内容,确实是一个在常见不过的需求了——所以模版提供了ifequal标签。
{% ifequal %}
比较两个值,如果相等,则显示 {% ifequal %}和{% endifequal %}
之间的所有内容:
{% ifequal user currentuser %}
<h1>Welcome!</h1>
{% endifequal %}
参数可以是硬编码的string,单引号和双引号均可,下面的代码是合法的:
{% ifequal section 'sitenews' %}
<h1>Site News</h1>
{% endifequal %}
{% ifequal section "community" %}
<h1>Community</h1>
{% endifequal %}
和 {% if %}
一样,{% ifequal %}
标签支持 {% else %}
{% ifequal section 'sitenews' %}
<h1>Site News</h1>
{% else %}
<h1>No News Here</h1>
{% endifequal %}
其它的模板变量,strings,integers和小数都可以作为 {% ifequal %}
的参数:
{% ifequal variable 1 %}
{% ifequal variable 1.23 %}
{% ifequal variable 'foo' %}
{% ifequal variable "foo" %}
其它的Go类型,如数组、切片或布尔值不能硬编码在 {% ifequal %}
里面,下面是不合法的:
{% ifequal variable true %}
{% ifequal variable [1, 2, 3,]%}
{% ifequal variable {'key': 'value'} %
如果你需要判断某个变量是true或false,用 {% if %}
即可。
6.2.4 注释
和HTML或编程语言如Go一样,模板语言允许注释 {# #}
,如:
{# This is a comment #}
模板渲染时注释不会输出,一个注释不能分成多行
下面的模板渲染时会和模板中的内容一样,注释标签不会解析成注释
This is a {# comment goes here
and spans another line #}
test.
6.2.5 过滤器
模板过滤器是变量显示前转换它们的值的方式,看起来像下面这样:
{{ name|lower }}
这将显示通过 lower
过滤器过滤后 {{ name }}
变量的值,它将文本转换成小写
使用 |
管道来申请一个过滤器
过滤器可以串成链,即一个过滤器的结果可以传向下一个
下面是escape文本内容然后把换行转换成p标签的习惯用法:
{{ my_text|escape|linebreaks }}
有些过滤器需要参数,需要参数的过滤器的样子:
{{ bio|truncatechars:"30" }}
这将显示bio标量的前30个字,过滤器参数一直使用双引号
下面是一些最重要的过滤器:
1、addslashes
在任何 \
、'
、"
前添加一个 \
,当你把一些文本输出到一个JavaScript字符串时这会十分有用。
2、date
根据一个格式化string参数来格式化 time.Time
对象,例如:
{{ pub_date|date:"2006-01-02 15:04:05" }}
3、escape
避免给定的string里出现 &
、"
、'
、<
、>
当你处理用户提交的数据和确认合法的XML和XHTML数据时这将很有用
escape
将作如下的一些转换:
Converts & to &amp;
Converts < to &lt;
Converts > to &gt;
Converts "(双引号) to &quot;
Converts '(单引号) to &#39;
4、length
返回值的长度,你可以在一个list或string上做此操作,或者在任何知道怎样决定自己的长度的Go对象上做此操作。