Skip to content

Query & Collection Helpers ​

take() / takeOne allow your templates to indifferently consume ElementQuerys, Collections, plain arrays, single Model instances and even hashes / assoc arrays, and handle them all in the same way when you want to consume them.

take() ​

It also accepts an optional second limit parameter that will limit the quantity of items in the returned collection.

It is available as both a Twig function and a filter.

twig
{% set featuredItems = take(aQueryOrArrayOrCollection, 4)  %}

Expanded example:

twig
{% set entryQuery = craft.entries.section('news') %}
{% set entryQueryResult = craft.entries.section('news').all() %}
{% set entryCollection = craft.entries.section('news').collect() %}
{% set singleEntry = craft.entries.section('news').one() %}

...

{% for entry in take(entryQuery, 4) %}
  {{ component('card/news', { data: entry })}}
{% endfor %}

{% for entry in take(entryQueryResult, 4) %}
  {{ component('card/news', { data: entry })}}
{% endfor %}

{% for entry in take(entryCollection, 4) %}
  {{ component('card/news', { data: entry })}}
{% endfor %}

{% for entry in take(singleEntry, 4) %}
  {# Only one card will be output here #}
  {{ component('card/news', { data: entry })}}
{% endfor %}

takeOne() ​

takeOne() returns the first item from a array-like set, null if the set was empty, or just the item itself in any other case. It is available as both a Twig function and a filter.

That means ugly code like this:

twig
{% set image = data.imageField[0] ?? data.imageField[0] ?? null %}

Can be replaced with the much more expressive:

twig
{% set image = takeOne(data.imageField) %}

Expanded example:

twig
{# This could be a query, or a collection for an eager loaded relation #}
{% set assetQuery = data.imageField %}
{% set assetQueryResult = data.imageField.all() %}
{% set singleAsset = data.imageField.one() %}
{% set fakeAsset = {
 title: 'Placeholder image',
 url: 'https://www.fillmurray.com/400/300',
 alt: 'Unbelievabill',
 width: 400,
 height: 300,
} %}

{% set images = [
 assetQuery,
 assetQueryResult,
 singleAsset,
 fakeAsset,
] %}

...
<section>
 {% for image in images %}
   {# takeOne() doesn't care #}
   {{ component('image', { data: takeOne(image)} ) }}
 {% endfor %}
</section>

fill() ​

fill() is useful when you want to be sure to end up with a set number of list items in total, drawing from a series of sources in preferential order. It is available as a Twig function.

twig
{% set featuredItems = craft.entries.section('news').isFeatured(true) %}
{% set otherItems = craft.entries.section('news').isFeatured(false) %}

{% for item in fill(5, featuredItems, otherItems) %}
  {# This loop will run five times, outputting (say) 3 x `featuredItems` (all found) and then 2 x other items #}
{% endfor %}