前置准备
什么是 Liquid?
一句话说明
Liquid 允许开发者在 Shopify 主题中嵌入逻辑、循环和变量,以动态生成 HTML
Liquid 是一门开源的模板语言,由 Shopify 创造并用 Ruby 实现。它是 Shopify 主题的骨骼,并且被用于加载店铺系统的动态内容。
从 2006 年起,Liquid 就被 Shopify 所使用,现在更是被大量 web 应用所使用。
中文教程 https://liquid.bootcss.com
Liquid官方概述 https://shopify.dev/docs/api/liquid
Shopify 主题开发教程:Shopify Dev Docs,深入讲解 Liquid 在 Shopify 中的应用。
VS Code
安装 Liquid
插件(如 vscode-liquid
)以支持语法高亮
liquidjs 案例
基础
注释
<!-- ... -->: 这是标准的 HTML 注释
{% comment %} ... {% endcomment %}: 这是 Liquid 特有的注释标签
仅不会显示在页面中,而且会被 Liquid 解析器完全移除,不会出现在最终的 HTML 源代码中。
对象
{{
和 }}
用于输出变量、对象属性或表达式的值。它们是 Liquid 中最基本的输出方式。
{{ page.title }}
{{
和 }}
用于输出变量、对象属性或表达式的值。它们是 Liquid 中最基本的输出方式。
标记(tag){% %}
标记(tag) 创造了模板的逻辑和控制流。他们由单括号加百分号标识:{%
和 %}
。
标记(tag)并不产生任何可见的文本输出。这意味着你可以用他们为变量赋值、创建条件和循环逻辑,并且不在页面上显示出任何 Liquid 逻辑代码。
{% if user %}
Hello {{ user.name }}!
{% endif %}
控制流
if
{% if product.title == 'Awesome Shoes' %}
These shoes are awesome!
{% endif %}
unless
{% unless product.title == 'Awesome Shoes' %}
These shoes are not awesome.
{% endunless %}
elsif / else
<!-- If customer.name = 'anonymous' -->
{% if customer.name == 'kevin' %}
Hey Kevin!
{% elsif customer.name == 'anonymous' %}
Hey Anonymous!
{% else %}
Hi Stranger!
{% endif %}
case/when
{% 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)用于重复运行一段代码。
不同于 Java,Liquid 需要手动标记 for/if
循环的结束
-
endfor
: 标记for
循环的结束。它告诉 Liquid 循环体到此结束,应该返回到循环的开始,进行下一次迭代 (如果还有剩余的迭代)。如果没有endfor
,Liquid 引擎将无法确定循环的结束位置,导致模板解析错误。 -
endif
: 标记if
条件语句的结束。它告诉 Liquidif
语句块到此结束。如果没有endif
,Liquid 引擎将无法确定条件块的结束位置,导致模板解析错误 -
for
`for` 循环中所能够使用的`属性`在 shopify 官方文档
{% for product in collection.products %}
{{ product.title }}
{% endfor %}
break
{% for i in (1..5) %}
{% if i == 4 %}
{% break %}
{% else %}
{{ i }}
{% endif %}
{% endfor %}
continue
{% for i in (1..5) %}
{% if i == 4 %}
{% continue %}
{% else %}
{{ i }}
{% endif %}
{% endfor %}
limit
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{ item }}
{% endfor %}
1 2
offset
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array offset:2 %}
{{ item }}
{% endfor %}
3 4 5 6
range
{% for i in (3..5) %}
{{ i }}
{% endfor %}
{% assign num = 4 %}
{% for i in (1..num) %}
{{ i }}
{% endfor %}
3 4 5
1 2 3 4
reversed
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array reversed %}
{{ item }}
{% endfor %}
6 5 4 3 2 1
cycle
循环一组字符串并按照它们传入的顺序将其输出。
每次调用 cycle
时,传入的参数中的下一个字符串将被输出。
cycle
必须用在 for 循环中。
输入
cycle 的使用场景包括:
对表格中的奇数/偶数行输出相应的类(class)
在一行中的最后一列输出一个唯一的类(class)
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
{% cycle 'one', 'two', 'three' %}
one
two
three
one
{% for item in (1..4) %}
<div class="{% cycle 'odd', 'even' %}">Item {{ item }}</div>
{% endfor %}
类似 Java 中
String[] classes = {"odd", "even"};
int cycleIndex = 0;
for (int i = 1; i <= 4; i++) {
System.out.println("<div class=\"" + classes[cycleIndex] + "\">Item " + i + "</div>");
cycleIndex = (cycleIndex + 1) % classes.length;
}
cycle (parameters)
cycle
能够接受一个叫做 cycle group
的参数,以便满足你在模版中需要使用多个 cycle
代码块的情况。如果没有为 cycle group 命名,那么将会假定带有相同参数的 cycle 调用属于同一个组(group)。
tablerow
生成一个 HTML 表格。必须用 <table>
和 </table>
这两个 HTML 标签将其包裹起来。
参数 :
cols
: 指定多少列,不填就是 1 行包括全部数据limit
和offset
: 与for
循环中的含义相同,用于限制循环的次数和起始位置,limit
在执行到指定的脚标(index)之后退出 tablerow,offset
在指定的脚标(index)之后开始执行 tablerow 。range
定义循环执行的范围。可利用数字和变量来定义执行范围。
表格生成一行,列出所有product.title
<table>
{% tablerow product in collection.products %}
{{ product.title }}
{% endtablerow %}
</table>
表格生成三列,列出所有product.title
<table>
{% tablerow product in collection.products cols:3 %}
{{ product.title }}
{% endtablerow %}
</table>
表格生成两列,且只读取前三个数据,列出所有product.title
{% tablerow product in collection.products cols:2 limit:3 %}
{{ product.title }}
{% endtablerow %}
{% tablerow product in collection.products cols:2 offset:3 %}
{{ product.title }}
{% endtablerow %}
<!--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>
变量
变量标记(variable tag)用于创建新的 Liquid 变量。
assign
{% assign my_variable = false %}
{% if my_variable != true %}
This statement is valid.
{% endif %}
变量用 "
包裹之后则将其当做字符串对待
{% assign foo = "bar" %}
{{ foo }}
capture
将 capture
开始与结束标记之间的字符串捕获之后赋值给一个变量。通过 {% capture %}
创建的变量都是字符串。
{% capture my_variable %}I am being captured.{% endcapture %}
{{ my_variable }}
输出
I am being captured
{% assign favorite_food = 'pizza' %}
{% assign age = 35 %}
{% capture about_me %}
I am {{ age }} and my favorite food is {{ favorite_food }}.
{% endcapture %}
{{ about_me }}
输出
I am 35 and my favourite food is pizza
increment
{% increment my_counter %}
{% increment my_counter %}
{% increment my_counter %}
my_counter的值会被自动添加
0
1
2
通过 increment
标记(tag)创建的变量与通过 assign
或 capture
创建的变量是相互独立的。
在下面的实例中,名为 “var” 的变量是通过 assign
创建的。然后将 increment
标记(tag)在相同的变量名上应用了几次。注意,increment
标记(tag)不会对 assign
创建的变量 “var” 及其值产生任何影响。
{% assign var = 10 %}
{% increment var %}
{% increment var %}
{% increment var %}
{{ var }}
0
1
2
10
decrement
{% decrement variable %}
{% decrement variable %}
{% decrement variable %}
-1
-2
-3
原始内容
raw
标记在 Liquid 中用于告诉模板引擎:不要解析或执行 {% raw %}
和 {% endraw %}
标记之间的任何内容,直接按照字面意思输出即可。
如果输出的内容与 Liquid 模板语言有冲突时(例如 Mustache、Handlebars 模板语言)可以避免冲突。
{% raw %}
In Handlebars, {{ this }} will be HTML-escaped, but
{{{ that }}} will not.
{% endraw %}
输出
In Handlebars, {{ this }} will be HTML-escaped, but {{{ that }}} will not.
过滤器
过滤器 改变 Liquid 对象的输出。他们被用在输出上,通过一个 |
符号分隔
{{ "/my/fancy/url" | append: ".html" }}
输出
/my/fancy/url.html
多个过滤器可以共同作用于同一个输出,并按照从左到右的顺序执行。
输入
{{ "adam!" | capitalize | prepend: "Hello " }}
输出
Hello Adam!
控制输出的空白符
在 Liquid 模版中,你可以将连字符放在标记(tag)中,例如 {{-
、-}}
、{%-
和 -%}
,用于将标记(tag)渲染之后的输出内容的左侧或右侧的空拍符剔除。
通常,即使不输出文本,模版中的任何 Liquid 表达式仍然会在渲染之后输出的 HTML 中包含一个空行:
输入
{% assign my_variable = "tomato" %}
{{ my_variable }}
请注意渲染之后输出的 “tomato” 字符前面包含了一个空行:
输出
tomato
通过为 assign
标记(tag)添加连字符,可以将渲染之后所输出的空拍符删除:
输入
{%- assign my_variable = "tomato" -%}
{{ my_variable }}
输出
tomato
如果你不希望任何标记(tag)被渲染之后所输出的内容有任何空白符,只需在所有标记(tag)两侧全部添加连字符即可,例如 ({%-
和 -%}
):
输入
{% assign username = "John G. Chalmers-Smith" %}
{% if username and username.size > 10 %}
Wow, {{ username }}, you have a long name!
{% else %}
Hello there!
{% endif %}
不做空白符控制的输出
Wow, John G. Chalmers-Smith, you have a long name!
输入
{%- assign username = "John G. Chalmers-Smith" -%}
{%- if username and username.size > 10 -%}
Wow, {{ username }}, you have a long name!
{%- else -%}
Hello there!
{%- endif -%}
带有空白符控制的输出
Wow, John G. Chalmers-Smith, you have a long name!