[SOLVED] Filter by template type

I know this has been asked before but I could not get any solution working and since I’m a newbie Grav user, I’m probably missing something very obvious.

I want to make the haywire home.twig file display the latest three blog posts, but not only from /blog (as in the original theme) but from all blogs that I have on the page.

|    |-post1
|    '-post2

I have tried the following (copied from the top of the home.html.twig file)

{% extends 'partials/base.html.twig' %}
{% block content %}
{% set all_blogs = page.collection({
        'items': '@root.descendants',
        'order': {
            'by': 'date',
            'dir': 'desc'

Then trying to use

{% for post in all_blogs.children.slice(0, 3) %}

Which yields no entry at all.

Also, trying any selection like

{% for post in pages.parent.template('blog').children.slice(0, 3) %}

does not work. Nor does

{% for post in page({'items':{'@taxonomy':{'template': 'blog'}}}).children.slice(0,3) %}

All these snippets were tried in the aforementioned twig file. Is that the correct place?

Also, my debug bar does not work, so I am struggling on multiple ends :thinking:

Any help is highly appreciated.

Kind Regards,

I don’t know why none of these attempts work but I’d suggest starting smaller with your loop to try and narrow down the issue such as starting with {% for post in all_blogs %} and just confirm at least something is filtering. There’s a lot to assume here so we’d probably need more code such as what’s in your loop to be able to suggest more.

The debugger is a great help - make sure you have “Twig Debugging” and also the “Debugger” both enabled to use it - but if its not working you can also just output a field directly onto your page so instead of {{ dump(post) }} you can just do something like <p>post test: {{ post }}</p> to see the value instead.


Thanks for your help!

Ok, first I needed to enable the debug bar (which was rather complicated as I needed to add debug bar support to the theme I am using).

So this now works:

{% set allblogitems = page.collection({
    'items': '@root.descendants',
    'order': {
        'by': 'date',
        'dir': 'desc',
}).ofType('item') %}

{% for post in allblogitems if post.parent.template=='blog' %}
{{ post.template() }}
{% endfor %}

The only thing I want to do now, is to restrict the output to 3 items. As of now, all items where the template type is ‘item’ and the parent template is ‘blog’ are shown.

I know I could do this with an if conditional like so:

{% if loop.index0 < 3 %}
{% endif %}

What I would really love is to select all items where the parent is a blog directly in the collection, that way I could use slice.

It might be possible to it like this
{% for post in allblogitems if post.parent.template=='blog'|slice(0, 3) %}
but I don’t think you can slice on a condition like that in a loop so that if statement might be the best way to go.

I don’t know if you can do this with pages but possibly something like this might also work?

{% set allblogitems = page.collection({
    'items': '@page.children': [/blog, /blog2]
    'order': {
        'by': 'date',
        'dir': 'desc',
    'limit': 3
}) %}