[Special Summer Sale] 40% OFF All Magento 2 Themes

Cart

Is it possible to use a liquid "where" array filter with nested properties?

  • This topic is empty.
Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #9225
    David Hoang
    Keymaster

    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.

    #9226
    David Hoang
    Keymaster

    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 %}
    
    #9228
    David Hoang
    Keymaster

    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.

    #9227
    David Hoang
    Keymaster

    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 %}
    
Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.