I'm new to all this. Is it possible to use craft.entries to return all entries with an empty entries field? Something like:

{% set drinksWithNoIngredients = craft.entries.section("drinks").ingredients(":empty:") %}
{% for drink in drinksWithNoIngredients %}
    <p>Do something with {{ drink.title }}...</p>

where ingredients is an entries field handle. This doesn't seem to work on entries fields, though. Or maybe I could do some kind of relatedTo magic, where the targetElement is some kind of special null value?

An alternative seems to be this:

{% set drinksWithNoIngredients = craft.entries.section("drinks") %}
{% for drink in drinksWithNoIngredients %}
    {% if not drink.ingredients.total() %}
    <p>Do something with {{ drink.title }}...</p>

But doing it that way calls .total() on every drink. Is that going to cause performance problems if I have a lot of drinks?


You were on the right track using relatedTo. But as there's no notRelatedTo parameter, you'd first have to get all drinks that are related to any ingredient and those entries can then be removed from a new ElementCriteriaModel, that returns all your drinks, using Craft's without filter. Instead of passing whole element models, you should better use this filter with element IDs (→ Why is the Craft without filter not working correctly and how to debug?). To get them just make use of the ids() method.

{% set ingredients = craft.entries.section('ingredients').limit(null) %}
{% set drinksWithIngredientsIds = craft.entries.section('drinks').relatedTo({targetElement: ingredients}).limit(null).ids() %}

{% set drinksWithNoIngredients = craft.entries.section('drinks')|without(drinksWithIngredientsIds) %}
| improve this answer | |
  • Genius! Thanks so much. On a minor note, I had to change the last line to retrieve ids: {% set drinksWithNoIngredientsIds = craft.entries.section('drinks').ids()|without(drinksWithIngredientsIds) %} for the without filter to kick in. I then was able to get all the entries I wanted via: craft.entries.id(drinksWithNoIngredientsIds). – jx7 Apr 17 '15 at 3:08
  • Also, out of curiosity, what role does the .limit(null) parameter play in the first two lines of code? – jx7 Apr 17 '15 at 3:10
  • limit is set to 100 by default. So it just makes sure you include all the ingredients, last line is for the output and you can limit or paginate to your liking. – carlcs Apr 17 '15 at 6:03

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.