Shopify 对象参考
Shopify 为 Liquid 模板提供了丰富的对象,这些对象包含了商店、产品、客户等各种数据。深入了解这些对象是构建动态主题的基础。
全局对象
shop 对象
包含商店的基本信息和设置。
<!-- 基本店铺信息 -->
<h1>{{ shop.name }}</h1>
<p>{{ shop.description }}</p>
<!-- 店铺联系信息 -->
<address>
{{ shop.address.address1 }}<br>
{% if shop.address.address2 %}{{ shop.address.address2 }}<br>{% endif %}
{{ shop.address.city }}, {{ shop.address.province }} {{ shop.address.zip }}<br>
{{ shop.address.country }}
</address>
<!-- 店铺设置 -->
<p>货币: {{ shop.currency }}</p>
<p>域名: {{ shop.domain }}</p>
<p>安全域名: {{ shop.secure_url }}</p>
<p>客服邮箱: {{ shop.customer_email }}</p>
<p>客服电话: {{ shop.phone }}</p>
<!-- 店铺策略页面 -->
{% if shop.privacy_policy %}
<a href="{{ shop.privacy_policy.url }}">隐私政策</a>
{% endif %}
{% if shop.refund_policy %}
<a href="{{ shop.refund_policy.url }}">退款政策</a>
{% endif %}
{% if shop.terms_of_service %}
<a href="{{ shop.terms_of_service.url }}">服务条款</a>
{% endif %}
cart 对象
表示当前购物车的状态和内容。
<!-- 购物车基本信息 -->
<div class="cart-summary">
<p>商品数量: {{ cart.item_count }}</p>
<p>总重量: {{ cart.total_weight }}g</p>
<p>小计: {{ cart.total_price | money }}</p>
{% if cart.total_discount > 0 %}
<p>折扣: -{{ cart.total_discount | money }}</p>
{% endif %}
{% if cart.taxes_included %}
<p>含税价格</p>
{% else %}
<p>不含税价格</p>
{% endif %}
</div>
<!-- 购物车商品 -->
{% for item in cart.items %}
<div class="cart-item">
<img src="{{ item.image | img_url: '100x100' }}" alt="{{ item.title }}">
<div class="item-details">
<h4>{{ item.product.title }}</h4>
{% if item.variant.title != 'Default Title' %}
<p>规格: {{ item.variant.title }}</p>
{% endif %}
<p>单价: {{ item.price | money }}</p>
<p>数量: {{ item.quantity }}</p>
<p>小计: {{ item.line_price | money }}</p>
<!-- 商品属性 -->
{% for property in item.properties %}
{% unless property.last == blank %}
<p>{{ property.first }}: {{ property.last }}</p>
{% endunless %}
{% endfor %}
<!-- 折扣信息 -->
{% for discount in item.line_level_discount_allocations %}
<p class="discount">折扣: {{ discount.discount_application.title }} (-{{ discount.amount | money }})</p>
{% endfor %}
</div>
</div>
{% endfor %}
<!-- 购物车为空时 -->
{% if cart.item_count == 0 %}
<div class="empty-cart">
<p>购物车是空的</p>
<a href="/collections" class="continue-shopping">继续购物</a>
</div>
{% endif %}
customer 对象
表示当前登录的客户信息。
{% if customer %}
<div class="customer-info">
<h2>欢迎回来,{{ customer.first_name }}!</h2>
<!-- 基本信息 -->
<div class="customer-details">
<p>姓名: {{ customer.first_name }} {{ customer.last_name }}</p>
<p>邮箱: {{ customer.email }}</p>
<p>注册时间: {{ customer.created_at | date: '%Y年%m月%d日' }}</p>
<p>订单数量: {{ customer.orders_count }}</p>
<p>总消费: {{ customer.total_spent | money }}</p>
<!-- 客户标签 -->
{% if customer.tags.size > 0 %}
<div class="customer-tags">
<strong>标签:</strong>
{% for tag in customer.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
<!-- 默认地址 -->
{% if customer.default_address %}
<div class="default-address">
<h3>默认地址</h3>
<address>
{{ customer.default_address.first_name }} {{ customer.default_address.last_name }}<br>
{{ customer.default_address.address1 }}<br>
{% if customer.default_address.address2 %}{{ customer.default_address.address2 }}<br>{% endif %}
{{ customer.default_address.city }}, {{ customer.default_address.province }} {{ customer.default_address.zip }}<br>
{{ customer.default_address.country }}
</address>
</div>
{% endif %}
<!-- 最近订单 -->
{% if customer.orders.size > 0 %}
<div class="recent-orders">
<h3>最近订单</h3>
{% for order in customer.orders limit: 3 %}
<div class="order-summary">
<p>订单号: {{ order.name }}</p>
<p>日期: {{ order.created_at | date: '%Y年%m月%d日' }}</p>
<p>金额: {{ order.total_price | money }}</p>
<p>状态: {{ order.financial_status }}</p>
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% else %}
<div class="guest-info">
<p>您尚未登录</p>
<a href="/account/login">登录</a> 或 <a href="/account/register">注册</a>
</div>
{% endif %}
request 对象
包含当前HTTP请求的信息。
<!-- 页面信息 -->
<div class="page-info">
<p>当前页面: {{ request.page_type }}</p>
<p>完整URL: {{ request.origin }}{{ request.path }}</p>
<!-- URL 参数 -->
{% if request.params.size > 0 %}
<div class="url-params">
<h4>URL参数:</h4>
{% for param in request.params %}
<p>{{ param.first }}: {{ param.last }}</p>
{% endfor %}
</div>
{% endif %}
<!-- 设备信息 -->
<p>用户代理: {{ request.user_agent }}</p>
<!-- 地理位置 (如果可用) -->
{% if request.locale %}
<p>语言环境: {{ request.locale.iso_code }}</p>
{% endif %}
</div>
<!-- 根据设备类型调整显示 -->
{% if request.user_agent contains 'Mobile' %}
<div class="mobile-content">
<!-- 移动端特定内容 -->
</div>
{% else %}
<div class="desktop-content">
<!-- 桌面端特定内容 -->
</div>
{% endif %}
页面特定对象
product 对象
表示单个产品的详细信息。
<div class="product-details">
<!-- 基本信息 -->
<h1>{{ product.title }}</h1>
<p class="vendor">品牌: {{ product.vendor }}</p>
<p class="type">类型: {{ product.type }}</p>
<!-- 价格信息 -->
<div class="pricing">
{% if product.compare_at_price > product.price %}
<span class="compare-price">{{ product.compare_at_price | money }}</span>
<span class="price on-sale">{{ product.price | money }}</span>
{% assign savings = product.compare_at_price | minus: product.price %}
<span class="savings">节省 {{ savings | money }}</span>
{% else %}
<span class="price">{{ product.price | money }}</span>
{% endif %}
</div>
<!-- 描述 -->
{% if product.description %}
<div class="description">
{{ product.description }}
</div>
{% endif %}
<!-- 产品标签 -->
{% if product.tags.size > 0 %}
<div class="product-tags">
{% for tag in product.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
<!-- 产品图片 -->
{% if product.images.size > 0 %}
<div class="product-gallery">
<!-- 主图 -->
<div class="main-image">
<img src="{{ product.featured_image | img_url: '600x600' }}"
alt="{{ product.featured_image.alt | default: product.title }}">
</div>
<!-- 缩略图 -->
{% if product.images.size > 1 %}
<div class="thumbnail-images">
{% for image in product.images %}
<img src="{{ image | img_url: '100x100' }}"
alt="{{ image.alt | default: product.title }}"
data-main="{{ image | img_url: '600x600' }}">
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
<!-- 产品变体 -->
{% if product.variants.size > 1 %}
<div class="product-variants">
<select name="id">
{% for variant in product.variants %}
<option value="{{ variant.id }}"
{% unless variant.available %}disabled{% endunless %}>
{{ variant.title }}
{% unless variant.available %} - 缺货{% endunless %}
</option>
{% endfor %}
</select>
</div>
{% endif %}
<!-- 库存状态 -->
<div class="availability">
{% if product.available %}
<span class="in-stock">有库存</span>
{% else %}
<span class="out-of-stock">缺货</span>
{% endif %}
</div>
<!-- SEO信息 -->
<div class="seo-info" style="display: none;">
<p>SEO标题: {{ product.seo.title | default: product.title }}</p>
<p>SEO描述: {{ product.seo.description | default: product.description | strip_html | truncate: 160 }}</p>
</div>
</div>
collection 对象
表示产品集合信息。
<div class="collection-header">
<h1>{{ collection.title }}</h1>
{% if collection.description %}
<div class="collection-description">
{{ collection.description }}
</div>
{% endif %}
{% if collection.image %}
<div class="collection-image">
<img src="{{ collection.image | img_url: '1200x400' }}"
alt="{{ collection.image.alt | default: collection.title }}">
</div>
{% endif %}
</div>
<div class="collection-info">
<p>产品数量: {{ collection.products_count }}</p>
<p>集合ID: {{ collection.id }}</p>
<p>句柄: {{ collection.handle }}</p>
</div>
<!-- 产品列表 -->
<div class="products-grid">
{% for product in collection.products %}
<div class="product-card">
<a href="{{ product.url }}">
{% if product.featured_image %}
<img src="{{ product.featured_image | img_url: '300x300' }}"
alt="{{ product.title }}">
{% endif %}
<h3>{{ product.title }}</h3>
<p class="price">{{ product.price | money }}</p>
</a>
</div>
{% endfor %}
</div>
<!-- 如果集合为空 -->
{% if collection.products.size == 0 %}
<div class="empty-collection">
<p>此集合中暂无产品</p>
</div>
{% endif %}
blog 和 article 对象
表示博客和文章信息。
<!-- 博客页面 -->
<div class="blog-header">
<h1>{{ blog.title }}</h1>
{% if blog.summary %}
<p class="blog-summary">{{ blog.summary }}</p>
{% endif %}
</div>
<!-- 文章列表 -->
<div class="articles-list">
{% for article in blog.articles %}
<article class="article-summary">
<h2><a href="{{ article.url }}">{{ article.title }}</a></h2>
<div class="article-meta">
<time datetime="{{ article.published_at | date: '%Y-%m-%d' }}">
{{ article.published_at | date: '%Y年%m月%d日' }}
</time>
<span class="author">作者: {{ article.author }}</span>
{% if article.tags.size > 0 %}
<div class="article-tags">
{% for tag in article.tags %}
<span class="tag">{{ tag }}</span>
{% endfor %}
</div>
{% endif %}
</div>
{% if article.excerpt %}
<div class="article-excerpt">
{{ article.excerpt }}
</div>
{% else %}
<div class="article-excerpt">
{{ article.content | strip_html | truncate: 200 }}
</div>
{% endif %}
<div class="article-footer">
<a href="{{ article.url }}" class="read-more">阅读全文</a>
<span class="comment-count">{{ article.comments_count }} 条评论</span>
</div>
</article>
{% endfor %}
</div>
<!-- 文章详情页 -->
{% if template contains 'article' %}
<article class="article-content">
<header class="article-header">
<h1>{{ article.title }}</h1>
<div class="article-meta">
<time datetime="{{ article.published_at | date: '%Y-%m-%d' }}">
{{ article.published_at | date: '%Y年%m月%d日' }}
</time>
<span class="author">{{ article.author }}</span>
{% if article.tags.size > 0 %}
<div class="article-tags">
{% for tag in article.tags %}
<a href="{{ blog.url }}/tagged/{{ tag | handle }}" class="tag">{{ tag }}</a>
{% endfor %}
</div>
{% endif %}
</div>
</header>
{% if article.image %}
<div class="article-image">
<img src="{{ article.image | img_url: '800x400' }}"
alt="{{ article.image.alt | default: article.title }}">
</div>
{% endif %}
<div class="article-body">
{{ article.content }}
</div>
<!-- 文章摘要 -->
{% if article.excerpt %}
<div class="article-summary">
<h3>摘要</h3>
{{ article.excerpt }}
</div>
{% endif %}
</article>
{% endif %}
模板和布局对象
template 对象
表示当前模板信息。
<!-- 根据模板类型显示不同内容 -->
{% case template %}
{% when 'index' %}
<div class="homepage-content">
<!-- 首页特定内容 -->
</div>
{% when 'product' %}
<div class="product-page">
<!-- 产品页特定内容 -->
</div>
{% when 'collection' %}
<div class="collection-page">
<!-- 集合页特定内容 -->
</div>
{% when 'cart' %}
<div class="cart-page">
<!-- 购物车页特定内容 -->
</div>
{% when 'blog' %}
<div class="blog-page">
<!-- 博客页特定内容 -->
</div>
{% when 'article' %}
<div class="article-page">
<!-- 文章页特定内容 -->
</div>
{% when 'page' %}
<div class="static-page">
<!-- 静态页面特定内容 -->
</div>
{% when 'search' %}
<div class="search-results">
<!-- 搜索结果页特定内容 -->
</div>
{% when '404' %}
<div class="not-found">
<!-- 404页面特定内容 -->
</div>
{% else %}
<div class="default-content">
<!-- 默认内容 -->
</div>
{% endcase %}
<!-- 模板调试信息 -->
{% if settings.debug_mode %}
<div class="template-debug">
<p>当前模板: {{ template }}</p>
<p>模板后缀: {{ template.suffix }}</p>
<p>模板目录: {{ template.directory }}</p>
<p>模板名称: {{ template.name }}</p>
</div>
{% endif %}
page 对象
表示静态页面信息。
<div class="page-content">
<header class="page-header">
<h1>{{ page.title }}</h1>
{% if page.author %}
<p class="page-author">作者: {{ page.author }}</p>
{% endif %}
<time datetime="{{ page.published_at | date: '%Y-%m-%d' }}">
发布于: {{ page.published_at | date: '%Y年%m月%d日' }}
</time>
</header>
<div class="page-body">
{{ page.content }}
</div>
<footer class="page-footer">
<p>页面ID: {{ page.id }}</p>
<p>句柄: {{ page.handle }}</p>
{% if page.updated_at %}
<p>最后更新: {{ page.updated_at | date: '%Y年%m月%d日' }}</p>
{% endif %}
</footer>
</div>
分页对象
paginate 对象
用于分页显示大量内容。
{% paginate collection.products by 12 %}
<!-- 产品网格 -->
<div class="products-grid">
{% for product in collection.products %}
<div class="product-card">
<!-- 产品卡片内容 -->
</div>
{% endfor %}
</div>
<!-- 分页导航 -->
{% if paginate.pages > 1 %}
<nav class="pagination" aria-label="分页导航">
<!-- 上一页 -->
{% if paginate.previous %}
<a href="{{ paginate.previous.url }}" class="pagination-link prev" rel="prev">
← 上一页
</a>
{% endif %}
<!-- 页码 -->
{% for part in paginate.parts %}
{% if part.is_link %}
<a href="{{ part.url }}" class="pagination-link">
{{ part.title }}
</a>
{% else %}
{% if part.title == '…' %}
<span class="pagination-ellipsis">…</span>
{% else %}
<span class="pagination-link current" aria-current="page">
{{ part.title }}
</span>
{% endif %}
{% endif %}
{% endfor %}
<!-- 下一页 -->
{% if paginate.next %}
<a href="{{ paginate.next.url }}" class="pagination-link next" rel="next">
下一页 →
</a>
{% endif %}
</nav>
<!-- 分页信息 -->
<div class="pagination-info">
<p>
显示第 {{ paginate.current_offset | plus: 1 }} -
{{ paginate.current_offset | plus: paginate.current_size }} 项,
共 {{ paginate.items }} 项
</p>
<p>第 {{ paginate.current_page }} 页,共 {{ paginate.pages }} 页</p>
</div>
{% endif %}
{% endpaginate %}
搜索对象
search 对象
表示搜索结果和相关信息。
{% if search.performed %}
<div class="search-results">
<h1>搜索结果</h1>
<p>搜索词: "{{ search.terms }}"</p>
<p>找到 {{ search.results_count }} 个结果</p>
{% if search.results.size > 0 %}
<div class="search-results-list">
{% for item in search.results %}
<div class="search-result-item">
{% case item.object_type %}
{% when 'product' %}
<div class="product-result">
<a href="{{ item.url }}">
{% if item.featured_image %}
<img src="{{ item.featured_image | img_url: '100x100' }}"
alt="{{ item.title }}">
{% endif %}
<h3>{{ item.title }}</h3>
<p class="price">{{ item.price | money }}</p>
</a>
</div>
{% when 'article' %}
<div class="article-result">
<h3><a href="{{ item.url }}">{{ item.title }}</a></h3>
<p class="excerpt">{{ item.content | strip_html | truncate: 150 }}</p>
<time>{{ item.published_at | date: '%Y年%m月%d日' }}</time>
</div>
{% when 'page' %}
<div class="page-result">
<h3><a href="{{ item.url }}">{{ item.title }}</a></h3>
<p class="excerpt">{{ item.content | strip_html | truncate: 150 }}</p>
</div>
{% endcase %}
</div>
{% endfor %}
</div>
{% else %}
<div class="no-results">
<p>未找到与 "{{ search.terms }}" 相关的结果</p>
<p>建议:</p>
<ul>
<li>检查拼写是否正确</li>
<li>尝试使用不同的关键词</li>
<li>使用更通用的搜索词</li>
</ul>
</div>
{% endif %}
</div>
{% else %}
<div class="search-form">
<form action="/search" method="get">
<input type="search" name="q" placeholder="搜索产品、文章..." value="{{ search.terms }}">
<button type="submit">搜索</button>
</form>
</div>
{% endif %}
对象使用最佳实践
1. 安全访问
<!-- 始终检查对象存在性 -->
{% if product and product.featured_image %}
<img src="{{ product.featured_image | img_url: '400x400' }}"
alt="{{ product.featured_image.alt | default: product.title }}">
{% endif %}
<!-- 使用 default 过滤器提供后备值 -->
{{ product.description | default: "暂无描述" }}
{{ customer.first_name | default: "客人" }}
2. 性能优化
<!-- 缓存复杂计算 -->
{% assign product_count = collection.products.size %}
{% assign has_sale_items = collection.products | where: 'compare_at_price_max', '>', 0 %}
<!-- 避免重复访问 -->
{% assign featured_image = product.featured_image %}
{% if featured_image %}
<img src="{{ featured_image | img_url: '400x400' }}"
alt="{{ featured_image.alt | default: product.title }}">
{% endif %}
3. SEO优化
<!-- 结构化数据 -->
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "{{ product.title | escape }}",
"description": "{{ product.description | strip_html | escape }}",
"brand": {
"@type": "Brand",
"name": "{{ product.vendor | escape }}"
},
"offers": {
"@type": "Offer",
"price": "{{ product.price | money_without_currency }}",
"priceCurrency": "{{ shop.currency }}",
"availability": "{% if product.available %}InStock{% else %}OutOfStock{% endif %}"
}
}
</script>
下一步学习
掌握Shopify对象后,建议继续学习:
- 全局对象详解 - 深入了解全局对象
- 产品对象详解 - 产品相关对象
- 客户对象详解 - 客户相关对象
- 高级 Liquid 技巧 - 对象的高级用法
理解Shopify对象是创建动态、数据驱动主题的关键基础!
最后更新时间: