Section vs Page

The more I’m using Zola, the less I understand the difference between a section and a page. A section is basically just a page with subpages so why differentiating it ?

My “sections” are pages with subpages and deserve date, taxonomies as well… I think these two should be merged. What are the reasons to keep them separated ?


I think it’s easier to have the two concepts separated for documentation rather than having just some comment saying there is a specific file called which allows to control pagination etc. It’s also easier to name things, eg a section has pages and subsections but if everything is named page it’s harder to understand imo.

You’re right and I think that’s the whole point. There is no reason separating both in terms of functionality but when it comes to explaining how to use zola, it’s very useful to introduce two concepts.

Here is a detail of the front-matter of page only, section only, and both:

# page
date =
updated =
draft = false
slug = ""
path = ""
# section
sort_by = "none"
page_template =
paginate_by = 0
paginate_path = "page"
insert_anchor_links = "none"
render = true
redirect_to = 
transparent = false
# both
title = ""
description = ""
weight = 0
in_search_index = true
template = "some.html"
aliases = []

Here is a detail of the variables available in a template for page only, section only, and both:

# page
date: String?;
year: Number?;
month: Number?;
day: Number?;
updated: String?;
slug: String;
draft: Bool;
summary: String?;
taxonomies: HashMap<String, Array<String>>;
earlier: Page?;
later: Page?;
heavier: Page?;
lighter: Page?;
# section
pages: Array<Page>;
subsections: Array<String>;
# both
content: String;
title: String?;
description: String?;
path: String;
components: Array<String>;
permalink: String;
toc: Array<Header>,
word_count: Number;
extra: HashMap<String, Any>;
translations: Array<TranslatedContent>;
lang: String;
relative_path: String;
ancestors: Array<String>;
assets: Array<String>;
reading_time: Number;

Right now I need my section to have taxonomies and the clean way to do that is to make it a page and to have a section to organize content. In the template, I have to load the section to get the content organization stuff. So I have a template mixing page and section. I think a cleaner way to do that is to have page and section the same object (lets call it “resource”) with the only difference that is a resource whose default template is section.html and or something else is a resource whose default template is page.html. In both templates, the resource will be available with the resource keyword so that template elements (like macros) can be reused for pages and sections.

You can look for example at the section (I ported the site from pelican). It has a breadcrumb feature allowing to browse between subsections and subpages as follows:


But I want it to benefit from the date and taxonomies today reserved to a page (here is a page example):

And I will have to compensate this lack of feature of a section by mixing page and section in my template. That’s an example which might be interesting later when thinking about the design :slight_smile:

Conceptually sections and pages are just a logical way of describing the relationships. A section is a collection of pages, simple.

Technically I get that a section is just a page (with some unique attributes) with a collection of child pages.

If you think sections should have taxonomies you should request it, but changing the concept of sections and pages makes no sense. Why clutter sections with dates for example? Or pages with paginate_path?

The same argument was made for TOC, it was missing in sections, someone made the case for it to be implemented and it was added.

The reality is the current implementation covers 80%+ of the use cases you will find on the web.

1 Like

As soon as sections have a content that can be written and read, there is a reason for them to have a ‘date’ and ‘updated’ attribute. I would like my readers to know how up to date they can expect the section content to be. Right now, I’m putting things like the list of authors or the date in the “extra” entry and I observe that my section and pages share so much templates elements that merging the two will help a lot.

I was just wondering if simplifying the concept will help in terms of software design. But apparently, the cost of having an unused ‘paginate_path’ in pages that are not sections (i.e pages without subpages) is too high.

In this case I will request sections to have date and taxonomies :slight_smile:


I’m posting here because Keats pointed me to this thread after I posted to a different thread: Request to add and section.updated

When I read this thread, I see there is a strong case that one abstraction is simpler, more flexible, and easier to explain in comparison to the current state of affairs.

I recognize there is a transition cost (in terms of both code and documentation). So, in my opinion, the main questions in play are: “is this worth the effort, now?” and “if not, when?” and “who wants to put in the effort to make the change?”.

