Shopify Dawn主题Liquid中如何排序集合将售罄商品置于底部并适配分页
Shopify Dawn主题集合页售罄商品全局下沉实现方案
需求背景
自定义Shopify Dawn主题时,需要将集合内所有售罄商品统一排序到列表最底部,避免用户翻页时提前看到大量售罄商品。
原有实现的问题
此前通过两次循环分别渲染当前页的在售、售罄商品,仅能实现单页内的售罄商品下沉。由于Shopify原生分页逻辑是基于原始集合的商品顺序拆分单页内容,因此售罄商品会散落在各个分页,无法实现全集合范围排序后再分页。
实现方案
方案1:后台自定义排序(最优,无需改代码)
该方案完全适配Shopify原生分页逻辑,无需修改前端代码,适配任意商品量级的集合:
- 为所有售罄商品统一打上
sold_out标签,可通过后台批量操作或自动化规则实现(库存为0时自动打标,库存恢复时自动移除标签) - 进入对应集合的后台设置页,排序规则选择「按标签排序」,设置优先级为无
sold_out标签的商品排在最前,有sold_out标签的商品排在最后 - 保存设置后即可生效,全集合的售罄商品会自动集中在最后几页
方案2:Liquid预筛选排序(前端代码实现,适合商品量≤200的集合)
如果无法通过后台配置实现,可通过Liquid预构建有序商品数组后再分页,完整实现代码如下:
<div id="CollectionProductGrid"> {% comment %} 第一步:拆分全集合商品为在售、售罄两个数组 {% endcomment %} {% assign in_stock_products = '' | split: '' %} {% assign sold_out_products = '' | split: '' %} {% for product in collection.products limit: 200 %} {% if product.available %} {% assign in_stock_products = in_stock_products | push: product %} {% else %} {% assign sold_out_products = sold_out_products | push: product %} {% endif %} {% endfor %} {% comment %} 拼接得到全局有序的商品数组 {% endcomment %} {% assign sorted_products = in_stock_products | concat: sold_out_products %} {% assign products_per_page = section.settings.products_per_page %} {%- paginate sorted_products by products_per_page -%} {%- if sorted_products.size == 0 -%} <div class="collection collection--empty page-width" id="main-collection-product-grid" data-id="{{ section.id }}"> <div class="loading-overlay gradient"></div> <p class="collection-product-count light" role="status"> {%- if collection.products_count == collection.all_products_count -%} {{ 'sections.collection_template.product_count_simple' | t: count: collection.products_count }} {%- else -%} {{ 'sections.collection_template.product_count' | t: product_count: collection.products_count, count: collection.all_products_count }} {%- endif -%} </p> <div class="title-wrapper center"> <h2 class="title title--primary"> {{ 'sections.collection_template.empty' | t }}<br> {{ 'sections.collection_template.use_fewer_filters_html' | t: link: collection.url, class: "underlined-link link" }} </h2> </div> </div> {%- else -%} <div class="collection page-width"> <div class="loading-overlay gradient"></div> <ul id="main-collection-product-grid" data-id="{{ section.id }}" class=" grid grid--1-col negative-margin product-grid {% if collection.products_count < 4 %} grid--{{ collection.products_count }}-col-tablet{% else %} {% if collection.products_count == 4 %} grid--4-col-desktop{% else %} grid--3-col-tablet grid--one-third-max grid--4-col-desktop grid--quarter-max{% endif %} {% endif %}"> {% comment %} 遍历排序后的当前分页商品 {% endcomment %} {%- for product in paginate.collection -%} <li class="grid__item"> {% render 'product-card', product_card_product: product, media_size: section.settings.image_ratio, show_secondary_image: section.settings.show_secondary_image, add_image_padding: section.settings.add_image_padding, show_vendor: section.settings.show_vendor, show_image_outline: section.settings.show_image_outline, show_rating: section.settings.show_rating, show_atc: section.settings.show_atc %} </li> {%- endfor -%} </ul> {%- if paginate.pages > 1 -%} {% render 'pagination', paginate: paginate, anchor: '' %} {%- endif -%} </div> {%- endif -%} {%- endpaginate -%} </div>
关键逻辑说明
- 先遍历全集合商品拆分出在售、售罄两个独立数组,再拼接得到「在售在前、售罄在后」的全局有序数组
- 分页逻辑直接作用于排序后的新数组,确保分页拆分是基于全局排序后的结果,售罄商品全部集中在最后几页
- 代码兼容原有主题的配置项、分页组件和产品卡片渲染逻辑,无需额外修改其他模板文件
注意:Shopify Liquid遍历集合商品默认最多返回200个,若集合商品量超过200,建议使用方案1的后台自定义排序实现
内容的提问来源于stack exchange,提问作者Preben F
相关产品推荐
相关产品推荐

