release: v0.17.0 (#677)

See CHANGELOG.md, section [0.17.0] — 2026-09-23.
This commit is contained in:
Ralksta
2026-09-23 12:09:08 +02:00
committed by GitHub
parent a3a6319c29
commit 89a8fac564
78 changed files with 9485 additions and 2050 deletions

View File

@@ -95,7 +95,7 @@ Subpages, albums and sections are reordered in place; the order in the panel is
The **Journal Studio** — a split-screen editor with the blocks on the left and a live preview of the real page on the right, separated by a divider you can drag with mouse, keyboard or touch.
Blocks are added from a menu (heading, text, quote, photo, photo pair), reordered, and deleted; each carries a type chip so long entries stay scannable. Photos are inserted through the asset picker, which fills in the Immich asset UUID for you. The frontmatter — cover image, title, subtitle, author, date, draft flag, password — is edited as form fields.
Blocks are added from a menu (heading, text, quote, facts, photo, photo pair, photo grid, album, map), reordered, and deleted; each carries a type chip so long entries stay scannable. Photos are inserted through the asset picker, which fills in the Immich asset UUID for you. A new entry can start from a template — Wedding, Hiking, Travel, Birthday, Portrait Session, Behind the Scenes, Pets, New Series — chosen in the create dialog; the blocks arrive with placeholder text and empty photo tiles to fill. The frontmatter — cover image, title, subtitle, author, date, draft flag, password — is edited as form fields.
Saving writes plain Markdown to `content/journal/<slug>.md`, which can equally be edited by hand.

View File

@@ -192,3 +192,11 @@ photos.example.com {
> limits on the password endpoints. See
> [Trusted Proxies](gallery-config.md#trusted-proxies) for the setting and a
> matching nginx config.
Login cookies (admin session and gallery passwords) are marked `Secure` when the
request arrived over HTTPS, which the app learns from `X-Forwarded-Proto`. Caddy
and Traefik send it on their own; nginx needs the
`proxy_set_header X-Forwarded-Proto $scheme;` line from the config linked above.
Opening the app over plain HTTP, e.g. `http://server:7211` on a home network,
works too: the cookies are then set without `Secure`, since a browser would
discard them otherwise.

View File

@@ -203,6 +203,7 @@ albums:
password: 'secure-password'
heroImage: 'asset-uuid'
sort: filename
download: true
```
| Key | Description |
@@ -215,6 +216,7 @@ albums:
| `assetOrder` | Pinned asset UUIDs for `sort: manual` |
| `grid` | **Experimental.** Grid override for this album only |
| `coverPosition` | **Experimental.** Focal point for the cover crop |
| `download` | Offer originals for download — see [Originals download](#originals-download) |
### Per-album grid (experimental)
@@ -244,6 +246,29 @@ albums:
Useful when the automatic centre crop cuts off a horizon or a face.
### Originals download
Opt in per album with `download: true`. Off everywhere by default, and opt-in
on purpose: a public portfolio should not start handing out full-resolution
originals because one client gallery needed to.
```yaml
albums:
- 'album-uuid':
download: true
```
Once enabled, visitors get a **Download album** link in the album header (every
original as a ZIP), and — where [client proofing](#client-proofing) is on — a
**Download selected (.zip)** action in the export dialog that zips just the
favourited photos.
The download route re-checks the allowlist, the `download` flag, every password
gate on a route to the album, and that each asset really belongs to that album,
so an edited URL cannot reach anything else. The ZIP keeps the original
filenames (deduplicated on collision) and is streamed, so album size does not
drive memory use.
## Password Protection
A password can be set on the whole site, on a subpage, on a single album, and on
@@ -567,6 +592,10 @@ The selection is encoded into the URL as a compact bitmask and mirrored into
`localStorage`, so **nothing is stored server-side** and a set of picks can be
shared, bookmarked, or sent back as a plain link.
When an album also opts into [originals download](#originals-download), the
export dialog gains a **Download selected (.zip)** action, and the album header
a **Download album** link.
Configured in `settings.yaml`:
```yaml

View File

@@ -137,9 +137,101 @@ real aspect ratios rather than forced equal:
![asset-uuid-left, asset-uuid-right](Optional caption)
```
Three or more render as a grid — rows of up to three, each row justified like
a pair (one shared height, widths from the real ratios, nothing cropped),
stacked on phones:
```markdown
![uuid-1, uuid-2, uuid-3, uuid-4](Optional caption)
```
Photos in an entry open in the same lightbox as the rest of the site, with
keyboard and swipe navigation.
### Facts
A `::facts` line followed by `Label: Value` lines in the same paragraph
renders as a compact definition list — distance and elevation for a hike,
date and venue for a wedding:
```markdown
::facts
Distance: 21 km
Elevation: 1,240 m
Start: 08:30
```
The first colon splits label from value, so a time keeps its `:`. Values take
the same inline markdown as text. Lines without a colon are ignored.
### Map
A `::map` line, with an optional caption after it, starts a map. The lines
after it say what is on it — numbered pins in the order written, joined by
a line:
```markdown
::map Busan → Seoul
Busan harbour: 35.098, 129.036
photo: 8f1c0e2a-…
photos: all
Seoul: 37.566, 126.978
line: off
```
| Line | Puts on the map |
| ----------------- | ------------------------------------------------------------------------------------------------- |
| `Label: lat, lng` | A point with a label, exactly where you typed it. |
| `lat, lng` | A point without a label. |
| `photo: <uuid>` | One of the entry's photos, placed by its GPS. Several ids may follow, comma-separated. |
| `photos: all` | Every geotagged photo in the entry, in the order they appear — skipping ids already listed above. |
| `line: off` | No connecting line. The default draws one when there are two or more pins. |
A map with no lines renders nothing. `photo`, `photos` and `line` are reserved
as labels; a coordinate pair that does not parse, or lies outside ±90 / ±180,
is ignored (the Studio warns before you save).
Typed points are published as typed — they are your content. Photo pins are
derived from EXIF, so they follow each album's `location:` setting the way
the map page does: `hidden` and `country` add no pin, `city` snaps to the
same 5 km grid, and where an album allows exact positions a journal pin is
still snapped to a 1 km grid — the map page shows the mean of an album's
photos in a city, never a single photo, and a story map should not be the
first surface that places one photo at its doorstep. Photo pins are computed
when the page renders; the Studio's preview shows typed points right away and
leaves photo pins for the live page.
The block renders only while `map: true` is set in `settings.yaml`, typed
points included — that setting also means "no map tiles from CartoDB for my
visitors".
### Album
"The first twelve of the Seoul album", without picking each photo:
```markdown
::album 371336b4-eb59-409c-b24e-a613f81ede5a
count: 12
skip: 0
layout: grid
caption: Twelve from Seoul
```
| Line | Meaning |
| -------------- | ------------------------------------------------------------------------------- |
| `::album <id>` | The Immich album id — the Studio's album picker fills it in. |
| `count: N` | How many photos. Default: the whole album. |
| `skip: N` | Offset, so two blocks can split one album. Default 0. |
| `layout: …` | `grid` (rows of three, default), `pairs` (rows of two) or `wide` (one per row). |
| `caption: …` | One caption under the set. |
The block is expanded into ordinary photo blocks when the page renders, so
the lightbox and everything else work as for hand-picked photos. Photos come
in the album's order; if the gallery pins a manual `assetOrder` for that
album, those come first. The album need not be published in `gallery.yaml` —
an entry may already show any single photo by id, and the author's pick is
the gate for a whole album just the same.
<p align="center">
<img src="screenshots/journal-entry.png" width="98%" alt="A rendered journal entry with heading, body text, a fullbleed photo and a quote" />
</p>
@@ -147,7 +239,10 @@ keyboard and swipe navigation.
> [!TIP]
> Writing asset UUIDs by hand is tedious. In the [Journal Studio](#journal-studio),
> **Add Block → Photo** opens the asset picker and fills the UUID in for you.
> **Add Block → Photo**, **2-Photo Pair** and **Photo Grid** open the asset
> picker and fill the UUIDs in for you; **Facts** and **Map** have their own
> small forms. New entries can also start from a template — Wedding, Hiking,
> Travel and the others — instead of an empty editor.
## Drafts