Skip to Content
🎉 探索 Shopify 的无限可能 结构化知识 + 实战案例,持续更新中...
Liquid 开发对象和属性

对象和属性

在 Liquid 中,对象是包含属性的数据结构。理解对象系统对于有效使用 Shopify 主题开发至关重要。

对象基础概念

什么是对象

<!-- 对象是具有属性的数据结构 --> {{ product.title }} <!-- product 是对象,title 是属性 --> {{ customer.first_name }} <!-- customer 是对象,first_name 是属性 --> {{ shop.name }} <!-- shop 是对象,name 是属性 -->

对象层次结构

<!-- Shopify 对象层次结构示例 --> 全局对象 ├── shop (商店对象) ├── cart (购物车对象) ├── customer (客户对象) └── request (请求对象) 页面特定对象 ├── product (产品对象) ├── collection (集合对象) ├── blog (博客对象) └── article (文章对象)

对象属性访问

点号访问

<!-- 基本属性访问 --> {{ product.title }} {{ product.price }} {{ product.description }} <!-- 嵌套属性访问 --> {{ product.featured_image.alt }} {{ customer.default_address.city }} {{ order.shipping_address.country }} <!-- 深层嵌套访问 --> {{ product.selected_or_first_available_variant.title }} {{ blog.articles.first.author }} {{ cart.items.last.product.vendor }}

方括号访问

<!-- 使用方括号访问属性 --> {{ product['title'] }} {{ customer['first_name'] }} {{ order['created_at'] }} <!-- 动态属性访问 --> {% assign property_name = 'title' %} {{ product[property_name] }} {% assign field = 'first_name' %} {{ customer[field] }}

动态属性访问示例

<!-- 根据用户选择显示不同属性 --> {% assign display_field = settings.product_display_field %} {% case display_field %} {% when 'title' %} {{ product.title }} {% when 'vendor' %} {{ product.vendor }} {% when 'type' %} {{ product.type }} {% else %} {{ product[display_field] }} {% endcase %} <!-- 循环显示多个属性 --> {% assign product_fields = 'title,vendor,type,price' | split: ',' %} <dl class="product-details"> {% for field in product_fields %} <dt>{{ field | capitalize }}:</dt> <dd>{{ product[field] }}</dd> {% endfor %} </dl>

对象存在性检查

检查对象是否存在

<!-- 检查对象本身是否存在 --> {% if customer %} <p>用户已登录: {{ customer.email }}</p> {% else %} <p>用户未登录</p> {% endif %} <!-- 检查嵌套对象是否存在 --> {% if product.featured_image %} <img src="{{ product.featured_image | img_url: '400x400' }}" alt="{{ product.featured_image.alt }}"> {% else %} <div class="no-image-placeholder">暂无图片</div> {% endif %}

检查属性是否存在

<!-- 检查属性是否存在且不为空 --> {% if product.description %} <div class="product-description"> {{ product.description }} </div> {% endif %} <!-- 检查属性是否不为 blank --> {% if product.description != blank %} <div class="product-description"> {{ product.description }} </div> {% endif %} <!-- 检查数组属性是否有内容 --> {% if product.images.size > 0 %} <div class="product-gallery"> {% for image in product.images %} <img src="{{ image | img_url: '300x300' }}" alt="{{ image.alt }}"> {% endfor %} </div> {% endif %}

安全访问模式

<!-- 使用 default 过滤器提供默认值 --> {{ product.description | default: "暂无描述" }} {{ customer.first_name | default: "访客" }} {{ product.featured_image.alt | default: product.title }} <!-- 链式安全访问 --> {% assign image_alt = product.featured_image.alt %} {% if image_alt == blank %} {% assign image_alt = product.title %} {% endif %} {{ image_alt }} <!-- 三级安全访问 --> {% if product.featured_image and product.featured_image.alt %} {{ product.featured_image.alt }} {% elsif product.featured_image %} {{ product.title }} {% else %} 默认图片描述 {% endif %}

对象方法和属性

数组对象方法

<!-- 数组长度 --> {{ product.images.size }} {{ collection.products.size }} {{ customer.addresses.size }} <!-- 第一个和最后一个元素 --> {{ product.images.first }} {{ product.images.last }} {{ collection.products.first }} {{ collection.products.last }} <!-- 数组索引访问 --> {{ product.images[0] }} {{ product.images[1] }} {{ product.images[-1] }} <!-- 最后一个元素 --> {{ product.images[-2] }} <!-- 倒数第二个元素 -->

字符串对象方法

<!-- 字符串长度 --> {{ product.title.size }} {{ customer.first_name.size }} <!-- 字符串检查 --> {% if product.title.size > 20 %} <h3 title="{{ product.title }}">{{ product.title | truncate: 20 }}</h3> {% else %} <h3>{{ product.title }}</h3> {% endif %}

日期对象方法

