Building Gallery Mental


My youngest daughter wanted new water colors and then proceeded by creating a bunch of art of various quality. The next logical step for her was to have an auction where she sold it all for hugs and potato crisps. Me being her biggest supporter through all this ended up with lots of her drawings and not enough wall space to hang it all. That's when I decided that I was going to stake out my own online gallery.

I already had my eyes on Neocities for a while and with it's generous 1 GB of easily available space it seemed the perfect fit for this project.

Getting org-anized

The plan was now to make orgmode do the heavy lifting, to make adding new artwork as painless as possible. What I came up with was an org file with a table detailing the artwork:

number artist title description year
1 D. Aughter Day at the beach Oils on paper. 2023

This table always get a new entry once I add a new sketch or painting. Then I add the corresponding artwork in a subdirectory artwork/00001/original.jpg. And finally I run the whole file with C-c C-v b.

Now all the little code blocks take over and produce an updated site by:

  • Iterating over the table looking for artwork where the thumb and large varieties of the images are not generated and creates them with imagemagicks convert program.
  • Creates two translated versions of the table by feeding it straight into the command line program trans from the debian package translate-shell.
  • Now iterating over all these tables (the original and the translated varieties). Create any missing meta.json file each artwork subdirectory. This file is suitable for javascript consumption via fetch api.
  • Finally iterate two more times to create a file detailing artworks per artist db/artists.json and one to select only the last artwork per artist db/highlights.json. These are used to enable navigation in the scope of an artist as well as decide what to show on the initial page respectively.

With all these files generated all that is needed is write a little javascript to generate something navigable. I opted for mithril here as I was pretty comfortable with it already. The good part is this code now doesn't need to change and all that is needed is adding to the main org table, move files in place and execute the buffer.

To not make the same calls over and over again I use :cache yes option liberally with my code blocks.

Pushing changes

I started out with the ruby neocities gem to push local changes but grew unhappy with it as the number of files grew and the sync slowed down. It also didn't feel emacsy enough.

So I wrote neocities.el as a replacement. I wanted to forego curl as a dependency as well but got stuck trying to make url-http.el handle a binary payload and finally gave up. After all curl is pretty great at its job.

With this library at my fingertips I then wrote a little wrapper for my eshell usage:

(defun npush (&rest artworks)
 (apply #'neocities-upload
  (append (list (file-expand-wildcards "db/*") "index.html"))
   (lambda (n)
    (file-expand-wildcards (format "artwork/%0.5d/*" n)))

So that after adding artwork 99 and 100 all I need to type in eshell is:

npush 99 100

The result

Having built this with multiple artists in mind I got some of my other daughters artwork and some of my own and put it all out there for your enjoyment.

Building this was really fun, and maintaining it is a breeze. Orgmode is great as a glue layer for the tools you already know. Thinking back I could perhaps have opted to generate all pages interlinked instead. But for me writing a little javascript was the easier solution as I felt I was more in control during the process.

Anyway this is what we ended up with: Gallery Mental.