Nimbu Developer Docs
Using Filters

Arrays & Collections Filters

Filter, sort, group, and manipulate arrays and collections with powerful helpers

Nimbu provides comprehensive array manipulation filters for filtering, sorting, grouping, and transforming collections.

Array Basics

size

Get array length:

{{ products | size }}
<!-- Output: 42 -->

{% if cart.items.size > 0 %}
  You have {{ cart.items.size }} items
{% endif %}

first

Get first element:

{{ products | first }}

{% assign featured = products | first %}

last

Get last element:

{{ articles | last }}

{% assign latest = blog.articles | last %}

Filtering Arrays

where

Filter array by property value:

{% assign published = articles | where: "published", true %}

{% assign featured_products = products | where: "featured", true %}

{% assign active_members = channels.team.all | where: "status", "active" %}

With Nested Properties:

{% assign expensive = products | where: "price", ">", 100 %}

where_exp

Filter with complex expressions:

{% assign recent = articles | where_exp: "article", "article.date > '2025-01-01'" %}

{% assign in_stock = products | where_exp: "p", "p.inventory > 0" %}

{% assign affordable = products | where_exp: "p", "p.price < 50" %}

Sorting Arrays

sort

Sort by property:

{% assign sorted_products = products | sort: "price" %}

{% assign alphabetical = team_members | sort: "name" %}

{% assign by_date = articles | sort: "published_at" %}

sort_natural

Case-insensitive alphabetical sort:

{% assign sorted = names | sort_natural %}

{% assign sorted_titles = articles | sort_natural: "title" %}

reverse

Reverse array order:

{% assign reversed = products | reverse %}

{% assign newest_first = articles | sort: "date" | reverse %}

Grouping and Organizing

group_by

Group array by property:

{% assign by_category = products | group_by: "category" %}

{% for group in by_category %}
  <h2>{{ group.name }}</h2>
  {% for product in group.items %}
    <p>{{ product.name }}</p>
  {% endfor %}
{% endfor %}

Result Structure:

[
  { name: "Clothing", items: [...] },
  { name: "Electronics", items: [...] }
]

group_by_exp

Group with expressions:

{% assign by_year = articles | group_by_exp: "article", "article.date | date: '%Y'" %}

{% for year_group in by_year %}
  <h2>{{ year_group.name }}</h2>
  {% for article in year_group.items %}
    <p>{{ article.title }}</p>
  {% endfor %}
{% endfor %}

{% assign by_price_range = products | group_by_exp: "p", "p.price | divided_by: 100 | times: 100" %}

Array Transformations

map

Extract property from all items:

{% assign product_names = products | map: "name" %}
<!-- Output: ["Product A", "Product B", "Product C"] -->

{% assign all_tags = articles | map: "tags" | flatten | uniq %}

{% assign prices = products | map: "price" %}

compact

Remove nil values:

{% assign clean_array = values | compact %}

{% assign valid_emails = users | map: "email" | compact %}

uniq

Remove duplicates:

{% assign unique = tags | uniq %}

{% assign all_categories = products | map: "category" | compact | uniq %}

flatten

Flatten nested arrays:

{% assign all_tags = articles | map: "tags" | flatten %}

{% assign flattened = nested_array | flatten %}

Array Slicing

slice

Extract portion of array:

{% assign first_three = products | slice: 0, 3 %}

{% assign items = array | slice: 5, 10 %}
<!-- Get 10 items starting from index 5 -->

offset / limit

Paginate arrays:

{% assign page_items = products | offset: 10 | limit: 20 %}
<!-- Skip first 10, take next 20 -->

{% assign recent = articles | limit: 5 %}

Set Operations

concat

Combine arrays:

{% assign combined = array1 | concat: array2 %}

{% assign all_items = featured_products | concat: new_products %}

join

Join array into string:

{{ tags | join: ", " }}
<!-- Output: "tag1, tag2, tag3" -->

{{ categories | join: " | " }}

split

Split string into array:

{% assign tags = "red,blue,green" | split: "," %}

{% assign words = sentence | split: " " %}

Practical Examples

Product Filtering and Sorting

<div class="product-grid">
  <!-- Get in-stock products, sorted by price -->
  {% assign available = products | where: "available", true %}
  {% assign sorted = available | sort: "price" %}

  {% for product in sorted %}
    <div class="product-card">
      <h3>{{ product.name }}</h3>
      <p class="price">{{ product.price | money_with_currency }}</p>
      <a href="{{ product.url }}">View Product</a>
    </div>
  {% endfor %}
</div>

Blog Archive by Year and Month

<div class="blog-archive">
  {% assign by_year = blog.articles | group_by_exp: "article", "article.published_at | date: '%Y'" %}

  {% for year_group in by_year | reverse %}
    <div class="year-section">
      <h2>{{ year_group.name }}</h2>

      {% assign by_month = year_group.items | group_by_exp: "article", "article.published_at | date: '%B'" %}

      {% for month_group in by_month %}
        <div class="month-section">
          <h3>{{ month_group.name }}</h3>

          <ul class="article-list">
            {% for article in month_group.items %}
              <li>
                <a href="{{ article.url }}">
                  {{ article.title }}
                </a>
                <time>{{ article.published_at | date: "%d" }}</time>
              </li>
            {% endfor %}
          </ul>
        </div>
      {% endfor %}
    </div>
  {% endfor %}
