CASE: group custom collection

There’s an extra filter in town group_by which will let you group a custom collection on a certain objects, which will let you display other info related to that grouping with lesser code!

Take this for example:

Above is inputted (or imported) while the below table will be rendered with following code:


{% comment %}create select options for type of shares{% endcomment %}
{% assign share_options = "VG|BE|NA" %}

<table class="usr-width-100 usr-bordered">
  <thead>
    <tr>
      <th class="usr-width-50 usr-line-bottom"><b>Name shareholder</b></th>
      <th class="usr-width-25 usr-line-bottom usr-align-right"><b>Amount of shares</b></th>
      <th class="usr-line-bottom usr-align-right"><b>Type of shares</b></th>
    </tr>
  </thead>
  <tbody>
    {% fori share in custom.shareholders %}{% comment %}custom collection "custom.shareholders" that will later be grouped{% endcomment %}
      <tr>
        <td>{% input share.name %}</td>
        <td>{% =$0+input share.amount_of_shares as:integer %}</td>
        <td>{% input share.type_share as:select options:share_options %}</td>
      </tr>
    {% endfori %} 
    <tr>
      <td></td>
      <td class="usr-line-top usr-line-bottom">{{ $0 | integer }}</td>
      <td></td>
    </tr>
  </tbody>
</table>

<br>


<!-------------------------------- NEWLY FILTER group_by --------------------------------->

{% comment %}group ON type of share using the newly filter GROUP_BY{% endcomment %}
{% assign shares = custom.shareholders | group_by:"type_share" %}{% comment %}this groups all shareholders on type of share; all the other info like name, are automatically grouped as well{% endcomment %}

{% stripnewlines %}
<table class="usr-width-100 usr-bordered">
  <thead>
    <tr>
      <th class="usr-align-right usr-width-10"><b>Type</b></th>
      <th class="usr-align-right usr-width-20"><b>Amount</b></th>
      <th><b>Persons</b></th>
    </tr>
  </thead>
  <tbody>
    {% for share in shares %}
      <tr>
        <td>
          {{ share[0] }}{% comment %}we access the "first part" by [0] which is our type we can display; in [1] is all our other info like name and amount, which are grouped (linked to [0]){% endcomment %}
        </td>
        <td>
          {% for item in share[1] %}
            {% $1+ item.amount_of_shares %}{% comment %}save the amount in register $1{% endcomment %}
          {% endfor %}
          {{ $1 | integer }}{% comment %}display value of $1 outside the second for-loop{% endcomment %}
          {% assign $1 = 0 %}{% comment %}needs to be reset in order to calculate correctly for the next loops to come{% endcomment %}
        </td>
        <td>
          {% for person in share[1] %}
            {{ person.name }}{% comment %}create sting that display the names, grouped on type of share{% endcomment %}
            {% unless forloop.last %}, {% endunless %}
          {% endfor %} 
        </td>
      </tr>
    {% endfor %}
  </tbody>
</table>
{% endstripnewlines %}

Obviously, this has a lot of use-cases. Drop a comment below if you have any questions!

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