Shopify Liquid脚本无法获取新增同色系关联产品问题
Shopify同色系产品推荐脚本问题排查与修复
问题现象
现有Liquid脚本用于产品页展示同色系关联产品:当产品带有_mor_标签时,遍历all集合中所有带该标签的其他产品。当前旧产品页面仅显示旧的同色系产品,新增的两个带_mor_和crosslinking标签的产品未被纳入推荐;但新品页面能正常显示旧的同色系产品,且已确认新品属于all集合,旧产品页面的调试日志显示脚本未遍历到这两个新品。
相关产品:
- 旧产品:Oddjob iPad/手机支架(深色橡木)
- 新品1:Gislev咖啡滤杯架(多款式深色橡木)
- 新品2:Hvidkilde卫生纸架(深色橡木)
原脚本代码:
{% if product.tags contains 'crosslinking' %} {%- assign tag_alt = "BLANK" -%} {%- for tag in product.tags -%} {%- assign tag_prefix = tag | slice: 0, 5 -%} {%- if tag_prefix == "_lys_" or tag_prefix == "_mor_" -%} {%- assign tag_alt = tag | strip | downcase -%} {%- break -%} {%- endif -%} {%- endfor -%} {%- unless tag_alt == "BLANK" -%} {%- assign all_collection_handle = 'all' -%} {%- if collections[all_collection_handle].products.size > 0 -%} {%- assign alt_products_total = 0 -%} {%- assign alt_products = collections[all_collection_handle].products -%} <!-- Add header before the alt products --> <p class="crosslinking-p"> <span style="font-weight: 600 !important; font-size: .8rem;"> {% if shop.locale == 'da' %}Produkter i samme farve:{% else %}Also available in:{% endif %} </span> </p> {%- assign sorted_alt_products = alt_products | sort: 'price' -%} <!-- Sort products by price --> {%- for alt_product in sorted_alt_products -%} {%- if alt_product.id != product.id -%} <!-- Exclude current product --> {% capture debug_msg %}Product ID: {{ alt_product.id }}, Title: {{ alt_product.title }}{% endcapture %} <script>console.debug("Checking alternative product - {{ debug_msg }}");</script> {%- assign matched = false -%} {%- for tag in alt_product.tags -%} {%- assign normalized_tag = tag | strip | downcase -%} {% if normalized_tag == tag_alt %} <script>console.debug(" - Tag check: Tag {{ normalized_tag }} matches tag_alt {{ tag_alt }}");</script> {%- assign matched = true -%} {%- assign alt_products_total = alt_products_total | plus: 1 -%} <a href="{{ alt_product.url }}" title="{{ alt_product.title }}"> <img src="{{ alt_product.featured_image | img_url: '50x50', crop: 'center', format: 'pjpg' }}" alt="{{ alt_product.title }}"> </a> <script>console.info(" -> Product matched: {{ alt_product.title }}");</script> {%- break -%} {% else %} <script>console.debug(" - Tag check: Tag {{ normalized_tag }} does not match tag_alt {{ tag_alt }}");</script> {% endif %} {%- endfor -%} {%- unless matched -%} <script>console.warn(" -> Product not matched: {{ alt_product.title }}");</script> {%- endunless -%} {%- endif -%} {%- endfor -%} {%- if alt_products_total == 0 -%} <p>No matching products found in the collection</p> <script>console.info("No matching products found in the collection");</script> {%- endif -%} {%- else -%} <p>No products in 'all' collection</p> <script>console.error("No products available in the 'all' collection");</script> {%- endif -%} {%- else -%} <p>No matching tag found</p> <script>console.error("No matching tag found in product tags");</script> {%- endunless -%} {% endif %}
问题原因
Shopify的collections.all.products默认仅返回前50个产品(受分页限制)。旧产品页面加载时,新品在按价格排序后超出了前50的范围,因此脚本无法遍历到;而新品页面加载时,旧产品可能处于排序后的前50中,所以能正常显示。
修复方案
方案1:改用标签直接查询(推荐,更高效)
直接通过标签筛选目标产品,无需遍历全集合,且能获取所有匹配产品:
{% if product.tags contains 'crosslinking' %} {%- assign tag_alt = "BLANK" -%} {%- for tag in product.tags -%} {%- assign tag_prefix = tag | slice: 0, 5 -%} {%- if tag_prefix == "_lys_" or tag_prefix == "_mor_" -%} {%- assign tag_alt = tag | strip | downcase -%} {%- break -%} {%- endif -%} {%- endfor -%} {%- unless tag_alt == "BLANK" -%} {%- assign matching_products = all_products | where: 'tags', tag_alt -%} {%- assign matching_products = matching_products | reject: 'id', product.id -%} {%- assign sorted_matching_products = matching_products | sort: 'price' -%} <!-- Add header before the alt products --> <p class="crosslinking-p"> <span style="font-weight: 600 !important; font-size: .8rem;"> {% if shop.locale == 'da' %}Produkter i samme farve:{% else %}Also available in:{% endif %} </span> </p> {%- if sorted_matching_products.size > 0 -%} {%- for alt_product in sorted_matching_products -%} <a href="{{ alt_product.url }}" title="{{ alt_product.title }}"> <img src="{{ alt_product.featured_image | img_url: '50x50', crop: 'center', format: 'pjpg' }}" alt="{{ alt_product.title }}"> </a> {%- endfor -%} {%- else -%} <p>{% if shop.locale == 'da' %}Ingen tilsvarende produkter fundet{% else %}No matching products found{% endif %}</p> {%- endif -%} {%- else -%} <p>{% if shop.locale == 'da' %}Ingen matchende tag fundet{% else %}No matching tag found{% endif %}</p> {%- endunless -%} {% endif %}
方案2:遍历全集合所有分页
如果需要保留原集合遍历逻辑,需处理分页获取所有产品:
{% if product.tags contains 'crosslinking' %} {%- assign tag_alt = "BLANK" -%} {%- for tag in product.tags -%} {%- assign tag_prefix = tag | slice: 0, 5 -%} {%- if tag_prefix == "_lys_" or tag_prefix == "_mor_" -%} {%- assign tag_alt = tag | strip | downcase -%} {%- break -%} {%- endif -%} {%- endfor -%} {%- unless tag_alt == "BLANK" -%} {%- assign all_collection = collections.all -%} {%- assign all_products = all_collection.products -%} <!-- 获取所有分页的产品 --> {%- for page in (2..all_collection.pages) -%} {%- assign all_products = all_products | concat: all_collection.products_page[page] -%} {%- endfor -%} {%- assign sorted_alt_products = all_products | sort: 'price' -%} {%- assign alt_products_total = 0 -%} <!-- Add header before the alt products --> <p class="crosslinking-p"> <span style="font-weight: 600 !important; font-size: .8rem;"> {% if shop.locale == 'da' %}Produkter i samme farve:{% else %}Also available in:{% endif %} </span> </p> {%- for alt_product in sorted_alt_products -%} {%- if alt_product.id != product.id -%} {%- assign matched = false -%} {%- for tag in alt_product.tags -%} {%- assign normalized_tag = tag | strip | downcase -%} {% if normalized_tag == tag_alt %} {%- assign matched = true -%} {%- assign alt_products_total = alt_products_total | plus: 1 -%} <a href="{{ alt_product.url }}" title="{{ alt_product.title }}"> <img src="{{ alt_product.featured_image | img_url: '50x50', crop: 'center', format: 'pjpg' }}" alt="{{ alt_product.title }}"> </a> {%- break -%} {% endif %} {%- endfor -%} {%- endif -%} {%- endfor -%} {%- if alt_products_total == 0 -%} <p>{% if shop.locale == 'da' %}Ingen tilsvarende produkter fundet{% else %}No matching products found{% endif %}</p> {%- endif -%} {%- else -%} <p>{% if shop.locale == 'da' %}Ingen matchende tag fundet{% else %}No matching tag found{% endif %}</p> {%- endunless -%} {% endif %}
说明
- 方案1使用
all_products | where直接筛选标签,性能更优,且不受分页限制,是优先推荐的修复方式。 - 方案2通过遍历所有分页获取全量产品,适合需要保留原集合遍历逻辑的场景,但注意Shopify对Liquid循环次数有上限(最多1000次),如果产品数量过多可能触发限制。
内容的提问来源于stack exchange,提问作者Kenneth Bon Nielsen
相关产品推荐
相关产品推荐

