Dan Dan - 12 days ago 10
Twig Question

Twig: elegant way to output array elements in a grid of N columns with if condition

I'm using Timber & Twig to write a Wordpress theme. It is my understanding that the idiomatic way of outputting posts in a grid with N columns is with the

batch
filter:

{% block content %}

{% for row in posts | batch(3) %}
<div class='grid-3'>
{% for post in row %}
<div class='col'>
{% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endblock %}


How would one go about using the
batch
filter with an
if
condition such that you only output, for example, top level posts in a hierarchy?

(Condition would be
{% if not post.parent %}
)

Answer

As far as I know, this is not possible. If you’re looking for an elegant way, I recommend going a different one:

Whenever I can, I don’t filter posts in Twig, but in PHP, before the posts are being passed to the template. With Timber, there are multiple ways you can go:

1. Adapt the query

Using the proper parameters for WP_Query, you can often select only the posts you need.

$context['posts'] = Timber::get_posts( array(
    'post_parent' => 0
) );

2. Filter the query results

Sometimes using a lot of parameters in WP_Query can make your query slow. For performance reasons it’s sometimes better to query more posts that you later filter with PHP.

$posts = Timber::get_posts();

$filtered = array();

foreach ( $posts as $post ) {
    if ( $post->post_parent === 0 ) {
        $filtered[] = $post;
    }
}

$context['posts'] = $filtered;

or

$posts = Timber::get_posts();

$posts = array_filter( $posts, function( $post ) {
    return $post->post_parent === 0;
} );

$context['posts'] = $posts;
Comments