A Static Art Gallery with Hugo
This is not the first time, and won’t be the last time I post about JS-free, bloat-free web. In this post I’d like to share how I build a art collection site for my gf.
the site: https://gi.nseng.art
I’m not a web designer and I’m not a frontend engineer. Yet I’ve wrote a lot about static blogging. I do this to make a point for the bloat-free web.
# A simple grid layout
I adopted the example from here. Later I’ll show how to plug this into the hugo system.
# Content Organization
Now, this is the tricky part. Simply put, hugo is opt for text, not blob objects like images or videos.
- For a formal presentation, artworks needs to documented with their meta data e.g. time of making, author, material, techniques, etc..
- The need for meta data management is similar to the need for bibliography management in acdemia.
- It’s far more complicated than the usual approach : putting a piece of artwork
in a post with markdown image via
[alt text]("url" "desc")
. For example, each media could appear in different places, with a consistent meta data display. Copying around the hyperlinks is a dead end.
are you talking about wordpress? - Yes I am. Wordpress makes it pretty easy to manage media files and I find it the optimal CMS for artists. But I won’t use it, again, to make a point.
Now, what about content organization?
A typical hugo content structure would look like this:
content
|- category1
|- post1.md
|- post2.md
|- post3
|- _index.md
|- sub1.md
|- sub2.md
|- img1.jpg
|- ...
...
The problem here is obvious: the assets like media are bounded to posts and there is not a central place for meta data management.
So instead, I do this:
content
|- category1
| |- post1.md
| |- post2.md
| ...
|- static
| |- media files
| |- ...
|
|- data
|- meta.json
the meta.json
would be our central place for metadata management. It will look
like this:
[
{
"id" : "aq2",
"name" : "",
"desc" : "A question 2, 2024, Oil on canvas, 70x55cm",
"image_url" : "/A_Question_2/A_Question_2.jpg",
"series" : "A Question 2",
"series_url" : "/arts/a_question_2/",
"tags" : ["painting"]
},
{
"id" : "aq1"
"name" : "",
"desc" : "A question 1, 2024, Oil on canvas, 160x114cm",
"image_url" : "/A_Question_1/A_Question_1.jpg",
"series" : "A Question 1",
"series_url" : "/arts/a_question_1/",
"tags" : ["painting"]
},
...
]
- each media may belong to a serie
- each piece of a serie may have its own name
- each media is identified by its file path (its relative url, same as its
relative path to
static/
) - each media is also identified by the id: this is handy to include media via shortcodes
- each media may be linked to a post (series_url)
- each media may have one or multiple tags (as in “categories”).
# hugo layouts and partials
Now let’s plug the metadata into hugo partials:
a gallery of ALL artworks:
layout/gallery/list.html
(only showing relevant parts)
|
|
layout/partials/
<div class="gallery-grid" style="max-width: 80%; margin:auto">
{{ range . }}
<figure class="gallery-frame">
{{with .video_url}}
<video class="gallery-img" playsinline="" controls="">
<source src="{{.}}" type="video/mp4">
</video>
{{else}}
<a href="{{.image_url}}" target="_blank">
<img class="gallery-img"
src="{{.image_url}}.tn.jpg"
alt="{{.desc}}"
title="{{.desc}}">
</a>
{{end}}
<figcaption> <a href ="{{.series_url}}">{{.series}}</a>
// <i>{{.desc}}</i>
<div class="tags">
{{range .tags}} <a href="/tags/{{.}}"> #{{.}} </a>
{{end}}
</div>
</figcaption>
</figure>
{{end}}
</div> <!--gallery-grid-->
Sub-gallery : filter the json data:
e.g. layouts/paintint/list.html
<center><h1>PAINTINGS</h1></center>
{{ $gl := where site.Data.gl_all "tags" "intersect" (slice "painting")}}
{{ partial "gallery_grid.html" $gl}}
# Thumbnails
It’s obvious that we shouldn’t use hi-res pictures for a gallery grid view. I
have a simple script to generate thumbnails. The thumbnails are store to the
same path as the original, with a suffix .tn.jpg
. This makes it easier for
templating.
#!/usr/bin/bash
DIR=$1
target_dirs=( "$@" )
echo "making thumbnails : NO RECURSION!"
gen_thumb_for_dir() {
local dir=$1
if [ ! -d "$dir" ]; then
echo "[ERROR] $DIR does not exist."
return
fi
rm $dir/*.tn.jpg
targets=($(find $dir \( -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" \)))
for i in "${targets[@]}"
do
echo "PROCESSING $i to $i.tn.jpg"
convert $i -resize 1280x1280 -strip $i.tn.jpg
done
}
for i in "${target_dirs[@]}"
do
gen_thumb_for_dir $i
done
# Add media to post via shortcode and ID
layouts/shortocodes/media.html
{{ $gl := site.Data.gl_all }}
{{ $id := .Get "id" }}
{{ range $gl }}
{{ if eq .id $id }}
{{ $t := ""}}
{{ if .name}}
{{$t = printf "%s - %s" .name .desc}}
{{else}}
{{$t = .desc}}
{{ end }}
<p class="md__image">
<img src="{{.image_url}}" alt="{{$t}}" title="{{$t}}" />
<div class="img-cap">{{$t}}</div>
</p>
{{ else }}
{{ end }}
{{ end}}
to use in a post:
{{<media id="aq2">}}
[+] click to leave a comment [+]
>> SEND COMMENT <<