1

I'm trying to figure out how to set up my relatedTo paramaters to do a category search. Normally it's not a problem but in this case I need something more complex than normal.

I have multiple category groups. Within each group I need to use an "or" condition. So entries are returned if they match any categories in that group.

But across the different groups I need to apply an "and" condition.

i.e. Group 1 is "colours", Group 2 is "size"

So if someone selects: Group 1: black, blue Group 2: small

I want to return any entries that are (black OR blue) AND (small)

Setting the 'or' condition within a group is no problem but I'm stumped on how I can merge the different sets of parameters together to get the desired results.

This is a truncated version of what I have so far, just showing 2 of my groups.

{# clear everything #}
{% set colourQuery = '' %}
{% set sizeQuery = '' %}

{# get all the search query parameters #}
{% set colour = craft.request.getParam('colour') %}
{% set size = craft.request.getParam('size') %}

{% set colourQuery = colour | join(',') %}
{% set sizeQuery = size | join(',') %}

{# colour #}
{% set colourParams = ['or'] %}
{% set cats = craft.categories.group('colour').slug( colourQuery | split(',') ).find() %}
{% for cat in cats %}
    {% set colourParams = colourParams | merge([{ targetElement: cat }]) %}
{% endfor %}

{# size #}
{% set sizeParams = ['or'] %}
{% set cats = craft.categories.group('size').slug( sizeQuery | split(',') ).find() %}
{% for cat in cats %}
    {% set sizeParams = sizeParams | merge([{ targetElement: cat }]) %}
{% endfor %}

Then I build the criteria... I'm sure this is where I'm going wrong

{# build criteria #}
{% set relatedParams = [] %}

{% set relatedParams = relatedParams | merge(colourParams) %}
{% set relatedParams = relatedParams | merge(sizeParams) %}

I've also tried

{# build criteria #}
{% set relatedParams = [
        ['and', colourParams],
        ['and', sizeParams],
    ] 
%}

I'm using relatedParams like so:

{% set products = craft.commerce.products('products').relatedTo(relatedParams).order(sortString).limit(numPerPage) %}

So, my question is how should I join those different paramater arrays in order to get what I need?

2

After some help from @RobinSchambach on the Craft Slack and a bit of trial and error I got to this, truncated for brevity.

{# clear everything #}
    {% set colourQuery = '' %}
    {% set sizeQuery = '' %}

    {# get all the search query parameters #}
    {% set colour = craft.request.getParam('colour') %}
    {% set size = craft.request.getParam('size') %}


    {% set colourQuery = colour | join(',') %}
    {% set sizeQuery = size | join(',') %}


    {# colour #}
    {% set colourParams = ['or'] %}
    {% set cats = craft.categories.group('colour').slug( colourQuery | split(',') ).find() %}
    {% for cat in cats %}
        {% set colourParams = colourParams | merge([{ targetElement: cat }]) %}
    {% endfor %}

    {# size #}
    {% set sizeParams = ['or'] %}
    {% set cats = craft.categories.group('size').slug( sizeQuery | split(',') ).find() %}
    {% for cat in cats %}
        {% set sizeParams = sizeParams | merge([{ targetElement: cat }]) %}
    {% endfor %}




    {# build criteria #}
    {% set relatedParams = ['and'] %}
    {% if colourQuery != '' %}
        {% set relatedParams = relatedParams | merge([{element : colourQuery}]) %}
    {% endif %}

    {% if sizeQuery != '' %}
        {% set relatedParams = relatedParams | merge([{element : sizeQuery}]) %}
    {% endif %}

The key difference is that I'm using the Category IDs rather than their slugs. I'm then passing them as comma delimited strings into the array to build up the criteria.

I'm working on refining this a bit more but it's now working as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.