Liquid语法
本博客内容取自Liquid官网
基本元素
对象
对象和变量名由双花括号标识:{{
和 }}
。
标记
标记(tag)创造了模板的逻辑和控制流。由单括号加百分号标识:{%
和 %}
。
标记(tag)并不产生任何可见的文本输出。可以用他们为变量赋值、创建条件和循环逻辑,并且不在页面上显示出任何 Liquid 逻辑代码。
过滤器
过滤器 改变 Liquid 对象的输出。他们被用在输出上,通过一个 |
符号分隔。
操作符
符号 | 含义 |
---|---|
== |
相等 |
!= |
不相等 |
> |
大于 |
< |
小于 |
>= |
大于或等于 |
<= |
小于或等于 |
or |
逻辑或 |
and |
逻辑与 |
contains
:
- 检查在一个字符串中是否存在某个子串
- 检查一个字符串数组中是否存在某个字符串
- 只能用于搜索字符串
真值和假值
在条件判断中任何返回 true
的都被叫做 真值(truthy)。任何返回 false
的都被叫做 假值(falsy)。
所有的对象(object)类型都可以被描述为真值(truthy)或假值(falsy)。即便是空字符串,也是真值。
除了 nil
和 false
之外的所有值都是真值。
nil
和 false
是假值。
数据类型
String(字符串)
将变量的值包裹在单引号或双引号之中就声明了一个字符串:
1
{% assign my_string = "Hello World!" %}
Number(数字)
数字类型包括浮点数和整数:
1
2
{% assign my_int = 25 %}
{% assign my_float = 39.756 %}
Boolean(布尔)
Booleans 类型只能是 true
或 false
。布尔值不能加引号。
1
2
{% assign foo = true %}
{% assign bar = false %}
Nil(空)
Nil 是一个特殊的空值,当 Liquid 代码没有可输出的结果时将返回 Nil。
并不是由 “nil” 这个三个字符组成的字符串。
如果 Liquid 标记(tag)或输出返回的是 nil
,页面上将不会有任何内容。
Array(数组)
数组能够存储一组任意类型的变量。
访问数组中的项
通过 迭代标记(iteration tag)可以访问数组中的所有项。
1
2
3
4
<!-- if site.users = "Tobi", "Laura", "Tetsuro", "Adam" -->
{% for user in site.users %}
{{ user }}
{% endfor %}
访问数组中的特定项
利用方括号 [
]
能够访问数组中的特定项。数组的索引从 0 开始。
1
2
3
4
<!-- if site.users = "Tobi", "Laura", "Tetsuro", "Adam" -->
{{ site.users[0] }}
{{ site.users[1] }}
{{ site.users[3] }}
初始化数组
无法只通过 Liquid 语法初始化一个数组。
控制输出的空白符
可以将连字符放在标记(tag)中,例如 {{-
、-}}
、{%-
和 -%}
,用于将标记(tag)渲染之后的输出内容的左侧或右侧的空白符剔除。
1
2
{% assign my_variable = "tomato" %}
{{ my_variable }}
这样输出的内容有空白行
1
2
{%- assign my_variable = "tomato" -%}
{{ my_variable }}
这样就没了。
注释
comment
标记让你能够在 Liquid 模板中书写的内容不被输出。
任何书写在 comment
起始与endcomment
结束之间的内容都不会被输出,如果是 Liquid 代码则不会被执行。
输入
1
Anything you put between {% comment %} and {% endcomment %} tags
输出
1
Anything you put between tags
条件语句
if
只有当某个条件为 true
时才执行一段代码。
1
2
3
{% if product.title == 'Awesome Shoes' %}
These shoes are awesome!
{% endif %}
unless
与 if
相对 – 只有当某个条件不成立时才执行一段代码。
1
2
3
{% unless product.title == 'Awesome Shoes' %}
These shoes are not awesome.
{% endunless %}
和下例的执行结果一致:
1
2
3
{% if product.title != 'Awesome Shoes' %}
These shoes are not awesome.
{% endif %}
elsif / else
为 if
或 unless
添加更多状态判断。
1
2
3
4
5
6
7
8
<!-- If customer.name = 'anonymous' -->
{% if customer.name == 'kevin' %}
Hey Kevin!
{% elsif customer.name == 'anonymous' %}
Hey Anonymous!
{% else %}
Hi Stranger!
{% endif %}
case/when
创建一个开关表达式,用于将一个变量和多个不同值进行比较。
case
用于初始化一个开关表达式,when
用于比较他们的值。
1
2
3
4
5
6
7
8
9
{% assign handle = 'cake' %}
{% case handle %}
{% when 'cake' %}
This is a cake
{% when 'cookie' %}
This is a cookie
{% else %}
This is not a cake nor a cookie
{% endcase %}
循环语句
循环标记(iteration tag)用于重复运行一段代码。
for
重复运行一段代码。
1
2
3
{% for product in collection.products %}
{{ product.title }}
{% endfor %}
break
循环过程中若干遇到 break
标记(tag){% break %}
即停止循环。
continue
循环过程中若遇到 continue
标记(tag){% continue %}
则跳出当前循环。
for (parameters)
limit
限定循环执行的次数。
输入
1
2
3
4
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{ item }}
{% endfor %}
输出
1
1 2
offset
从指定索引号开始执行循环。
输
1
2
3
4
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array offset:2 %}
{{ item }}
{% endfor %}
输出
1
3 4 5 6
range
定义循环执行的范围。可利用数字或变量来定义此执行范围。
输入
1
2
3
4
5
6
7
8
{% for i in (3..5) %}
{{ i }}
{% endfor %}
{% assign num = 4 %}
{% for i in (1..num) %}
{{ i }}
{% endfor %}
输出
1
2
3 4 5
1 2 3 4
reversed
反转循环的执行顺序。注意和 reverse
过滤器(filter)的拼写是不同的。
输入
1
2
3
4
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array reversed %}
{{ item }}
{% endfor %}
输出
1
6 5 4 3 2 1
tablerow
生成一个 HTML 表格。必须用 <table>
和 </table>
这两个 HTML 标签将其包裹起来。
输入
1
2
3
4
5
<table>
{% tablerow product in collection.products %}
{{ product.title }}
{% endtablerow %}
</table>
输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<table>
<tr class="row1">
<td class="col1">
Cool Shirt
</td>
<td class="col2">
Alien Poster
</td>
<td class="col3">
Batman Poster
</td>
<td class="col4">
Bullseye Shirt
</td>
<td class="col5">
Another Classic Vinyl
</td>
<td class="col6">
Awesome Jeans
</td>
</tr>
</table>
tablerow (parameters)
cols
定义表格应当有多少列。
输入
1
2
3
{% tablerow product in collection.products cols:2 %}
{{ product.title }}
{% endtablerow %}
输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<table>
<tr class="row1">
<td class="col1">
Cool Shirt
</td>
<td class="col2">
Alien Poster
</td>
</tr>
<tr class="row2">
<td class="col1">
Batman Poster
</td>
<td class="col2">
Bullseye Shirt
</td>
</tr>
<tr class="row3">
<td class="col1">
Another Classic Vinyl
</td>
<td class="col2">
Awesome Jeans
</td>
</tr>
</table>
limit
在执行到指定的脚标(index)之后退出 tablerow 。
1
2
3
{% tablerow product in collection.products cols:2 limit:3 %}
{{ product.title }}
{% endtablerow %}
offset
在指定的脚标(index)之后开始执行 tablerow 。
1
2
3
{% tablerow product in collection.products cols:2 offset:3 %}
{{ product.title }}
{% endtablerow %}
range
定义循环执行的范围。可利用数字和变量来定义执行范围。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!--variable number example-->
{% assign num = 4 %}
<table>
{% tablerow i in (1..num) %}
{{ i }}
{% endtablerow %}
</table>
<!--literal number example-->
<table>
{% tablerow i in (3..5) %}
{{ i }}
{% endtablerow %}
</table>
输出原始内容
raw
标记临时禁止处理其所包围的代码。
如果输出的内容与 Liquid 模板语言有冲突时(例如 Mustache、Handlebars 模板语言)可以避免冲突。
输入
1
2
3
4
In Handlebars, {{ this }} will be HTML-escaped, but
{{{ that }}} will not.
输出
1
In Handlebars, {{ this }} will be HTML-escaped, but {{{ that }}} will not.
变量
变量标记(variable tag)用于创建新的 Liquid 变量。
assign
创建一个新变量。
1
{% assign my_variable = false %}
capture
将 capture
开始与结束标记之间的字符串捕获之后赋值给一个变量。
通过 {% capture %}
创建的变量都是字符串。
输入
1
2
{% capture my_variable %}I am being captured.{% endcapture %}
{{ my_variable }}
输出
1
I am being captured.
capture
开始与结束标记之间的字符串可以包含定义的其他变量。
1
2
3
{% capture about_me %}
I am {{ age }} and my favorite food is {{ favorite_food }}.
{% endcapture %}
increment
创建一个全新的数值变量,并且在后续每次调用时将此变量的值加 1。初始值是 0。
输入
1
2
3
{% increment my_counter %}
{% increment my_counter %}
{% increment my_counter %}
输出
1
2
3
0
1
2
通过 increment
标记(tag)创建的变量与通过 assign
或 capture
创建的变量是相互独立的。
在下面的实例中,名为 “var” 的变量是通过 assign
创建的。然后将 increment
标记(tag)在相同的变量名上应用了几次。注意,increment
标记(tag)不会对 assign
创建的变量 “var” 及其值产生任何影响。
输入
1
2
3
4
5
{% assign var = 10 %}
{% increment var %}
{% increment var %}
{% increment var %}
{{ var }}
输出
1
2
3
4
0
1
2
10
decrement
创建一个全新的数值变量,并且在后续每次调用时将此变量的值减 1。初始值是 -1。
输入
1
2
3
{% decrement variable %}
{% decrement variable %}
{% decrement variable %}
输出
1
2
3
-1
-2
-3
和 increment 类似,在 decrement
之中创建的变量与通过 assign
或 capture
创建的变量是互相独立的。
过滤器
abs
返回一个数字的绝对值。
如果组成字符串的各个字符全是数字,abs
也能够对此字符串求绝对值。
append
将两个字符串拼接起来并返回拼接之后的值。
1
{{ "/my/fancy/url" | append: ".html" }}
append
同样能够作用于变量:
1
2
{% assign filename = "/index.html" %}
{{ "website.com" | append: filename }}
at_least
将数字限制在最小值。
输入
1
{{ 4 | at_least: 5 }}
输出
1
5
输入
1
{{ 4 | at_least: 3 }}
输出
1
4
at_most
将数字限制在最大值。
输入
1
{{ 4 | at_most: 5 }}
输出
1
4
输入
1
{{ 4 | at_most: 3 }}
输出
1
3
capitalize
将字符串首字母转为大写。
ceil
将一个浮点数向上取整并返回一个最接近的整数。
在 ceil 过滤器执行之前 Liquid 会先尝试将输入转换为数字格式。
compact
删除数组中的所有 nil
值。
concat
连接数组
date
将时间戳(timestamp)转换为另一种日期格式
1
2
3
4
5
{{ article.published_at | date: "%a, %b %d, %y" }}
{{ article.published_at | date: "%Y" }}
{{ "now" | date: "%Y-%m-%d %H:%M" }}
将 "now"
(或 "today"
) 单词传入 date
过滤器可以获取当前时间:
default
指定一个默认值,以防预期的值不存在。如果左侧的值为 nil
、false
或空,default
将输出此默认值。
如下实例中,product_price
并未被定义,因此将输出默认值。
输入
1
{{ product_price | default: 2.99 }}
输出
1
2.99
如下实例中,product_price
已被定义,不再输出默认值。
输入
1
2
{% assign product_price = 4.99 %}
{{ product_price | default: 2.99 }}
输出
1
4.99
如下实例中,product_price
的值为空,因此将输出默认值。
输入
1
2
{% assign product_price = "" %}
{{ product_price | default: 2.99 }}
输出
1
2.99
divided_by
将两个数相除。
如果除数(divisor)为整数,则将相除之后得到的结果向下取整得到最接近的整数
divided_by
返回的结果于除数是同一数据类型的,如果除数是整数,返回的结果也是整数;如果除数是浮点数(带有小数),返回的结果也是浮点数。
downcase
用于将字符串中的各个字符转换为小写形式
escape
对字符串转义操作就是将字符串中的某些字符替换为转义序列(escape sequence),这样整个字符串就能够用于 URL 了。如果字符串不需要转义则不会对字符串做任何操作。
escape_once
转义一个字符串并且不修改已经转义过的实体(entities)。对于无须转义的字符串不做任何修改。
输入
1
{{ "1 < 2 & 3" | escape_once }}
输出
1
1 < 2 & 3
first
返回数组的第一项。
1
{{ my_array.first }}
floor
将一个浮点数通过舍弃小数部分得到最近的整数。
在 floor 过滤器执行之前 Liquid 会先尝试将输入转换为数字格式。
join
将数组中的各个字符串合并为一个字符串,并将参数作为字符串之间的分隔符。
输入
1
2
3
{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}
{{ beatles | join: " and " }}
输出
1
John and Paul and George and Ringo
last
返回数组中的最后一项。
1
2
3
{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}
{{ my_array.last }}
lstrip
删除字符串左侧的所有空白符(制表符、空格和换行符)。字符串中间的所有空白符不受影响。
map
从对象(object)中提取指定名称的属性的值,并用这些值构建一个数组。
以下实例中,假定 site.pages
包含了整个网站的元数据信息。
利用 assign
和 map
过滤器创建一个变量,此变量只包含 site.pages
对象中 category
属性对应的所有值。
1
{% assign all_categories = site.pages | map: "category" %}
minus
从一个数中减去另一个数。
modulo
返回除法运算的余数。
newline_to_br
将所有换行符(\n
) 替换为 HTML 的 (<br>
) 标签。
输入
1
2
3
4
5
6
{% capture string_with_newlines %}
Hello
there
{% endcapture %}
{{ string_with_newlines | newline_to_br }}
输出
1
2
3
<br />
Hello<br />
there<br />
plus
两个数相加。
prepend
在一个字符串前面附加另一个字符串,也能作用于变量:
输入
1
2
3
{% assign url = "example.com" %}
{{ "/index.html" | prepend: url }}
remove
从一个字符串中删除所有出现的另一个子字符串。
输入
1
{{ "I strained to see the train through the rain" | remove: "rain" }}
remove_first
从一个字符串中仅仅删除第一次出现的另一个子字符串。
replace
将参数中给出的第一个参数全部替换为第二个参数。
1
{{ "Take my protein pills and put my helmet on" | replace: "my", "your" }}
replace_first
将字符串中出现的第一个参数替换为第二个参数。
reverse
将数组中的所有项的顺序反转。
reverse
不能直接应用到字符串上,但是可以先将字符串分割成字符数组,然后再将数组反转,最后将反转之后的数组合并。
1
{{ "Ground control to Major Tom." | split: "" | reverse | join: "" }}
round
将浮点数舍入到最近的整数,或者,如果传入的参数是一个数值的话,将浮点数舍入到参数指定的小数位。
1
2
{{ 183.357 | round: 2 }}
{{ 2.7 | round }}
rstrip
将字符串右侧的所有空白字符(制表符 - tab、空格符 - space 和 回车符 - newline)删除。
size
返回字符串中所包含的字符数或者数组中所包含的条目数量。
size
还支持“点标记”(例如 {{ my_string.size }}
)。这种用法便于在标签(tag)中使用 size
过滤器,例如条件判断标签(tag)。
1
2
3
4
5
{{ "Ground control to Major Tom." | size }}
{% if site.pages.size > 10 %}
This is a big website!
{% endif %}
slice
只传入一个参数时将返回此参数作为下标所对应的单个字符。(负数则从后向前数,找到起始位置)
第二个参数是可选的,用于指定返回的子字符串的长度。(不管第一个参数,总是从前向后数找n个)
1
{{ "Liquid" | slice: -3, 2 }} //输出ui
sort
对数组中的所有进行排序。排序后的数组是按照区分大小写的顺序排列的。
sort_natural
对数组进行排序,并且大小写无关。
split
根据参数传入的分隔符将字符串分解为数组。
split
通常被用于将以逗号为分隔符的字符串转换为数组。
1
{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}
strip
删除字符串左右两侧的所有空白符号(包括制表符、空格、换行符)。
strip_html
从字符串中删除所有 HTML 标签。
strip_newlines
从字符串中删除所有换行字符(newline character)。
times
将一个数乘以另一个数。
truncate
truncate
将字符串截短为指定的字符个数。如果指定的字符数量小于字符串的长度,则会在字符串末尾添加一个省略号(…) 并将此省略号计入字符个数中。
输入
1
{{ "Ground control to Major Tom." | truncate: 20 }}
输出
1
Ground control to...
自定义省略号
truncate
还支持第二个可选参数,用于指定一个字符序列,此字符序列将被添加到截短字符串的后面。
默认是省略号(…),但是你可以按照你的需要传递一个新的。
第二个参数的长度将被计入第一个参数的字符个数中。
例如,如果你希望将字符串截短为 10 个字符,并且使用由 3 个字符组成的省略号,这时,你需要将 truncate
的第一个参数设置为 13,是因为需要计入省略号的 3 个字符。
输入
1
{{ "Ground control to Major Tom." | truncate: 25, ", and so on" }}
输出
1
Ground control, and so on
无省略号
你可以将字符串按照第一个参数截短为指定长度,并且可以通过传递一个空字符作为第二个参数,从而让截短之后的字符串不显示省略号。
输入
1
{{ "Ground control to Major Tom." | truncate: 20, "" }}
输出
1
Ground control to Ma
truncatewords
将字符串截短为指定的单词个数。
如果指定的单词数量小于字符串中包含的单词个数,则会在字符串末尾添加一个省略号(…)。
输入
1
{{ "Ground control to Major Tom." | truncatewords: 3 }}
输出
1
Ground control to...
自定义省略号
truncatewords
还支持第二个可选参数,用于指定一个字符序列,此字符序列将被添加到截短字符串的后面。
默认是省略号(…),但是你可以按照你的需要传递一个新的。
输入
1
{{ "Ground control to Major Tom." | truncatewords: 3, "--" }}
输出
1
Ground control to--
无省略号
如果你不希望在末尾添加省略号,可以将 truncatewords
的第二个参数设置为空字符串:
输入
1
{{ "Ground control to Major Tom." | truncatewords: 3, "" }}
输出
1
Ground control to
uniq
删除数组中的所有冗余项(重复项)。
upcase
将字符串中的每个字符都转换为大写形式。对于已经全是大写的字符串不做任何操作。
url_decode
对通过 url_encode
编码的字符串进行解码。
输入
1
{{ "%27Stop%21%27+said+Fred" | url_decode }}
输出
1
'Stop!' said Fred
url_encode
将字符串中非 URL 安全的字符转换为百分号编码(percent-encoded)的字符。
输入
1
{{ "john@liquid.com" | url_encode }}
输出
1
john%40liquid.com