2021-09-11, updated on 2024-01-06
I've finally settled (for now) on the Zola static-site generator. This is largely because it's simple, with no bells and whistles from the start, and very good getting started documentation. This post is to just outline a few of the things I've found that took me a while to figure out, or that I thought were non-trivial.
The official docs are useful as a starting point.
I couldn't find a way to reference one section from another. That is, to have posts stored in /content/blog/*.md, but list those posts from /content/_index.md and the base template. I ended up just using /content as the blog section. It's a little messy, but it works at least.
It's nice to be able to inline a small (resolution and file size) image in a post, but to still have the full-size image available for those who want to view it. I started off in the docs for this which are quite good for the basics, but took me a little while to work out the details.
To summarise, I was trying to:
By default co-located assets are copied vertabim to the /public folder alongside your post in HTML form. This seemed messy because I didn't want to link directly to these and have images in multiple paths. The solution built on the shortcodes example in the documentation. As such, I defined a short-code in /templates/shortcodes/post_image.html as follows.
{% if path is containing(page.components | first) %}
{% set imgpath = path %}
{% else %}
{% set imgpath = page.components | concat(with = path) | join(sep = "/") %}
{% endif %}
{% set thumb = resize_image(path=imgpath, width=400, height=10, op="fit_width") %}
{% set image = resize_image(path=imgpath, width=5000, height=5000, op="fit") %}
<figure>
<a href="{{ image.url }}"><img src="{{ thumb.url }}" /></a>
{% if caption %}<figcaption>{{ caption }}</figcaption>{% endif %}
</figure>
The top conditional part will prepend the current post's folder name to the provided image path, if it is missing. It will only work for posts directly under /content and not if they are more deeply nested, which is fine for my purposes. It also possibly won't work with pages with custom slugs, but I'll cross that bridge if and when I get there.
The function then creates two images in /static/processed_images which will be named with a hash. thumb
refers to the small one with the defined width and will be inlined in the page with the img
tag. image
is "resized" in such a way that the largest dimension will be resized to 5000 pixels. If the image is smaller than that however, it will remain in its original form, with its aspect ratio maintained.
I use the above in my markdown files like this.
{{ resize_image(path="my-image.jpg", caption="Some caption text") }}
<!-- OR -->
{{ resize_image(path="/my-post/my-image.jpg", caption="Some caption text") }}
The final change was to add an expression in the main section of config.toml
to ignore images in the content directory to stop them being copied to public. This is how I enforced that all images must go through resize_image
in order to be used.
ignored_content = ["*.{gif,jpg,png}"]
Points for confusion:
resize_image
that is defined within Zola. The fact the short-code in the documentation is also called resize_image
is only because the file that contains it is called resize_image.html
.resize_image
requires that both width and height are defined, even if using an operation that only requires one (e.g. fit_width
requires only width). This is why height
above is defined as an arbitrary 10 above.Sometimes logging internal data is handy when you can't quite find the right docs. If you want to print e.g. the page
or section
variable within a Zola template, you can use something like this
<pre>{% if section %}{{ section | json_encode(pretty=true) | safe }}{% else %}no section :({% endif %}</pre>