</div>

Category Navigation with Counts

<nav class="category-filter">
  {% assign by_category = products | group_by: "category" %}

  <ul class="category-list">
    {% for group in by_category | sort: "name" %}
      <li>
        <a href="?category={{ group.name | parameterize }}">
          {{ group.name }}
          <span class="count">({{ group.items.size }})</span>
        </a>
      </li>
    {% endfor %}
  </ul>
</nav>
<div class="related-products">
  <h3>You May Also Like</h3>

  {% assign same_category = products | where: "category", product.category %}
  {% assign others = same_category | where_exp: "p", "p.id != product.id" %}
  {% assign related = others | limit: 4 %}

  <div class="product-grid">
    {% for item in related %}
      <div class="product-card">
        <img src="{{ item.images.first.url | filter, width: '300px' }}" alt="{{ item.name }}">
        <h4>{{ item.name }}</h4>
        <p class="price">{{ item.price | money_with_currency }}</p>
      </div>
    {% endfor %}
  </div>
</div>

Tag Cloud with Frequency

<div class="tag-cloud">
  {% assign all_tags = articles | map: "tags" | flatten %}
  {% assign unique_tags = all_tags | uniq | sort_natural %}

  {% for tag in unique_tags %}
    {% assign count = all_tags | where: tag | size %}

    <a
      href="/blog/tag/{{ tag | parameterize }}"
      class="tag"
      style="font-size: {{ count | times: 2 | plus: 12 }}px;">
      {{ tag }} ({{ count }})
    </a>
  {% endfor %}
</div>

Price Range Filtering

<div class="price-ranges">
  {% assign ranges = products | group_by_exp: "p", "p.price | divided_by: 50 | times: 50" %}

  <ul class="range-list">
    {% for range in ranges | sort: "name" %}
      {% assign min = range.name %}
      {% assign max = range.name | plus: 49 %}

      <li>
        <a href="?price_min={{ min }}&price_max={{ max }}">
          {{ min | money_without_currency }} - {{ max | money_without_currency }}
          <span class="count">({{ range.items.size }})</span>
        </a>
      </li>
    {% endfor %}
  </ul>
</div>

Pagination with Array Slicing

{% assign page = params.page | default: 1 | to_i %}
{% assign per_page = 12 %}
{% assign offset = page | minus: 1 | times: per_page %}

{% assign page_items = products | offset: offset | limit: per_page %}
{% assign total_pages = products.size | divided_by: per_page | ceil %}

<div class="products">
  {% for product in page_items %}
    <!-- Product card -->
  {% endfor %}
</div>

<nav class="pagination">
  {% if page > 1 %}
    <a href="?page={{ page | minus: 1 }}">Previous</a>
  {% endif %}

  {% for i in (1..total_pages) %}
    <a href="?page={{ i }}" {% if i == page %}class="active"{% endif %}>{{ i }}</a>
  {% endfor %}

  {% if page < total_pages %}
    <a href="?page={{ page | plus: 1 }}">Next</a>
  {% endif %}
</nav>
{% assign featured = products | where: "featured", true %}
{% assign regular = products | where: "featured", false %}
{% assign all_sorted = featured | concat: regular %}

<div class="product-list">
  {% for product in all_sorted %}
    <div class="product {% if product.featured %}featured{% endif %}">
      <!-- Product display -->
    </div>
  {% endfor %}
</div>

Team Directory by Department

<div class="team-directory">
  {% assign by_department = channels.team.all | group_by: "department" %}

  {% for dept_group in by_department | sort: "name" %}
    <section class="department">
      <h2>{{ dept_group.name }}</h2>

      {% assign sorted_members = dept_group.items | sort: "name" %}

      <div class="team-grid">
        {% for member in sorted_members %}
          <div class="team-card">
            <img src="{{ member.photo.url | filter, width: '200px', height: '200px', cropping: 'fill', gravity: 'face' }}" alt="{{ member.name }}">
            <h3>{{ member.name }}</h3>
            <p class="role">{{ member.role }}</p>
            <p class="email">{{ member.email }}</p>
          </div>
        {% endfor %}
      </div>
    </section>
  {% endfor %}
</div>

Best Practices

1. Chain Filters Efficiently

Order operations for performance:

<!-- ✅ Good: Filter before sort -->
{% assign results = products | where: "available", true | sort: "price" %}

<!-- ❌ Bad: Sort before filter (wastes sorting) -->
{% assign results = products | sort: "price" | where: "available", true %}

2. Use where_exp for Complex Conditions

<!-- ✅ Good: Complex filtering -->
{% assign affordable_in_stock = products | where_exp: "p", "p.price < 100 and p.inventory > 0" %}

<!-- ❌ Bad: Multiple where calls -->
{% assign temp = products | where: "price", "<", 100 %}
{% assign result = temp | where: "inventory", ">", 0 %}

3. Cache Expensive Operations

<!-- ✅ Good: Cache grouped results -->
{% assign by_category = products | group_by: "category" %}
<!-- Reuse by_category multiple times -->

<!-- ❌ Bad: Repeat grouping -->
{% for category in products | group_by: "category" %}...{% endfor %}
{% for category in products | group_by: "category" %}...{% endfor %}

Next Steps

Master array and collection manipulation in Nimbu themes!

On this page