如何简化Shopify Liquid代码片段以遵循DRY原则?
简化Shopify Liquid产品列表代码(遵循DRY原则)
你的核心需求是消除重复代码,实现主图+hover图的逻辑(有第二张图则用第二张,无则复用主图)。下面提供两种优化方案,都严格遵循DRY(Don't Repeat Yourself)原则:
方案1:用Snippet复用图片渲染逻辑(推荐)
把重复的图片标签生成逻辑抽成独立的代码片段,后续维护或修改只需改一处。
步骤1:创建图片渲染Snippet
在Shopify后台的「代码编辑器」中新建snippets/product-image.liquid,写入以下代码:
{% comment %} 参数说明: - image: 图片对象(必填,如product.featured_image) - class: 图片的CSS类名(可选) - alt: 图片的alt文本(可选) {% endcomment %} {% assign image_widths = '300,500,700,900,1000,1445,1680,2048,2200,2890,4096' | split: ',' %} {% capture srcset %} {% for width in image_widths %} {{ image | image_url: width: width }} {{ width }}w{% unless forloop.last %},{% endunless %} {% endfor %} {% endcapture %} <img class="{{ class | default: 'product-image' }}" srcset="{{ srcset | strip_newlines }}" src="{{ image | image_url }}" alt="{{ alt | default: '' }}" width="{{ image.width }}" height="{{ image.height }}" />
步骤2:简化主模板代码
替换原有的产品列表代码为:
<ul class="homepage-products"> {% for product in collections.homepage.products %} {% assign featuredImage = product.featured_image %} {% assign hoverImage = product.images[1] | default: featuredImage %} <li class="homepage-products-li"> <h2 class="homepage-products-title">{{ product.title }}</h2> <a class="homepage-products-a" href="{{ product.url }}"> {% render 'product-image', image: featuredImage, class: 'homepage-products-image', alt: product.title %} {% render 'product-image', image: hoverImage, class: 'homepage-products-hover-image', alt: product.title %} </a> </li> {% endfor %} </ul>
方案2:无需Snippet的轻量化优化
如果不想新增Snippet,可通过条件赋值和循环生成srcset来减少重复:
<ul class="homepage-products"> {% assign image_widths = '300,500,700,900,1000,1445,1680,2048,2200,2890,4096' | split: ',' %} {% for product in collections.homepage.products %} {% assign featuredImage = product.featured_image %} {% assign hoverImage = product.images[1] | default: featuredImage %} {% capture featured_srcset %} {% for width in image_widths %} {{ featuredImage | image_url: width: width }} {{ width }}w{% unless forloop.last %},{% endunless %} {% endfor %} {% endcapture %} {% capture hover_srcset %} {% for width in image_widths %} {{ hoverImage | image_url: width: width }} {{ width }}w{% unless forloop.last %},{% endunless %} {% endfor %} {% endcapture %} <li class="homepage-products-li"> <h2 class="homepage-products-title">{{ product.title }}</h2> <a class="homepage-products-a" href="{{ product.url }}"> <img class="homepage-products-image" srcset="{{ featured_srcset | strip_newlines }}" src="{{ featuredImage | image_url }}" alt="{{ product.title }}" width="{{ featuredImage.width }}" height="{{ featuredImage.height }}" /> <img class="homepage-products-hover-image" srcset="{{ hover_srcset | strip_newlines }}" src="{{ hoverImage | image_url }}" alt="{{ product.title }}" width="{{ hoverImage.width }}" height="{{ hoverImage.height }}" /> </a> </li> {% endfor %} </ul>
关键优化点说明
- 用
default过滤器替代if-else:{% assign hoverImage = product.images[1] | default: featuredImage %}直接实现「有第二张图则用,无则复用主图」的逻辑,无需冗余的分支判断。 - 循环生成srcset:把固定的宽度列表存为数组,通过循环生成srcset内容,避免重复书写11行宽度规则。
- Snippet复用逻辑:方案1将图片渲染逻辑抽离,不仅简化当前代码,还能在店铺其他页面复用,后续修改图片尺寸或格式只需调整Snippet一次。
内容的提问来源于stack exchange,提问作者Marek Szczepański
相关产品推荐
相关产品推荐

