Mr Eggtart.

Relative Path in Zola

Zola is a static site generation engine written in Rust. It is blazing fast. It has almost everything I need. However, there are also some quirks that I do not like. For one, for some reasons, it is difficult to get relative path working. I like relative path, because it makes everything easily portable. So here is my solution for now:

{# filename: templates/macros/urls.html #}

{% macro rel_url(path, trailing_slash=false, cachebust=false) %}
    {%- set url = get_url(path=path, trailing_slash=trailing_slash, cachebust=cachebust) | replace(from=config.base_url, to="") -%}
    {%- if url is starting_with("//") -%}
        /{{- url | trim_start_matches(pat="//") -}}
    {%- else -%}
        {{- url -}}
    {%- endif -%}
{% endmacro rel_url %}

Luckily, config.base_url has the domain path of the URL. So what this macro does is wrap around the built-in get_url call. get_url returns absolute URL. I then remove config.base_url if it is present in the URL. Then I replace the extra // with /. There you have the relative URL.

How to use it?

You put the import in a template. And then call the macro like the following.

{% import "macros/urls.html" as macros %}

<a href="{{macros::rel_url(path=post.permalink, trailing_slash=true)}}">A Relative Post Link</a>

For Markdown, I do not know how to make it work cleanly

### A header {#someheader}

[Link to header in absolute url](#someheader)
E.g., "https://some.blog/posts/relative_url/#someheader"

The workaround:
[Link to header in relative url](./#someheader)
E.g., "./#someheader"

The workaround is not as clean, but at least it works.

I hope this post saves you time.