Zola: Breadcrumbs

Created on 10 Apr 2018  ยท  18Comments  ยท  Source: getzola/zola

From messing around with Gutenberg for an hour or so, one of the features I'm missing (or can't seem to find documentation for) is a "breadcrumbs"-like navigation.

For example, if I have:

.
โ”œโ”€โ”€ _index.md
โ”œโ”€โ”€ section_a
โ”‚ย ย  โ”œโ”€โ”€ subsection_aa
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ _index.md
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ subsection_page.md
โ”‚ย ย  โ”œโ”€โ”€ _index.md
โ”‚ย ย  โ”œโ”€โ”€ section_page.md
โ”‚ย ย  โ””โ”€โ”€ antother_page.md
โ””โ”€โ”€ section_b
    โ””โ”€โ”€ _index.md

and I'm on site.com/section_a/subsection_aa/subsection_page/, I'd like to be able to create a navbar at the top like:

home > section_a > subsection_aa > subsection_page title

Or if I'm on site.com/section_a/subsection_aa/ itself, I might see:

home > section_a > subsection_aa title

It seems like {{section.components}} might get me close, but I would like to be able to fetch full data about the parent (and grandparent, etc.) so that I can get their permalink, title, and so on.

Is there a neat trick that I could do to build this, or maybe something I'm missing that would allow me to build this?

Thanks!

done enhancement

Most helpful comment

It's all in the next branch

All 18 comments

Taking a look at how this works under the hood a little, I think if we could add "parent" to the serialization of Section and Page somehow, we'd be closer to getting this to work.

From looking at what {{ __tera_context }} gives you, that might just give you infinite data, though...

Maybe if this hypothetical "parent" field only gave you the path of the immediate parent, and if there was a more generic get_page/get_section that worked for any URL, you could write some sort of recursive macro to build a breadcrumb navigation.

I could see the "parent" field being relatively useful for other purposes too, either way.

Sounds like a good idea to add the parent section for those cases, I'll take a PR!

Another way is to have a root field, an array of all top level sections.

Or we could provide some lineage or breadcrumbs array (of pairs of url => title) that would allow with tera built-in filters (first and last) to walk the breadcrumbs in the direction you like, or just get the parent section as requested in #350. If the array doesn't contain the current page but just the parents, it can be generated once per section (not once per page).

Does more of the parent content/metadata need to be exposed? Keeping it minimal (url/title) will be nice for memory usage but maybe there's use cases i'm not thinking of?

Does more of the parent content/metadata need to be exposed? Keeping it minimal (url/title) will be nice for memory usage but maybe there's use cases i'm not thinking of?

I'm thinking that that should be good enough -- at least for this feature. It might be nice to have additional information about the parent, but that doesn't necessarily need to happen with this issue/request.

I've thought it through a little more. Do we really need to expose the permalink? I think page/section titles would be enough, given that we can use relative URLs to go up in the folder hierarchy. Like go to parent section with <a href=".">, one section up with <a href="..">, two sections up with <a href="../.."> etc.. If some people actually need complete permalinks for some setup, this is also achievable by splitting the current page permalink with '/' and rejoining without the last part of the path.

So given an array of titles for ancestors we could just do something like:

{% set depth = page.ancestors | length %}
{% for ancestor in page.ancestors %}
    <a href="{% if loop.last %}.{% else %}{% set level = depth - loop.index0 %}{{ "../" | repeat(times=level) }}{% endif %}" title="{{ ancestor }}">{{ ancestor }}</a>
{% endfor %}

โ†‘โ†‘โ†‘ Yes i know there's no repeat filter in the templates. Maybe it would be nice to have one though :)

So do you agree with me only titles are important for breadcrumbs? That is, unless some people want to expose actual Page/Section instances for the complete ancestry.

Not 100% related but what about https://github.com/Keats/gutenberg/issues/480
That would make breadcrumbs fairly easy to build

Titles are important but it needs to work across languages once i18n is in so that's another hurdle

See #484 that adds parent_section that should make breadcrumbs pretty easy to add @paulcmal

Oh yeah sorry, forgot to reply earlier. I'll check it out, sounds like it should be good though!

Having thought about it a bit, I don't think it would actually solve the issue of breadcrumbs because it would go from parent to root but breadcrumbs are displayed from root to parent and you can't append to an array in Tera. Maybe having the full list of ancestors paths would be better.

I believe to have nice breadcrumbs, pages and section need to have a list of parent sections, from root to parent. I'm not sure whether to include the index section in that list though as it will always be the first in the array. parents could be called ancestors, whatever is the clearest.

Ideally, it would look like:

<ul class="breadcrumbs">
    {% for parent in page.parents %}
        {% set s = get_section(path=parent, include_pages=false) %}
        <li><a href="{{s.permalink}}">{{s.title}}</a></li>
    {% endfor %}
</ul>

The parameter include_pages of get_section doesn't exist yet but is an easy addition to make it faster for those usecases where you only need the section metadata.

A page/section can still get the parent section by doing {{ page.parents | last }} when needed.

Any thoughts @paulcmal @crsaracco @happycoder97 ?

Sounds good. :+1:

A small suggestion.. I think get_section_metadata(path=parent) or get_section(path=parent, metadata_only=true) is better than get_section(path=parent, include_pages=false)

How is the navbar on the left in https://www.getgutenberg.io/documentation/ implemented?

I like metadata_only, I'll go with that.

How is the navbar on the left in https://www.getgutenberg.io/documentation/ implemented?

https://github.com/Keats/gutenberg/blob/master/docs/templates/documentation.html#L9-L24

It's all in the next branch

The parameter include_pages of get_section doesn't exist yet but is an easy addition to make it faster for those usecases where you only need the section metadata.

That's an elegant solution to the performance issue indeed! But what do you think about the "optimization" i proposed here? I think just having the titles would match 90% of usecases (while being lighter than having to reparse the whole sections).

Maybe the best of both world would be to have the parents as a map of titles โ†’ paths, so one could simply loop through the titles when simply building breadcrumbs (using ../ form links), or get_section on the path when needed for advanced use-cases. What do you think?

A page/section can still get the parent section by doing {{ page.parents | last }} when needed.

Nice :)

But what do you think about the "optimization" i proposed here? I think just having the titles would match 90% of usecases (while being lighter than having to reparse the whole sections).

You never know what people might want so sending all the metadata is safer. The difference in terms of perf for sending all the metadata and only the title is pretty small.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

snsvrno picture snsvrno  ยท  4Comments

svenstaro picture svenstaro  ยท  5Comments

kurji picture kurji  ยท  6Comments

Keats picture Keats  ยท  7Comments

NuLL3rr0r picture NuLL3rr0r  ยท  6Comments