Last active
February 25, 2025 14:04
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% 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 %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% 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