Skip to content

Instantly share code, notes, and snippets.

@TeamDijon
Last active February 25, 2025 14:04
Show Gist options
  • Save TeamDijon/62d6a439ef9d8f149d0932026f79d3c7 to your computer and use it in GitHub Desktop.
Save TeamDijon/62d6a439ef9d8f149d0932026f79d3c7 to your computer and use it in GitHub Desktop.
Snippet showing a DRY paginated product grid using both collection and product_list source
{% liquid
# Using the collections object is necessary as we can't paginate collection settings, only collectionDrop objects
assign featured_collection = collections[section.settings.featured_collection]
assign product_list = section.settings.product_list
if featured_collection == null and product_list == blank
# Default behavior handling can go there
endif
assign pagination_size = section.settings.pagination_size
# We reference the paginate object inside the associated paginate tag to use later, in a DRY manner
assign paginate_object = null
if product_list and product_list.count > 0
assign source = null | default: products: product_list
paginate product_list by pagination_size
assign paginate_object = paginate
endpaginate
else
assign source = featured_collection
paginate featured_collection.products by pagination_size
assign paginate_object = paginate
endpaginate
endif
assign pagination_markup = paginate | default_pagination
%}
<div class="product-list-container">
<ul class="product-list">
{% for paginated_product in source.products
limit: paginate_object.page_size
offset: paginate_object.current_offset
%}
<li class="product-container">
{% render 'product-card', product: paginated_product
</li>
{% endfor %}
</ul>
{{ pagination_markup }}
</div>
{% schema %}
{
"name": "Product grid",
"class": "shopify-section--product-grid",
"blocks": [],
"settings": [
{
"type": "header",
"content": "Product source"
},
{
"type": "collection",
"id": "collection",
"label": "Collection"
},
{
"type": "product_list",
"id": "product_list",
"label": "Product list",
"info": "Takes priority over collection"
},
{
"type": "header",
"content": "Pagination settings"
},
{
"type": "range",
"id": "pagination_size",
"label": "Pagination size",
"min": 4,
"max": 60,
"step": 1,
"default": 20
}
],
"presets": [
{
"name": "Product grid",
"blocks": [],
"settings": {}
}
]
}
{% endschema %}
{% liquid
# Using the collections object is necessary as we can't paginate collection settings, only collectionDrop objects
assign featured_collection = collections[section.settings.featured_collection]
assign product_list = section.settings.product_list
if featured_collection == null and product_list == blank
# Default behavior handling can go there
endif
assign pagination_size = section.settings.pagination_size
assing source = featured_collection
if product_list and product_list.count > 0
# We create a Liquid object with a "products" property containing the product_list data
assign source = null | default: products: product_list
endif
%}
<div class="product-list-container">
{% # Weirdly, this line is necessary or the trick won't work, investigation needed %}
{% paginate collections.all.products %}{% endpaginate %}
{% paginate source.products by pagination_size %}
{% liquid
assign pagination_markup = paginate | default_pagination
%}
<ul class="product-list">
{% for paginated_product in source.products %}
<li class="product-container">
{% render 'product-card', product: paginated_product
</li>
{% endfor %}
</ul>
{{ pagination_markup }}
{% endpaginate %}
</div>
{% comment %}
In the past, my code looked like this : (same code inside both paginate tags, not DRY)
{% liquid
assign product_source = 'collection'
if product_list and product_list.count > 0
assign product_source = 'product_list'
endif
%}
{% if product_source == 'collection' %}
{% paginate featured_collection.products by pagination_size %}
...
{% endpaginate %}
{% else %}
{% paginate product_list by pagination_size %}
...
{% endpaginate %}
{% endif %}
{% endcomment %}
{% schema %}
{
"name": "Product grid",
"class": "shopify-section--product-grid",
"blocks": [],
"settings": [
{
"type": "header",
"content": "Product source"
},
{
"type": "collection",
"id": "collection",
"label": "Collection"
},
{
"type": "product_list",
"id": "product_list",
"label": "Product list",
"info": "Takes priority over collection"
},
{
"type": "header",
"content": "Pagination settings"
},
{
"type": "range",
"id": "pagination_size",
"label": "Pagination size",
"min": 4,
"max": 60,
"step": 1,
"default": 20
}
],
"presets": [
{
"name": "Product grid",
"blocks": [],
"settings": {}
}
]
}
{% endschema %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment