Managing content in two columns

I’ve a template ‘columns.html.twig’, with two columns as following:


{% for child in page.collection %} {% if child.header.position!="right" %} {% include 'partials/item.html.twig' with {'page':child, 'truncate':true} %} {% endif %} {% endfor %}
{% for child in page.collection %} {% if child.header.position=="right" %} {% include 'partials/item.html.twig' with {'page':child, 'truncate':true} %} {% endif %} {% endfor %}

As you can see, the twig-code loops through each sub-page and renders the content of each sub-page with the ‘partials/item.html.twig’ template.
By the way: This only works, when you define a ‘’ with following header information:

    items: @self.children
        by: name
        dir: asc

You then just have to put the content for the two columns in sub-folders. In the item.html.twig of each sub-page you only have to put a variable named ‘position’


title: Aktuell
position: right

If position equals ‘left’ or is missing the content is rendered in the left column.
In the item.html.twig it is also possible to render an image with for instance

{{|first.cropZoom(900,300).html }}

My Question: Is there a better (less complicated) way to manage content in two or more columns?

Do you really want to be specifying left and right columns? I think you really just want two columns right?

How do you want your articles distributed? left, then right, the left then right? or the first half on left and the second on right?

I would probably implement this so that you don’t have to specify anything in the pages themselves, just a header toggle on the main ‘blog’ page to indicate two columns. Then in your twig file loop over the collection of pages and build a left and right array (based on your requirement for how they should be distributed.

Then you can just have a your two columns and output the columns by looping over the left and right arrays.

Another alternative that would be a little faster and more efficient would be that when you are looping over your pages the first time in the Twig, instead of building two arrays, build two strings. By this i mean build two strings of the rendered output, so that in the part where you are rending your columns, you don’t need to loop again, you can just display the left and right column string that you have already output.

Hope that makes sense!

The project I am working on is not a blog. It’s a website of a club, wich presents the work of stone artists.
So I have to know, wich part of my site appears on the left and wich part on the right.
Nevertheless thank you very much for your comprehensive informations!

Until now the site is running with contao. But I’m looking for a simpler yet flexible cms. Grav is in the narrower choice!

Why don’t you just specify responsive grid to display the items using 50% of the width and let CSS (or browser) to decide where to place the items?

It’s not only a blog, where it doesn’t matter, where the content is placed. Especially on title pages you often want to explicitly determine, where the content is rendered. For instance think of a left column with a welcome text and a right column with news.
(See the picture “2columns” in my last post)

In that case nothing prevents you from using 2 separate collections with different taxonomies? page.collection() is a function that takes an array just like the one you define in your page frontmatter. You can either pass the array directly or you can define one in your file header.

        by: modified
        dir: desc
    limit: 10
    pagination: false

And then just call:

{% for child in page.collection(page.header('news')) %}

Or shortcut to the page header:

{% for child in page.collection('news') %}

This is an interesting appoach. Thank you! I’ll give it a try…

Ok, I tried it, but there seems still something, I don’t understand. Let’s say, I’ve got a page called ‘’ and a corresponding template called ‘main.html.twig’. Beyond that there are subfolders of, that hold files called and also there is a template called item.html.twig.
Assuming that only one item-content should displayed in the main page, wich syntax I had to use for the taxonomy variable in that ?
Simple graph:
— subfolder with
— subfolder with (this item-content should be shown!)
— subfolder with

I tried following:


title: My Main Page
        by: name
        dir: asc



In main.html.twig:

{% for child in page.collection(page.header('news')) %}
{{ child.content }}
{% endfor %} 

And I get this exception:

An exception has been thrown during the rendering of a template (“Argument
should be either header variable name or array of parameters”) in “main.html.twig” at > line 65.

Remark: I also defined the taxonomie ‘news’ in the site.yaml.

At line 65 of main.html.twig what happened?

It was following line :

page.collection(page.header('news')) %}


instead your code.

Doing so avoids at least the exception. So far so good. But I see no content…