1

Struggling to get multiple relationship filtering working. So want to filter an entry (people) by one or more of the following: - location (entries) - specialism (categories) - team (categories)

For example, if I have any entries that are related to location X, specialism Y and team Z then show them but when trying to use relatedTo with the and parameter I am getting zero results, whether that is in twig or at element API level. I have tried both passing in element ids and objects but with no success, so eg:

{% set relatedTo = [
    'and',
    [
        field: team', 
        targetElement:  teamCategories
    ],
    [
        field: location', 
        targetElement:  locationEntries
    ],
] %}

Then:

{% set entries = craft.entries({ section: 'people' }).relatedTo(relatedTo)  %}

But always seems to return zero results when I know there are matching relationships in the CMS.

Any thoughts?

1

You need to use the has notation in Twig for associative arrays using {}, rather than the normal array notation using [].

This should work:

{% set relatedTo = [
    'and',
    {
        field: 'team', 
        targetElement:  teamCategories
    },
    {
        field: 'location', 
        targetElement:  locationEntries
    },
] %}

Edit: If you want to conditionally check whether any of the relatedTo parameters exist and build the query accordingly, you could do something like this:

{% set relatedTo = null %}

{% set locationRelationCriteria = locationEntries ? { field: 'location', targetElement: locationEntries } : {} %}

{% set teamRelationCriteria = teamCategories ? { field: 'team', targetElement: teamCategories } : {} %}

{% set specialismRelationCriteria = specialismCategories ? { field: 'specialism', targetElement: specialismCategories } : {} %}


{% set relationCriteraCount = locationRelationCriteria | length + teamRelationCriteria | length + specialismRelationCriteria | length %}


{# relationCriteriaCount will equal 2 * the number of relation criteria with values, since the length of the criteria hash with values is 2 #}
{# so if relationCriteriaCount > 2, there must be more than one criteria with values, so we'll need to 'and' them together #}

{% if relationCriteraCount > 2 %}

    {% set relatedTo = [ 'and' ] %}

    {# Now go through each criteria and merge if it is not empty #}

    {% if locationRelationCriteria %}
        {% set relatedTo = relatedTo | merge([locationRelationCriteria]) %}
    {% endif %}

    {% if teamRelationCriteria %}
        {% set relatedTo = relatedTo | merge([teamRelationCriteria]) %}
    {% endif %}

    {% if specialismRelationCriteria %}
        {% set relatedTo = relatedTo | merge([specialismRelationCriteria]) %}
    {% endif %}

{% elseif relationCriteraCount == 2 %}

    {# relationCriteraCount == 2 so there must be only one relation criteria with values #}

    {% set relatedTo = locationRelationCriteria ?: teamRelationCriteria ?: specialismRelationCriteria ?: null %}

{% endif %}

{% if relatedTo %}
    {% set entries = craft.entries({ section: 'people' }).relatedTo(relatedTo) %}
{% endif %}
  • thanks Steve - struggling to see how to build this dynamically though, eg build out the elements of the associative array if values are present (if that makes sense) – Cole Henley May 29 at 12:26
  • I've edited my answer to include conditional checking for related criteria. Is this what you were after? – Steve Rowling May 29 at 14:54
1

Thanks for the pointers and help with this @Steve - so after some struggles have finally got this working.

So needed to pass related ids or elements likes so (using ids for brevity):

{% set entries = craft.entries({ section: 'people' }).relatedTo({ 
    targetElement: [
        'and',
        7,
        136
    ] }) %}

The issue before was (based on the documentation) abstracting the target elements I wanted to query into separate array elements, eg:

[
    'and',
    { targetElement: 7 },
    { targetElement: 136 }
]

Hopefully, that helps somebody else experiencing similar issues. The same principle works at a plugin/PHP level, eg:

$peopleEntries = Entry::find()->section('people')->relatedTo(
    ['targetElement'=>['and',7, 136]]
);

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.