1

I’m trying to do something, the answer to which should be as simple as searching a Matrix field value but that’s not working for reasons I can’t fathom.

Setup

  • I have a Matrix field called programme.
  • It includes a block type called item.
  • That block type has a field with a handle of od.
  • I have a test case entry that has 4 item blocks in it.
  • All 4 of these blocks have a value in their od field but I need to check for scenarios where some or all of those blocks have that field empty.

So, I’m querying:

{% set talks   = entry.programme.type('item').all() %}
{% set odTalks = entry.programme.type('item').od(':notempty:').all() %}

…and then checking that works with:

<pre>
    talks: {{ talks|length }}
    odTalks: {{ odTalks|length }}
</pre>

…and the result I’m getting is:

talks: 4
odTalks: 0

I’ve tried other search values I know should work with the specific entry’s values, including regex strings. I've tried searching other fields in the block, and nothing works.

What could I be doing wrong?


Would be a shame to have to do something like this just to compare the lengths of talks and odTalks and act accordingly…

{% set odTalks = 0 %}

{% for talk in talks %}
    {% if talk.od is not empty %}
        {% set odTalks = odTalks + 1 %}
    {% endif %}
{% endfor %}

…even though that works and produces the expected:

talks: 4
odTalks: 4
2

My guess would be that this is happening due to lingering parameter values, as it looks like you’re not using clone() at all.

For every place that you are calling entry.programme, change to clone(entry.programme). For example:

{% set talks   = clone(entry.programme).type('item').all() %}
{% set odTalks = clone(entry.programme).type('item').od(':notempty:').all() %}

If you don’t clone the entry query before setting parameters on it and executing it, then whatever parms you set will stay set on it the next time you access the same entry query further on in your template.

(That is mentioned throughout the docs wherever we demonstrate setting parameters on element query field values, e.g. under Working with Matrix Field Data. But I realize it’s awkward & annoying – see craftcms/cms#5640 for my idea of how to improve this in Craft 4.)

If adding clone() functions everywhere doesn’t solve this on its own, the next thing I’d do is run the query through getRawSql() and see what that produces:

<pre>{{ clone(entry.programme).type('item').od(':notempty:').getRawSql() }}</pre>

You can paste the query that’s output into a MySQL client, and see if there’s anything obviously wrong with it. Or paste it into your question above.

| improve this answer | |
  • Thanks Brad. All very good to know. Will try this. – Jonathan Schofield Aug 19 at 16:04

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.