<!-- 日期格式化 --> {{ order.created_at | date: '%Y-%m-%d' }} {{ article.published_at | date: '%B %d, %Y' }} <!-- 日期比较 --> {% assign today = 'now' | date: '%Y-%m-%d' %} {% assign order_date = order.created_at | date: '%Y-%m-%d' %} {% if order_date == today %} <span class="today-order">今日订单</span> {% endif %}

对象遍历

遍历数组对象

<!-- 遍历产品图片 --> {% for image in product.images %} <div class="image-item"> <img src="{{ image | img_url: '400x400' }}" alt="{{ image.alt | escape }}" data-index="{{ forloop.index0 }}"> </div> {% endfor %} <!-- 遍历购物车商品 --> {% for item in cart.items %} <div class="cart-item"> <h4>{{ item.title }}</h4> <p>数量: {{ item.quantity }}</p> <p>价格: {{ item.price | money }}</p> <p>小计: {{ item.line_price | money }}</p> </div> {% endfor %} <!-- 遍历客户地址 --> {% for address in customer.addresses %} <div class="address-card"> <h4>{{ address.first_name }} {{ address.last_name }}</h4> <p>{{ address.address1 }}</p> {% if address.address2 != blank %} <p>{{ address.address2 }}</p> {% endif %} <p>{{ address.city }}, {{ address.province }} {{ address.zip }}</p> <p>{{ address.country }}</p> </div> {% endfor %}

有条件的遍历

<!-- 只遍历可用的产品变体 --> {% for variant in product.variants %} {% if variant.available %} <option value="{{ variant.id }}"> {{ variant.title }} - {{ variant.price | money }} </option> {% endif %} {% endfor %} <!-- 遍历特定标签的文章 --> {% for article in blog.articles %} {% if article.tags contains 'featured' %} <article class="featured-article"> <h2>{{ article.title }}</h2> <p>{{ article.excerpt }}</p> </article> {% endif %} {% endfor %}

对象过滤和操作

使用 where 过滤器

<!-- 过滤可用产品 --> {% assign available_products = collection.products | where: 'available', true %} <!-- 过滤特定供应商的产品 --> {% assign apple_products = collection.products | where: 'vendor', 'Apple' %} <!-- 过滤包含特定标签的产品 --> {% assign featured_products = collection.products | where: 'tags', 'featured' %} <!-- 显示过滤结果 --> <div class="filtered-products"> {% for product in featured_products %} {% render 'product-card', product: product %} {% endfor %} </div>

使用 map 提取属性

<!-- 提取所有产品标题 --> {% assign product_titles = collection.products | map: 'title' %} <!-- 提取所有供应商 --> {% assign vendors = collection.products | map: 'vendor' | uniq %} <!-- 提取所有价格 --> {% assign prices = collection.products | map: 'price' %} <!-- 显示提取的信息 --> <div class="vendors-list"> <h3>品牌列表:</h3> {% for vendor in vendors %} <span class="vendor-tag">{{ vendor }}</span> {% endfor %} </div>

对象排序

<!-- 按标题排序 --> {% assign sorted_products = collection.products | sort: 'title' %} <!-- 按价格排序 --> {% assign price_sorted = collection.products | sort: 'price' %} <!-- 按创建时间排序 --> {% assign newest_first = collection.products | sort: 'created_at' | reverse %} <!-- 显示排序结果 --> <div class="sorted-products"> {% for product in price_sorted %} <div class="product-item"> <h4>{{ product.title }}</h4> <p>{{ product.price | money }}</p> </div> {% endfor %} </div>

复杂对象操作

对象聚合统计

<!-- 统计不同类型的产品数量 --> {% assign electronics_count = 0 %} {% assign clothing_count = 0 %} {% assign books_count = 0 %} {% assign other_count = 0 %} {% for product in collection.products %} {% case product.type %} {% when 'Electronics' %} {% assign electronics_count = electronics_count | plus: 1 %} {% when 'Clothing' %} {% assign clothing_count = clothing_count | plus: 1 %} {% when 'Books' %} {% assign books_count = books_count | plus: 1 %} {% else %} {% assign other_count = other_count | plus: 1 %} {% endcase %} {% endfor %} <div class="category-stats"> <h3>产品分类统计</h3> <ul> <li>电子产品: {{ electronics_count }}</li> <li>服装: {{ clothing_count }}</li> <li>图书: {{ books_count }}</li> <li>其他: {{ other_count }}</li> </ul> </div>

对象关系分析

