Shopify中构建可复用可自定义DRY Liquid区块的最优方式探讨
嘿,这个问题我太有发言权了——在Shopify Liquid里既要保持代码DRY,又要让商家每次复用区块都能自定义配置,确实得找对平衡点。你提到的两种方法各有短板,那咱们来拆解下最佳实践:
思路很简单:把可复用的核心渲染逻辑抽成Snippet,然后用带Schema配置的Section(或Section Blocks)来传递商家自定义的参数。这样既保证代码只写一次(DRY),又让商家能在主题编辑器里每次复用都设置新选项。
1. 单实例可配置区块:Section传参给Snippet
适合商家需要在页面不同位置添加独立配置的单个区块(比如单个特色产品卡片)。
第一步:写复用的Snippet
创建snippets/product-card.liquid,把核心渲染逻辑放这里,通过render接收外部传参:
<div class="product-card"> <h3>{{ product.title }}</h3> <img src="{{ product.featured_image | img_url: 'medium' }}" alt="{{ product.title }}"> <p class="price">{{ product.price | money }}</p> {% if include.show_button %} <a href="{{ product.url }}" class="btn">{{ include.button_text }}</a> {% endif %} </div>
第二步:写带配置的Section
创建sections/product-feature.liquid,通过Schema定义商家可编辑的选项,然后把配置传给Snippet:
{% assign selected_product = all_products[section.settings.product_handle] %} {% render 'product-card', product: selected_product, show_button: section.settings.show_cta_button, button_text: section.settings.cta_button_text %} {% schema %} { "name": "特色产品卡片", "settings": [ { "type": "text", "id": "product_handle", "label": "产品Handle", "default": "example-product" }, { "type": "checkbox", "id": "show_cta_button", "label": "显示CTA按钮", "default": true }, { "type": "text", "id": "cta_button_text", "label": "按钮文字", "default": "立即购买" } ] } {% endschema %}
现在商家在主题编辑器里可以多次添加这个Section,每次都能选不同产品、开关按钮、修改按钮文字,而核心的卡片逻辑只在Snippet里写了一次。
2. 多实例批量配置:用Section Blocks管理多个区块
如果商家需要在同一个区域添加多个同类型区块(比如一排产品卡片,每个都有独立配置),用Section的blocks功能更高效。
创建sections/multi-product-features.liquid:
<div class="product-grid"> {% for block in section.blocks %} {% assign product = all_products[block.settings.product_handle] %} {% render 'product-card', product: product, show_button: block.settings.show_cta_button, button_text: block.settings.cta_button_text %} {% endfor %} </div> {% schema %} { "name": "多产品展示区", "blocks": [ { "type": "product_card", "name": "产品卡片", "settings": [ { "type": "text", "id": "product_handle", "label": "产品Handle", "default": "example-product" }, { "type": "checkbox", "id": "show_cta_button", "label": "显示CTA按钮", "default": true }, { "type": "text", "id": "cta_button_text", "label": "按钮文字", "default": "立即购买" } ] } ], "presets": [ { "name": "多产品展示区", "blocks": [ { "type": "product_card" } ] } ] } {% endschema %}
商家可以在这个Section里添加N个产品卡片,每个都能独立配置,核心逻辑还是复用同一个Snippet,完全符合DRY原则。
对比你原有方案的优势
- 对比纯Snippet:解决了无法自定义的痛点,商家能在编辑器里可视化修改配置,核心渲染逻辑仍只写一次
- 对比复制Section:不用重复复制Section代码,要么多次添加同一个Section(每个独立配置),要么在一个Section里批量管理多个区块,彻底避免代码冗余
额外场景:模板里直接复用(非编辑器自定义)
如果不需要在主题编辑器里配置,只是在模板(比如product.liquid、collection.liquid)里复用区块,直接调用Snippet并传递参数即可:
{% render 'product-card', product: product, show_button: true, button_text: '查看详情' %}
内容的提问来源于stack exchange,提问作者Jackson Cunningham

