skip to Main Content

In my collection template I’m showing product variants if applicable and products if not. This works very well, safe for the fact that it seems impossible to paginate. I’ve tried creating a custom array of variants/products, but paginate wants nothing to do with it.

Here’s the code I’m currently using which works for outputting variants/products in a grid:

{% for product in collection.products %}
  {% if product.variants.size == 0 %} 
    {% include 'product-card-grid2', max_height: max_height %}
  {% else %}
    {% for variant in product.variants %}
      {% include 'product-card-grid2', max_height: max_height %}
    {% endfor %}
  {% endif %}
{% endfor %}

How do you paginate something like this? Essentially I’d like something like the excellent pimoroni.com.

Liquid seems exceptionally rigid in terms of array construction/manipulation.

I guess the alternative would be to output the list as json and then manually handling it in JS, but it would be nice if that’s avoidable.

One page may show 200 and another may show 50. I’d like to normalize that to 20 per page – also to avoid hitting shopify’s hard cap on collections.

2

Answers


  1. Chosen as BEST ANSWER

    Concat only works on arrays. Luckily there are ways to handle that. Array doesn't have the slice method (only strings) so we need to construct that too. Modulo takes care of under/overflow.

    At last, success:

    {% comment %}
        ------------------------------------------------------------------------------
        Consolidating the product list for later use.
        NOTE: It will probably cap over 50 products!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Needs to be rewritten at some point to use page number to load only the needed
        products.
    {% endcomment %}
    
    {% assign productList = "" | split: "" %}
    {% assign counter = 0 %}
    {% assign variantLimit = 30 %}
    
    {% for product in collection.products %}
      {% assign productList = productList | concat: product.variants %}
      {% assign counter = counter | plus: product.variants.size %}
    {% endfor %}
    
    {% assign maxSize = productList.size %}
    
    
    {% assign start = current_page | minus: 1 | times: variantLimit %}
    {% assign end = current_page | times: variantLimit | minus: 1 %}
    
    {% if end > maxSize %}
      {% assign end = productList.size | modulo: variantLimit %}
    {% endif %}
    
    {% assign slice = "" | split: "" %}
    {% for i in (start..end) %}
      {% assign temp = productList[i] | where: "available", true %}
      {% assign slice = slice | concat: temp %}
    {% endfor %}
    
    {% assign productList = slice %}
    

    And this as product loop

     {% for variant in productList %}
        {% include 'product-card-grid2', max_height: max_height %}
     {% endfor %}
    

    Also remember the next button

     {% unless end > maxSize %}
        <a href="?page={{current_page | plus: 1}}">Next Page</a>
     {% endunless %}
    

  2. You can’t achieve this only with liquid.

    You can paginate the products but the variants will throw the logic of.

    So there is not a lot of you can do.

    One hacky ways is to overwrite the paginate limit to something crazy to show all the products and create a JS paginate instead of a liquid one.

    Example:

    {% paginate collection.products by 9999 %}
    {% for product in collection.products %}
      {% if product.variants.size == 0 %} 
        {% include 'product-card-grid2', max_height: max_height %}
      {% else %}
        {% for variant in product.variants %}
          {% include 'product-card-grid2', max_height: max_height %}
        {% endfor %}
      {% endif %}
    {% endfor %}
    {% endpaginate %}
    

    But if you have a lot of products the load time will be crazy slow for the back-end to process the request.


    Another option is to create a GraphQL query with the Storefront API and populate the page via JS. Bu this may be an overkill for such a thing.


    Another option is to use some kind of an App that will pull the variants and create the pagination for you. ( via JS once again )


    Last option is to describe this to your client and that you don’t have an easy/optimised way to handle variants pagination because of Shopify limitations.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search