1 Like

Just to be clear, I personally prefer having the distinction and a few other people like it as well so it’s not as clear cut.

Hello, I’ve read this while looking for a way to get the section variables of the section a page is in.
For me this seems like a benefit of having pages belong to a section.

My simple use case is to have the {{ section.title }} included in the <title> element. So far it seems that a page simply forgets about its section. I see that there is get_section(), but it is a bit inconvenient to run it on every page!

While drafting this, I found the page.components variable has what I need. :slight_smile:

I found this trick useful for exploring what variables existed. In the template of a page:

{% set section = get_section(path="my_section/", metadata_only=true) %}

<h2>section vars</h2>
{% for key,value in section %}
<code>{{ key }} = {{ value }}</code><br>
{% endfor %}
<h2>page vars</h2>
{% for key,value in page %}
<code>{{ key }} = {{ value }}</code><br>
{% endfor %}

example output:

section vars

relative_path = blog/
content =
permalink =
ancestors = []
title = List of blog posts
description =
extra = [object]
path = /blog/
components = [blog]
toc = []
word_count = 0
reading_time = 0
lang = en
assets = []
pages = []
subsections = []
translations = []

page vars

relative_path = blog/
content = <p>Foo</p>
permalink =
slug = my-blog-page
ancestors = [, blog/]
title = My blog page
description =
updated =
date = 2021-02-23
year = 2021
month = 2
day = 23
taxonomies = [object]
extra = [object]
path = /blog/my-blog-page/
components = [blog, my-blog-page]
summary =
toc = []
word_count = 1
reading_time = 1
assets = []
draft = true
lang = en
lighter =
heavier =
earlier = [object]
later =
translations = []

I would like to add a use-case that led me to Zola in the first place because it does not enforce a structure for my site. My use-case might also require adding dates and taxonomies to Sections—

It is a publication that collects several intermittently updated “zines”, each with several single-page articles, but ocassionally with larger multi-page stories.

The first level “zines” are clearly Zola Sections. And the single-page articles therein are clearly Zola Pages. But the longer stories inside these “zines” are Subsections that contain a few Pages of content.

Now the problem becomes if I turn the stories into Sections they can no longer show up on the date-sorted index for every “zine”, even though they are very clearly published in the same manner as all the other single-page articles and are just split apart because they’re longer. Nor can I have any taxonomies for them.

Some of these longer stories may be ongoing series of their own, where I was hoping I would get to update the data-field for their Subsection–Page each time a new chapter (Page) got added under them, and still retain their next/previous navigation. But then I found out we can’t have dates in Sections.

Is there any way for me to get both the automatic indices for these multi-page stories and still have the stories show up under the date-sorted indices of their parent zines?

1 Like

IMHO, the distinction between page and section makes sense, but is too restrictive in its current form, I’m especially being bitten by not being able to preserve the sort order as soon as subsections are introduced. I have a hard time coming up with a use case for separating subsections and pages in something like a menu. Right now, my subsections simply come first and the pages second but that’s just not convenient for the user, who has to scan the list twice for alphabetically sorted sections, or is just lost when sorting by weight where the order is important, f.ex. in a book. In use cases like documentations, the missing summary also makes it impossible to display a decent preview as soon as subsections are used to split the larger pages up.

That being said, how about making a section be a page with more features while still defaulting to a different template like it is now? This way, the fields that people need would be (optionally) present, the different default template would still be a guard between the normal page features and the more advanced section features, which usually contains the more complicated logic in my experience.

For the use case where pages are split into a subsection with its own pages, how about merging the section variables pages and subsections and adding tests to Tera, something like allowing {% if item is page %} or {% if item is section %}, perhaps? That way, we would be able to keep things sorted, while still being able to make a clear distinction when building a menu.

Do you have an example? I made GitHub - getzola/book: Gitbook theme for Zola as a theme and didn’t run any particular issue (unless you mean something different like an actual book)

Still suffering from this. Example:

1 Like