puttaalu 856439f3fd Paginate the gallery grid with 60 photos per page
Emit /page/N/ pages alongside index.html and render a pager at the
bottom of each page. Ships as a plain link that navigates without JS,
and an IntersectionObserver enhancement that fetches the next page and
appends tiles for an infinite-scroll feel.
2026-07-02 22:20:28 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:57:49 +02:00
2026-07-02 00:53:17 +02:00
2026-07-02 00:53:17 +02:00

photogallery

A minimal static photo gallery with an Atom feed and an upload API.

How it works

  1. Drop photo.jpg + photo.toml into the content directory (or upload via the web UI at /upload).
  2. The binary watches the directory and rebuilds the static site on any change.
  3. nginx serves public/ and proxies /upload to the local API, secured with htpasswd.

For each photo the generator produces a 600×600 square thumbnail for the grid and an aspect-preserved medium JPEG (longest side 1600) for the detail page. The original file stays reachable from a download link on the detail page. Regeneration is skipped when the destination is at least as new as the source, so editing one sidecar doesn't reprocess every photo.

The upload page reads DateTimeOriginal from a JPEG's EXIF (or falls back to the file's modification time) and prefills the date field, which stays editable before submitting.

Sidecar format

caption = "Tempelhof at sunrise"
date    = "2026-06-14"

If no .toml is present the filename is used as the caption and today's date as the date.


Using as a NixOS flake module

1. Add to your flake inputs

inputs = {
  nixpkgs.url        = "github:NixOS/nixpkgs/nixos-unstable";
  photogallery.url   = "github:youruser/photogallery";
};

2. Import the module

nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
  modules = [
    inputs.photogallery.nixosModules.default
    ./configuration.nix
  ];
};

3. Configure

services.photogallery = {
  enable   = true;
  baseURL  = "https://photos.yourdomain.tld";

  # Optional: identity shown on the header and copyright footer
  author  = "Ada Lovelace";
  handle  = "@ada@example.com";
  bio     = "Photos from the field.";
  bioAlt  = "";  # optional secondary line in the alt-script font

  # Optional: swap fonts
  fontsURL    = "https://fonts.googleapis.com/css2?family=EB+Garamond:wght@400;600;700&family=Manjari:wght@400;700&display=swap";
  serifFamily = "EB Garamond";
  mlFamily    = "Manjari";

  # Optional: built-in nginx vhost
  nginx = {
    enable       = true;
    domain       = "photos.yourdomain.tld";
    htpasswdFile = "/etc/nginx/.htpasswd-gallery";
  };
};

Create the htpasswd file:

nix-shell -p apacheHttpd --run \
  "htpasswd -c /etc/nginx/.htpasswd-gallery youruser"

Available options

Option Default Description
enable false Enable the service
baseURL Public URL, no trailing slash
contentDir /var/lib/photogallery/content Images and .toml sidecars
outputDir /var/lib/photogallery/public Generated site output
port 8080 Upload API port (localhost only)
author Ashik Salahudeen Name shown on the header, photo pages and copyright footer
handle @puttaalu@inflo.ws Handle line under the author name
bio Personal photo journal. Primary bio line
bioAlt Malayalam default Secondary bio line in the alt-script font ("" to omit)
fontsURL Crimson Pro + Manjari Stylesheet URL loading both web fonts
serifFamily Crimson Pro CSS font-family for the primary serif
mlFamily Manjari CSS font-family for the alt-script bio
nginx.enable false Configure an nginx vhost
nginx.domain Domain for the vhost
nginx.htpasswdFile htpasswd file for /upload
nginx.enableACME true Enable Let's Encrypt

Bootstrap (first build)

buildGoModule needs a go.sum and the correct vendorHash.

# 1. Generate go.sum
go mod tidy

# 2. Commit go.sum
git add go.sum && git commit -m "add go.sum"

# 3. Get the vendorHash — this will fail and print the correct hash
nix build
# error: hash mismatch ... got: sha256-XXXXX...

# 4. Paste the hash into flake.nix, then build again
nix build

Uploading via curl

curl -u user:password \
     -F "image=@photo.jpg" \
     -F "caption=Tempelhof at sunrise" \
     -F "date=2026-06-14" \
     https://photos.yourdomain.tld/upload

Or open https://photos.yourdomain.tld/upload in a browser.

S
Description
No description provided
Readme MIT 134 KiB
Languages
Go 40.1%
HTML 30.8%
Nix 15.5%
CSS 13.6%