Interstellar
Interstellar
发布于 2025-05-05 / 17 阅读
1
0

Liquid语言

前置准备

什么是 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 条件语句的结束。它告诉 Liquid if 语句块到此结束。如果没有 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!

评论