Liquid 开发 · 整理与归档

Liquid 变量与对象访问

Liquid 变量与对象访问 Shopify 主题里的「变量」是你用 {% assign %} 、 {% capture %} 或循环里自带的 名字 → 值 ;「对象」是平台注入的 product 、 cart 、 shop 等(见

Liquid 变量与对象访问

Shopify 主题里的「变量」是你用 {% assign %}{% capture %} 或循环里自带的 名字 → 值;「对象」是平台注入的 productcartshop 等(见 Shopify 对象参考)。本篇只解决三件事:怎么存值、在哪能用、怎么安全读属性

官方标签说明:assign 、capture 、increment / decrement 。


1. {% assign %}:赋值与类型

Liquid 里变量没有声明类型,值可以是字符串、数字、布尔或对象引用。

{% assign title = product.title %}
{% assign discount = product.price | times: 0.9 %}
{% assign show_vendor = true %}
{% assign css = "product-card product-card--compact" %}
 
<h2 class="{{ css }}">{{ title }}</h2>
<p>{{ discount | money }}</p>

金额product.price 等为 整数最小货币单位(多数币种为「分」),计算后再交给 \| money 格式化,避免按「元」心算又忘了乘除。


2. 作用域:不要套用「块级局部变量」

与 JavaScript 不同,Liquid 里 {% assign %} 没有块级作用域:在同一份模板(或同一 snippet 渲染进程)里,在 for / if 里赋的值,在外面仍能读到,后者会覆盖前者。

{% assign x = "before" %}
{% for i in (1..2) %}
  {% assign x = "in loop" %}
{% endfor %}
{{ x }}

上面最终会输出最后一次写入的 x。若需要在循环里「累计」,用循环变量或单独起名(如 total_quantity),不要假设「出了循环变量就销毁」。

{% assign total = 0 %}
{% for line in cart.items %}
  {% assign total = total | plus: line.quantity %}
{% endfor %}

需要 独立计数器(不影响同名 assign)时,可用 {% increment var %} / {% decrement var %}(适用场景见官方文档)。


3. {% capture %}:拼一整段 HTML 或字符串

capture 会把标签之间的 渲染结果(含换行)存进变量,适合组装一大块 markup,再一次性输出。

{% capture greeting %}
  {% if customer %}
    你好,{{ customer.first_name | escape }}。
  {% else %}
    你好,访客。
  {% endif %}
{% endcapture %}
 
<p>{{ greeting }}</p>

注意:capture 里是 先执行 Liquid 再存字符串,中间若有未定义变量会得到空字符串;对外输出用户内容时仍要对动态片段做 escape 或交给过滤器。


4. 真假值与 blank

常用写法:

意图 推荐
是否有当前客户 {% if customer %}
字符串 / 数组是否有「实质内容」 {% if thing != blank %}
可选字段默认值

不要用其它语言里的 != null:Liquid 里用 blank(Shopify 扩展)判断空字符串、空数组、nil 等更省事。

{% if product.description != blank %}
  <div class="rte">{{ product.description }}</div>
{% endif %}
 
{{ product.metafields.custom.subtitle | default: product.title }}

5. 访问对象属性:点号与 []

{{ product.title }}
{{ product['title'] }}
 
{% assign key = 'vendor' %}
{{ product[key] }}

嵌套时逐级判断,避免中间层为 nil 时连环报错:

{% if customer.default_address %}
  {{ customer.default_address.city }}
{% endif %}

数组:支持 .first / .last、按索引 images[0],以及 {% for %}. 详见 数据类型


6. 与过滤器配合(不要把业务写太胖)

assign 常与过滤器连用;复杂逻辑建议拆给 snippet 或多步 assign,便于读和维护。

{% assign slug = product.title | handleize %}
{% assign excerpt = product.description | strip_html | truncate: 160 %}

易错where 用于 数组里筛对象属性,语法为 array | where: '属性名', 值,不能当成 SQL 随意写比较运算符;不确定时查 过滤器 与官方示例。


7. 条件里「间接赋值」

Liquid 没有三元运算符,用 if / elseassign + if 组合:

{% if product.available %}
  {% assign badge_class = 'in-stock' %}
{% else %}
  {% assign badge_class = 'sold-out' %}
{% endif %}
 
<span class="{{ badge_class }}">
  {% if product.available %}现货{% else %}售罄{% endif %}
</span>

8. 命名习惯(保持可读即可)

  • snake_casefeatured_countshow_sale_badge
  • 避免单字母、tmp1,半年后只有自己认识。
  • 布尔含义用前缀:is_has_show_

9. 调试(仅开发 / 预览)

{% if request.design_mode %}
  <pre class="theme-debug">{{ product | json }}</pre>
{% endif %}

勿在生产页面长期输出完整 json,体积与敏感字段都不友好。


10. 常见误区(对照检查)

  1. 以为 for 里的 assign 外面看不见 — 实际上会泄漏到外层,注意变量名冲突。
  2. customer != null — 改用 {% if customer %}!= blank
  3. 在 Liquid 里硬算含税总价 — 结账税费以结算为准,模板里演示类计算务必标注「展示用」。
  4. 一大段 HTML 用字符串 append — 优先 capture 或拆 snippet,否则引号与转义极易出错。

11. 延伸阅读

更细的语法以 Shopify Liquid 参考  为准。