<!-- 分析购物车中的产品关系 --> {% assign cart_vendors = "" %} {% assign cart_types = "" %} {% assign total_value = 0 %} {% for item in cart.items %} <!-- 收集供应商 --> {% unless cart_vendors contains item.vendor %} {% if cart_vendors == "" %} {% assign cart_vendors = item.vendor %} {% else %} {% assign cart_vendors = cart_vendors | append: "," | append: item.vendor %} {% endif %} {% endunless %} <!-- 收集产品类型 --> {% unless cart_types contains item.product.type %} {% if cart_types == "" %} {% assign cart_types = item.product.type %} {% else %} {% assign cart_types = cart_types | append: "," | append: item.product.type %} {% endif %} {% endunless %} <!-- 计算总价值 --> {% assign line_total = item.quantity | times: item.price %} {% assign total_value = total_value | plus: line_total %} {% endfor %} <div class="cart-analysis"> <h3>购物车分析</h3> <p>涉及品牌: {{ cart_vendors | split: "," | size }}</p> <p>产品类型: {{ cart_types | split: "," | size }}</p> <p>总价值: {{ total_value | money }}</p> <p>平均单价: {{ total_value | divided_by: cart.item_count | money }}</p> </div>

对象数据转换

<!-- 将产品数据转换为 JSON --> {% assign product_data = "" %} {% capture product_json %} { "id": {{ product.id }}, "title": "{{ product.title | escape }}", "price": {{ product.price }}, "available": {{ product.available }}, "images": [ {% for image in product.images %} { "src": "{{ image | img_url: '400x400' }}", "alt": "{{ image.alt | escape | default: product.title }}" }{% unless forloop.last %},{% endunless %} {% endfor %} ], "variants": [ {% for variant in product.variants %} { "id": {{ variant.id }}, "title": "{{ variant.title | escape }}", "price": {{ variant.price }}, "available": {{ variant.available }} }{% unless forloop.last %},{% endunless %} {% endfor %} ] } {% endcapture %} <script> window.productData = {{ product_json }}; </script>

对象调试技巧

输出对象结构

<!-- 查看完整对象结构 --> {% if settings.debug_mode %} <div class="debug-panel"> <h4>产品对象调试</h4> <pre>{{ product | json }}</pre> </div> {% endif %} <!-- 查看特定对象的属性 --> {% if settings.debug_mode %} <div class="debug-info"> <h4>客户对象属性</h4> <ul> <li>ID: {{ customer.id }}</li> <li>邮箱: {{ customer.email }}</li> <li>名字: {{ customer.first_name }}</li> <li>姓氏: {{ customer.last_name }}</li> <li>订单数: {{ customer.orders_count }}</li> <li>总消费: {{ customer.total_spent | money }}</li> <li>标签: {{ customer.tags | join: ", " }}</li> </ul> </div> {% endif %}

检查对象类型

<!-- 检查变量类型 --> {% if settings.debug_mode %} <div class="type-info"> <p>product.id 类型: {{ product.id.class }}</p> <p>product.title 类型: {{ product.title.class }}</p> <p>product.price 类型: {{ product.price.class }}</p> <p>product.available 类型: {{ product.available.class }}</p> <p>product.images 类型: {{ product.images.class }}</p> </div> {% endif %}

性能优化技巧

避免重复对象访问

<!-- 不好的做法 --> {% for i in (1..10) %} {{ collection.products.size }} <!-- 每次都访问 --> {% endfor %} <!-- 好的做法 --> {% assign product_count = collection.products.size %} {% for i in (1..10) %} {{ product_count }} <!-- 使用缓存的值 --> {% endfor %}

预处理复杂对象

<!-- 预处理可用产品 --> {% assign available_products = collection.products | where: 'available', true %} <!-- 预计算价格范围 --> {% assign min_price = collection.products | map: 'price' | sort | first %} {% assign max_price = collection.products | map: 'price' | sort | last %} <!-- 使用预处理的数据 --> <div class="collection-info"> <p>可用商品: {{ available_products.size }}</p> <p>价格范围: {{ min_price | money }} - {{ max_price | money }}</p> </div>

最佳实践

1. 安全访问

<!-- 始终检查对象存在性 --> {% if product and product.featured_image %} <img src="{{ product.featured_image | img_url: '400x400' }}" alt="{{ product.featured_image.alt | default: product.title }}"> {% endif %}

2. 使用有意义的变量名

<!-- 好的变量命名 --> {% assign featured_products = collection.products | where: 'featured', true %} {% assign customer_is_vip = customer.tags contains 'vip' %} {% assign product_has_variants = product.variants.size > 1 %}

3. 避免深度嵌套

<!-- 将深度嵌套分解为步骤 --> {% assign selected_variant = product.selected_or_first_available_variant %} {% if selected_variant %} {% assign variant_title = selected_variant.title %} {% assign variant_price = selected_variant.price %} {% endif %}

下一步学习

掌握对象和属性后,建议继续学习:

  1. 运算符和表达式 - 学习对象比较和操作
  2. Shopify 对象参考 - 了解所有可用对象
  3. 高级 Liquid 技巧 - 进阶对象操作
  4. 性能优化 - 对象使用优化

理解对象系统是掌握 Liquid 的关键,它为动态内容提供了强大的数据访问能力!

最后更新时间: