CASE: Push & Pop (How to seamlessly add/remove items in/from an array)

Hi there :raised_hand_with_fingers_splayed:,

Let me introduce you to push and pop, our 2 fresh new tags in liquid.

If you regularly create arrays in your templates, you sometimes have to deal with the problem of assigning a separator (using the append filter) to divide the different items that are part of that array. Many times, separators like commas or dots will cause issues as they might be part of those items. In order to make your life easier and the code clearer, we introduced these 2 tags.

Here is the syntax:

{% push item to:array %}
{% pop array to:var %}

By default, Push & Pop work with the LIFO (Last In First Out) logic:

  • push will add an item at the end of your array
  • pop will remove the last item of your array and will give you the option to store this value into a variable (to:var is optional).

It is possible to override the LIFO behaviour with the attribute at:beginning and insert/remove to/from the head rather than the tail of the array:

{% push item to:array at:beginning %}
{% pop array to:var at:beginning %}

Of course, before you start using push & pop, you need to create an array. You can always create a blank one in the following way:

{% assign test_array = test_array | split:'' %}

The split filter, converts that variable into an array (you just leave the space between the quotation marks empty).

As always, it’s better to understand the theory with an example. Let’s say we have a table with a list of invoices and their calculated VAT amounts. We want then to show a summary of the VAT values for 2019 at the end of our template or in a different one. We can create an array that stores the information in the following way:

{% assign array_2019 = array_2019 | split:'' %}

{% stripnewlines %}
<table class="usr-width-100 usr-bordered">
  <thead>
    <tr>
      <th>Invoice date</th>
      <th>Invoice amount</th>
      <th>VAT rate</th>
      <th>Tax to pay</th>
    </tr>
  </thead>
  <tbody>
    {% fori item in custom.my_collection %}
      <tr>
        <td>
          {% input item.invoice_date as:date %}
          {% assign invoice_year = item.invoice_date | date:'%Y' %}
        </td>
        <td>
          {% input item.invoice_amount as:currency %}
        </td>
        <td>
          {% input item.vat_rate as:percentage %}
          {% assign tax_to_pay = item.invoice_amount*item.vat_rate %}
        </td>
        <td>
          {{ tax_to_pay | currency }}
        </td>
        {% if INT(invoice_year) == 2019 %}
          {% push tax_to_pay to:array_2019 %}
        {% endif %}
      </tr>
    {% endfori %}
    
  </tbody>
</table>
{% endstripnewlines %}

To print the contents of my array I simply loop over it:

**First array**
<table>
  <tbody>
    {% for item in array_2019 %}
      <tr>
        <td>{{ item | currency }}</td>
      </tr>
    {% endfor %}
  </tbody>
</table>

image

With pop I can remove the last VAT amount from the array and store it on a variable called “last_tax_to_pay”

{% pop array_2019 to:last_tax_to_pay %}

**Second array**

<table>
  <tbody>
    {% for item in array_2019 %}
      <tr>
        <td>{{ item | currency }}</td>
      </tr>
    {% endfor %}
  </tbody>
</table>


Last tax item to pay: {{ last_tax_to_pay | currency }}

image

On the second array, you can see how the last item has disappeared and can now be shown by printing the variable name.

Hope it’s clear. Do not hesitate to ask any questions if not :wink:

Best,
Borja

This case has been updated on 03/10/2022 to include HTML tables.

1 Like

This is great functionality!

I do have a question though: Is it possible to pop a specific value from the array? I’ll give you an example where I need this:

{% if custom.[question_key].answer == blank %}
    {% assign [rgs_key] = [rgs_key]+1 %}
    {% assign [group_description] = [group_description]+1 %}
  {% else %}
    {% push rgs_key to:rgs_prepared %}
  {% endif %}

So the push works like a charm, but what happens when the user makes the checked text field blank once more? I cannot use pop, since this might very well not me the last item pushed. So, can I add citeria to the pop? Or would I still need to use the old timey ‘remove’ here?

Hi Ronald,

Good question! Unfortunately pop can only delete the first or the last item of the array. That functionality might be implemented in the future but for now you have to use remove I am afraid.

Best,
Borja