Deth

Fitness and everything else

My Zola Figure Shortcode

One thing that makes static site generators nice is how they can automate so many repetitive things. Sure, WordPress and friends did that, but there was a lot more to maintain. Using SSGs is more like the old days when I wrote all of my HTML manually. I don’t miss that.

The biggest reason I switched over from Hugo to Zola was the simple fact that I understood Zola’s templating language a lot more readily. The syntax is just easier on my brain.

My first bigger project when I was in the process of moving over to Zola was to create a figure shortcode. I wanted it to automatically generate images in various sizes, like it did in Hugo. I wanted it to generate an image srcset from them and use the appropriate information, so browsers could figure out the best-sized image to download.

1{%- set path = src -%}
2{%- set meta = get_image_metadata(path=path) -%}
3{%- set width = meta.width -%}
4{%- set srcset_list = [] -%}
5{%- set sizes_list = [480,800,1200,1600,2000,2500] -%}
6{%- for sizes in config.extra.sizes -%}
7{% set_global DefaultResizedMetaHeight = "" %}
8{% set_global DefaultResizedMetaWidth = "" %}
9
10{% if width >= sizes.size -%}
11{%- set_global resized = resize_image(path=path, width=sizes.size, op="fit_width", quality=95) -%}
12{% set_global TheUrl = resized.url %}
13{%- set element = TheUrl ~ " " ~ sizes.size ~ "w"-%}
14{%- set_global srcset_list = srcset_list | concat(with=[element]) -%}
15{%- set The_Size= sizes.size / 2 %}
16{%- set size = "(max-width: " ~ The_Size ~ "px) " ~ sizes.size ~ "px" -%}
17{%- set_global sizes_list = sizes_list | concat(with=[size]) -%}
18{%- set_global sizes_list = sizes_list | concat(with=", 100vw") -%}
19{% if sizes.size == 800 %}
20{%- set_global DefaultResizedURL = TheUrl -%}
21{% if DefaultResizedMeta %}
22 {%- set DefaultResizedMeta = get_image_metadata(path=resized.static_path, allow_missing=true) -%}
23{% set_global DefaultResizedMetaHeight = DefaultResizedMeta.height %}
24{% set_global DefaultResizedMetaWidth = DefaultResizedMeta.width %}{% endif %}
25 {% endif %}
26{%- endif -%}
27{%- endfor -%}
28{%- set DefaultRisized = resize_image(path=path, width=800, op="fit_width", quality=95) -%}
29<figure class="picture">
30 <figcaption>
31 {%- if title -%}
32 <h4>{{- title | safe -}}</h4>
33 {%- endif %}
34
35 </figcaption>
36<a href="{{- get_url(path=path) | safe -}} " title = "View Full sized Picture">
37 <picture> <source {%- if meta.format == "jpg" %}
38 type="image/jpeg" {% endif %}
39 srcset="{{- srcset_list | join(sep=",
40 ") | safe }}"{#sizes="{{ sizes_list | join(sep=",
41 ") | safe -}}"#}>
42
43 <img alt="{{- alt | safe -}}" {% if DefaultResizedURL %} src=" {{- DefaultResizedURL | safe -}}" {% else %} src="{{ get_url(path=path) | safe }} "{% endif %} {% if DefaultResizedMetaWidth %} width= "{{- DefaultResizedMetaWidth -}}" {%- endif %} {%- if DefaultResizedMetaHeight -%} height= "{{- DefaultResizedMetaHeight -}}" {%- endif %}>
44</picture> </a>
45
46 </figure>

One glitch I came across is that Zola would error on not finding a file if it was resizing a bunch at once. That takes some time, but Zola didn’t wait for it to be done to continue on with the template. I solved that with this little hack of surrounding the code with an if to check whether it exists. No big deal. Zola is less popular, so it has fewer eyes on it, and it’s also a less mature project.

{% if DefaultResizedMeta %}
...
{% endif %}

Feel free to use this if it’s helpful to you.

The shortcode is just called like this:

{{ fig(alt="This picture shows the full moon with brightly lit clouds around it.", src="/images/FullMoonClouds.jpg", title= "Full Moon Clouds") }}

It would certainly be nice if they eventually added something like Hugo’s render hooks for the markdown code for images. Then I could convert this to use that hook and use plain markdown. That would make my markdown files much more portable if I should decide to change static site generators in the future.