Garbage Collector


The little space of a writer, tinkerer, and a coffee addict

Use Hugo Shortcodes to read pictures EXIF metadata

Use Hugo Shortcodes to read pictures EXIF metadata
An example of EXIF reading

If you’ve read my previous article about a Champagne cave visit, you may have noticed that all the photos are displaying their technical metadata : Camera and Lens model, aperture, speed, etc. Sorry to deceive you, but I haven’t written all these text manually, I’ve used one of the resourceful Hugo feature : the shortcodes.

What are shortcodes

Basically, Hugo shortcodes allow you to create custom tags that Hugo will read and interpret during rendering based on a template you’ve provided.

In my pictures case, this shortcode :

{{< exif src="photos/visite-cave-champagne/DSC_0019.jpg" alt="Test EXIF reading" >}}

Will render this :

Test EXIF reading
Test EXIF reading
f/1.8 - 35mm - 1/30 - ISO 6400
NIKON D5600 Nikon AF-S DX Nikkor 35mm f/1.8G
Seb - 2022-01-06 15:17:37 +0100 CET - Creative Commons Attribution-ShareAlike (CC BY-SA)

How to declare the shortcode

As the documentation says, the shortcodes can be declared at two places, in the following order :

  1. /layouts/shortcodes/<SHORTCODE>.html
  2. /themes/<THEME>/layouts/shortcodes/<SHORTCODE>.html

For my Exif reader, I’ve created the following file : /layouts/shortcodes/exif.html

Inside, I’ve put this code :

{{- $imageName := .Get "src" -}}
{{- $alt := .Get "alt" -}}
{{- $originalImage := resources.Get $imageName -}}

<figure>
<img src="{{ $originalImage.RelPermalink }}" alt="{{ $alt }}">

{{ with $originalImage.Exif }}
 <figcaption>{{ $alt }}
 <br />{{with   .Tags.Model }}{{ . }}   {{ end }}   {{with   .Tags.LensModel }}{{ . }}   {{ end }}   {{ with   .Tags.FNumber }}<i>f</i>{{ . }}   {{ end }}   {{ with   .Tags.FocalLength }}   {{ . }}mm{{ end }}   {{ with   .Tags.ExposureTime }}   {{ partial   "format-exposure-time.html"   . }}   {{ end }}   {{ with   .Tags.ISOSpeedRatings }} ISO {{ . }}{{ end }}
 <br />{{with   .Tags.Artist }}{{ . }} - {{ end }}   {{with   .Tags.DateTimeOriginal }}   {{ . }} - {{ end }}   {{ with   .Tags.Copyright}}{{ . }}{{ end }}
 </figcaption>

{{ end }}
</figure>

You may have noticed this part : {{ partial "format-exposure-time.html" . }}.

That’s a partial template I’ve found on Hugo’s Forum to format the exposure time from raw milliseconds to 1/xx seconds as displayed by cameras. You can create it in the following folders :

  1. /layouts/partials/format-exposure-time.html
  2. /themes/<THEME>/layouts/partials/format-exposure-time.html

With the following code (which I don’t really understand to be honest) :

{{ $n   :=   "- . ," }}   {{/* numFmt   options */}}
{{ $p   :=   9 }}   {{/* precision */}}
{{ $e   :=   "" }}
{{ if   eq (printf   "%T"   .) "float64" }}
 {{ $r   :=   div   1   . }}
 {{ if   math.ModBool (mul $r (pow   10 $p)) (mul (int $r) (pow   10 $p)) }}
 {{ $e   =   printf   "1/%d s" (int $r) }}
 {{ else }}
 {{ $e   =   printf   "%s s" (lang.NumFmt $p   . $n ) }}
 {{ end }}
{{ else }}
 {{ $e   =   printf   "%s s"   . }}
{{ end }}
{{ return $e }}

Variation : Display all EXIF tags

For debugging purpose, I had to create a version of this shortcode that returns all supported tags. It’s the same procedure as below, but I’ve named the HTML file exif-full.html.

So, if I call this :

{{< exif-full src="photos/visite-cave-champagne/DSC_0019.jpg" alt="Test EXIF reading" >}}

The output will display all EXIF metadata :

Date: 2022-01-06 15:18:33 +0100 CET Lat/Long: 0/0 Tags:* TAG: Artist: Seb
* TAG: CFAPattern:
* TAG: Copyright: Creative Commons Attribution-ShareAlike (CC BY-SA)
* TAG: CustomRendered: 0
* TAG: DateTime: 2022-01-11 22:27:26 +0100 CET
* TAG: DateTimeDigitized: 2022-01-06 15:18:33 +0100 CET
(...)

The shortcode code is the same, with an extra part taken from Hugo’s Image Processing documentation :

{{- $imageName   :=   .Get   "src" -}}
{{- $alt   :=   .Get   "alt" -}}
{{- $originalImage   :=   resources.Get $imageName -}}

<figure>
<img src="{{ $originalImage.RelPermalink }}" alt="{{ $alt }}">

{{ with $originalImage.Exif }}
 <figcaption>{{ $alt }}
 <br />{{with   .Tags.Model }}{{ . }}   {{ end }}   {{with   .Tags.LensModel }}{{ . }}   {{ end }}   {{ with   .Tags.FNumber }}<i>f</i>{{ . }}   {{ end }}   {{ with   .Tags.FocalLength }}   {{ . }}mm{{ end }}   {{ with   .Tags.ExposureTime }}   {{ partial   "format-exposure-time.html"   . }}   {{ end }}   {{ with   .Tags.ISOSpeedRatings }} ISO {{ . }}{{ end }}
 <br />{{with   .Tags.Artist }}{{ . }} - {{ end }}   {{with   .Tags.DateTimeOriginal }}   {{ . }} - {{ end }}   {{ with   .Tags.Copyright}}{{ . }}{{ end }}
 </figcaption>
{{ end }}
</figure>

{{ with $originalImage.Exif }}
Date: {{ .Date }}
Lat/Long: {{ .Lat}}/{{ .Long }}
Tags:
{{ range $k, $v   :=   .Tags }}
<li>TAG: {{ $k }}: {{ $v }}</li>
{{ end }}
{{ end }}

Lens Model issue with Darktable

During my shortcode testings, I’ve encountered an issue where the Lens Model field was not displayed. As the value was correctly displayed by Darktable (which I use to develop my pictures) and gThumb, I thought about a problem with in my code, or maybe Hugo. So I’ve opened a support request on Hugo’s forum.

Thanks to some nice analysis material provided by the members of this forum, and ensured the problem was my pictures and not Hugo, I’ve understood that Darktable didn’t properly filled the Lens Model field. Instead, it was the Lens ID and Hugo is not currently reading it.

After digging a little on Darktable issues, I’ve found this one and this one that helped me. In Darktable export module, open the module preferences.

darktable

First, ensure the “Exif Data” field is checked.

Then, add a redefined tag for Exif.Photo.LensModel with $(LENS) as a value.

darktable

Export your picture again and you should have the expected result.

I hope this shortcode will help you, don’t hesitate to send your suggestions about this code, as I’m not a developer, maybe it could be better 😀


📑 Table of Contents

📚 Read my latest book

Follow me on Mastodon

🏷️ All Tags 📄 All Posts 🗺 Sitemap RSS Feed