Breadcrumb

A mini macro for a breadcrumb:

# usage
{{ macros::breadcrumb(path=page.components | safe) }}

# definition
{% macro breadcrumb(path) %}
{% set cur = "/" %} /
{% for elt in path %}
    {% set_global cur = cur ~ elt ~ "/" %}
    <a href="{{cur}}">{{ elt }}</a> /
{% endfor %}
{%- endmacro %}

Leading to this result:

image

3 Likes

Here is my improved version to build breadcrumbs

# usage
{{ macros::breadcrumb(path=["/tags", term.path], titles=["Tags", term.name]) }}
{{ macros::breadcrumb_page(path=section.components, titles=section.components) }}

# definition
{% macro breadcrumb(path, titles) %}
<script type="application/ld+json">
    {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement":
        [
            {
                "@type": "ListItem",
                "position": 1,
                "item": {
                    "@id": "{{ get_url(path="", trailing_slash=false) }}",
                    "name": "{{ config.title | safe }}"
                }
            }{% if path | length > 0 %},{% endif %}
            {%- for crumb in path %}
            {
                "@type": "ListItem",
                "position": {{ loop.index + 1 }},
                "item": {
                    "@id": "{{ get_url(path=crumb, trailing_slash=false) }}",
                    "name": "{{ titles[loop.index0] | safe }}"
                }
            }{% if not loop.last %},{% endif %}
            {%- endfor %}
        ]
    }
</script>

{%- endmacro %}
{% macro breadcrumb_page(path, titles) %}
{% set cur = "/" %}
{% set path_bc = [] %}
{% for elt in path %}
    {% set_global cur = cur ~ elt ~ "/" %}
    {% set_global path_bc = path_bc | concat(with=cur) %}
{% endfor %}
{{- jsonld_macros::breadcrumb(path=path_bc, titles=titles) -}}
{%- endmacro %}

Source: blog.williamdes.eu/jsonld_macros.html at a7ac3b592fecc9c43640a6be9e376f379471f95a · wdesportes/blog.williamdes.eu · GitHub

1 Like

While both of your solutions are great, i have come-up with something much more better and modular

{% block breadcrumb %}
<div class="breadcrumb-container">
    <a class="breadcrumb-path" href="/">Home</a>
    {% set current = section | default(value=page) %}
    {% for ancestor in current.ancestors %}
    {% if loop.first %}
    {% continue %}
    {% endif %}
    <span class="breadcrumb-separator">/</span>
    {% set section = get_section(path=ancestor) %}
    <a class="breadcrumb-path" href="{{ section.permalink }}">{{ section.title }}</a>
    {% endfor %}
    <span class="breadcrumb-separator">/</span>
    <a class="breadcrumb-path active" href="{{ current.permalink }}">{{ current.title }}</a>
</div>
{% endblock breadcrumb %}

This doesn’t depend on the filename/slug while also leaving space for much more modularity

also, ancestors were added for the purpose of breadcrumbs

Ancestry

Each page and section will now have all their parent sections paths in an ancestors property. This allows you to easily do breadcrumbs as well as just being able to access the parent section, which wasn’t possible before.

Blockquote from: Vincent Prouillet: Developer & Entrepreneur

1 Like

I’m very new to Zola and Tera, so please excuse my lack of knowledge for now.

I just added that last example into the base.html file, but I get the following error:

Error: Failed to render '404.html' (error happened in a parent template)
Error: Reason: Variable `page` not found in context while rendering '404.html'

I’m wondering what if statement should I add at the beginning of that block to cover this case.

Thanks.


Update: For now, I used this simple approach:

{% block breadcrumb %}
    {% if page %}
        <div class="breadcrumb-container">
            ...
       </div>
    {% endif %}
{% endblock breadcrumb %}

You have to include the macro and call it in your template. See this theme for example: https://git.42l.fr/HugoTrentesaux/Albatros