Skip to content

Latest commit

 

History

History
317 lines (229 loc) · 8.69 KB

06.02.md

File metadata and controls

317 lines (229 loc) · 8.69 KB

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 %} 标签接受 andor 或者 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 %}

如果你想结合 andor 来做高级逻辑,只需使用嵌套的 {% 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;amp;  
Converts < to &amp;lt;  
Converts > to &amp;gt;  
Converts "(双引号) to &amp;quot;  
Converts '(单引号) to &amp;#39; 

4、length 返回值的长度,你可以在一个list或string上做此操作,或者在任何知道怎样决定自己的长度的Go对象上做此操作。

links