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 <<