The chosen view is published at /, the other under /timeline/ or /grid/. Page paths, pager links and the cross-links between the views are derived from the setting. The directory named after the default view is removed on build, since it can only be a leftover from before a switch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
143 lines
5.2 KiB
Markdown
143 lines
5.2 KiB
Markdown
# 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
|
||
|
||
```toml
|
||
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
|
||
|
||
```nix
|
||
inputs = {
|
||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||
photogallery.url = "github:youruser/photogallery";
|
||
};
|
||
```
|
||
|
||
### 2. Import the module
|
||
|
||
```nix
|
||
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
||
modules = [
|
||
inputs.photogallery.nixosModules.default
|
||
./configuration.nix
|
||
];
|
||
};
|
||
```
|
||
|
||
### 3. Configure
|
||
|
||
```nix
|
||
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:
|
||
|
||
```bash
|
||
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 |
|
||
| `pageSize` | `60` | Photos per page on the timeline and grid views |
|
||
| `defaultView` | `timeline` | View at the site root, `timeline` or `grid`; the other is served under `/timeline/` or `/grid/` |
|
||
| `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`.
|
||
|
||
```bash
|
||
# 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
|
||
|
||
```bash
|
||
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.
|