skip to Main Content

I’m trying to filter an array of blocks using block settings. I can filter by properties like “type” using the following syntax:

{% assign example = section.blocks | where: "type", "photos" %}

What I need to do is filter by block settings, something like this:

{% assign example = section.blocks | where: settings.collection, collection.handle %}

The above example is failing silently.

A note: Currently I am accomplishing what I need using a capture with a for loop and an if statement, and then assigning with a split — but the code is so bloated, and doing all that for a simple filter operation seems ridiculous. I find myself constantly feeling like I’m fighting with liquid, and I guess I’m hoping it might be just a bit more elegant than I’m giving it credit for.

3

Answers


  1. You are doing it wrong. where will work only at the root element. In your case section.blocks is the root element so where can be used for something like section.blocks.abcd_property.

    Rough example: {% assign example = section.blocks | where: 'collection', collection.handle %} will load all section blocks having their collection property as collection.handle value

    This will work

    {% if settings.collection == collection.handle  %}
    {% assign example = section.blocks %}
    {% else %}
    {% assign example = '' | split: '' %}
    {% endif %}
    
    Login or Signup to reply.
  2. I don’t know much about Ruby, but it seems you can’t pass nested properties with dot notation to the where filter. However, after seeing people accessing nested values using map, I tested mixing the two, and the map filter seems to work well for this case.

    I have a boolean setting called default in my blocks, and I got the settings object for the last block with default set to true using this:

    {% assign obj = section.blocks | map: 'settings' | where: 'default' | last %}
    

    Of course, then you can’t get data outside of the settings object that was extracted. For that I think you really would need to loop through the section.blocks and find filter manually using the if tag.

    Login or Signup to reply.
  3. Previously used map which loses outer data but found string notation works with where for nested properties:

    E.g., Using a posts collection where each .md file has the front-matter:

    header:
        isArchived: true
    

    The following liquid snippet filters archived posts via header.isArchived:

    {% assign archived = site.posts | where: "header.isArchived", true %}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search