Get the content without the summary

On my site, I sometimes want to use tables of content. However, I would prefer to include them after the first paragraph (similar to how Wikipedia does it). My idea is to use the break created by adding a summary (with <!-- more -->), i.e. put the summary on top, then the table of contents, then the rest of the content. For this, I would need a page variable containing only the rest of the content, so the summary doesn’t repeat (and preferably without the auto-generated continue-reading span, as I can add that myself in this case). Does something like this exist? Or is there another way of injecting a table of contents into the middle of my post?

2 Likes

There’s no way to do that right now in zola, but that would be easy to do in JS

I’d like to second this, as a feature request. This should be pretty straightforward to code and not require JavaScript.

Okay, I’ve found two workarounds: The first one is to use

    {{ page.summary | default(value="") | safe }}
    <!-- toc here -->
    {{ page.content | replace(from = page.summary | default(value=""), to= "") | safe }}

the downside of this is that the replace function replaces all occurrences, which feels a bit weird (but also that’s an issue with Tera default functions tbh).

An alternative way is to use split:

    {% set content = page.content | split(pat="<!-- TOC -->") %}
    {% if content | length > 1 %}
    {{ content[0] | safe }}
    {% endif %}

    <!-- TOC here -->

    {% if content | length > 1 %}
    {{ content[1] | safe }}
    {% else %}
    {{ content[0] | safe }}
    {% endif %}

This one puts the TOC where you write <!-- TOC -->. The advantage is that this is not bound to the “summary” feature anymore, and you can better customize where to put it. I agree that the code is a bit less elegant, though it would have a rather pretty solution if I could store templated blocks into their own variable. Still need to figure that out.