Skip to main content

Query Items

This page covers how to loop over raw data — static arrays, ACF repeater fields, or any dynamic data.

Unlike the Post, Term, and User query types, Item doesn't query the database. It wraps existing data so you can loop over it.

Basic usage​

Paste this directly into the Item Source field in the Loop block's sidebar:

[
{"name": "Home", "url": "/"},
{"name": "About", "url": "/about"}
]

Inline arrays​

Array of objects​

Each object becomes an item with named properties:

[
{"name": "Home", "url": "/"},
{"name": "About", "url": "/about"},
{"name": "Contact", "url": "/contact"}
]

Simple values​

When items are plain strings or numbers, item is the value itself:

["Home", "About", "Services", "Contact"]

Numbered items​

[0, 1, 2, 3, 4]

Key-value pairs​

When items are an object (associative array), each item is a value, as in Twig:

{
"color": "red",
"size": "large",
"weight": "2kg"
}

To get the keys too, name them before the value, separated by a comma. In the sidebar, set the data alias to key, value; in the inspector, write:

{% for key, value in get_items() %}
<dt>{{ key }}</dt>
<dd>{{ value }}</dd>
{% endfor %}

In a list, the key is the position of the item, from 0.

These fields return a map, ready for a key-value loop:

  • request.get and request.post without a key: parameter names and values
  • post.meta and post.raw_meta without a key: meta keys and values
  • post.terms('all', {merge: false}): each taxonomy and its terms
  • site.theme: the theme's fields
  • a product's default_attributes, and a variation's variation_attributes: attribute slugs and values
{% for name, value in request.get %}
<dt>{{ name }}</dt>
<dd>{{ value }}</dd>
{% endfor %}

Rows of items​

batch groups a list into rows: loop over the rows, then over each row in a nested Loop block.

{% for row in post.meta('gallery', {transform_value: true})|batch(3) %}
<div class="row">
{% for image in row %}
<img src="{{ image.src('medium') }}" alt="{{ image.alt }}">
{% endfor %}
</div>
{% endfor %}

ACF fields​

Enter a dynamic expression in the Item Source field to loop over ACF data. A plain name is read first as the name of a Variable, then as an expression.

Repeater fields​

Loop over repeater rows — each row's sub-fields become item properties:

post.meta('team_members')

Nested repeaters — use a second Loop block inside the first, whose data alias is member here:

member.social_links

Relationship and post object fields​

With transform_value, these return full post objects, whatever the field's return format, so you can access post provider fields directly:

post.meta('related_posts', {transform_value: true})
{% for item in post.meta('related_posts', {transform_value: true}) %}
<a href="{{ item.link }}">{{ item.title }}</a>
{% endfor %}

This also works with user, taxonomy, image, and gallery fields. Without the option, you get what ACF returns, as in Timber: see Relational fields.

More examples​

[
{"label": "Home", "url": "/", "icon": "home"},
{"label": "Products", "url": "/products", "icon": "shop"},
{"label": "Blog", "url": "/blog", "icon": "pen"},
{"label": "Contact", "url": "/contact", "icon": "mail"}
]
[
{"name": "Twitter", "url": "https://twitter.com/yourhandle", "icon": "twitter"},
{"name": "GitHub", "url": "https://github.com/yourhandle", "icon": "github"},
{"name": "LinkedIn", "url": "https://linkedin.com/in/yourhandle", "icon": "linkedin"}
]

Pricing table​

[
{"name": "Starter", "price": "9", "features": "5 projects, 1GB storage"},
{"name": "Pro", "price": "29", "features": "Unlimited projects, 50GB storage"},
{"name": "Enterprise", "price": "99", "features": "Everything, priority support"}
]

Template examples​

In the HTML inspector, a Loop block over a JSON list or object shows as get_items(), with empty parentheses: the data stays in the sidebar. An expression source shows as the expression itself. get_items only exists in this tag: it isn't a function you can call in an expression.

Feature list from custom fields​

{% for item in post.meta('features') %}
<div class="feature">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
</div>
{% endfor %}

FAQ accordion from repeater​

{% for item in post.meta('faq') %}
<details>
<summary>{{ item.question }}</summary>
<p>{{ item.answer }}</p>
</details>
{% endfor %}
Common mistake

get_items() is for data you already have. If you need to query posts from the database, use get_posts() — not get_items() with a list of post IDs.

Next steps​

  • Loop — loop concept and data sources
  • get_posts() — query posts from the database