Five weeks of undocumented evolution left the docs describing a site that
partly no longer exists, with nothing marking which documents were historical.
The code is treated as the source of truth throughout; every claim below was
verified against code, config or the Makefile rather than inferred.
Two mechanisms, following patterns the repo already used:
- docs/reference/superseded-decisions.md (new) — one authoritative table of all
14 reversals: what was planned, where, what is true now, when, and why. Plus
a short list of decisions that were NOT reversed, since their planning docs
are old enough to look suspect.
- Inline "> **Superseded ...**" notes at each stale claim, so a claim can never
be read un-corrected. This mirrors the existing "> History:" notes in
architecture.md and "> **Changed 2026-07:**" in trip-switching.md.
Scope split by tense: present-tense docs (CLAUDE.md, reference/, guides/,
README.md, CONCEPTS.md) are corrected; past-tense records (plans/, specs/,
milestones/, summary.md, pm-analysis.md) are annotated only, never rewritten —
their staleness is what makes them records.
Present-tense corrections:
- CLAUDE.md asserted css-compiled/ is generated from css/style.css and
css/tokens.css. That source relationship does not exist: css/ is hand-authored
and served directly via assets.addCss in partials/base.html.twig, while
css-compiled/ is esbuild output from the CSS imports inside js/src/*.js.
Highest-severity finding — an always-loaded file inviting a hand-edit of a
generated bundle.
- README.md documented every remote-* target without the -test/-prod suffix
guard-env requires, so its entire server runbook was unrunnable, and listed
7 of ~20 targets while CLAUDE.md designates it authoritative for the full
list. Rewritten with all targets, grouped, and the suffix rule stated.
- README.md told readers to "git clone" into user/, which is a submodule.
- architecture.md: nav is Home + Trips + (authenticated) New Post, not
"Home + Past Trips only"; template tree omitted trips.html.twig,
post-form.html.twig and forms/, and placed base.html.twig at templates/ root
rather than in partials/; entry-actions has three API routes, not just delete;
added the undocumented css-compiled/maplibre-gl.css output and a section on
the /post pin editor as the one sanctioned non-entry-map map.
- design-system.md: documented 13 colour tokens against 19 in tokens.css
(missing --color-error, --color-draft-accent and four glass overlays); claimed
"all 3 map templates"; and described --color-canvas as "white".
- design-system-light.md documented a light palette in present tense. No light
mode exists — tokens.css has a single :root block, no prefers-color-scheme or
data-theme switch, and no light hex appears in css/. Banner added.
- posting.md said photos were optional; they are required, 1-6. It documented
hero_image, which was removed for entries (stories keep it). It had no mention
of the frontend edit flow or photo editor, both shipped 2026-07-08. Photo
files are photo-01..NN, zero-padded.
- working/README.md advertised summary.md as the project's "current state" while
summary.md describes Leaflet, /tracker, /map and /stats. Most misleading line
in the tree.
- CLAUDE.md: recorded js/src/location-map.js as the one sanctioned exception to
the single-map-path rule, and documented that make start/setup fail on a clean
checkout because docker-compose.yml still builds a travel-memories service
whose source moved out in a80b0a9.
Also: 2026-07-23-post-form-location-override.md read "Not started" while merged
in user/ as dd19995; status corrected.
Findings that are not documentation problems — the compose breakage, a
repeatable drift check, the unused shortcode-gallery-plusplus, and demo fixtures
for retired views — are collected in
docs/working/2026-07-25-doc-drift-recommendations.md and deliberately not acted
on. Design and verification method: docs/working/specs/2026-07-25-docs-reconciliation-design.md
The submodule gitlink is deliberately not bumped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
171 lines
8.1 KiB
Markdown
171 lines
8.1 KiB
Markdown
# Posting a Journal Entry
|
||
|
||
Two ways to post: the **mobile form** at `/post` (quick, phone-friendly) or the **Admin panel** at `/admin` (scheduling, bulk edits). The `/post` form also **edits** existing entries — see below.
|
||
|
||
---
|
||
|
||
## Quick start — mobile form
|
||
|
||
1. Open `/post` on your phone (login required)
|
||
2. **Attach 1–6 photos** — photos come first because they anchor what you write. **At least one is required**; the form collapses them into a summary bar once uploaded
|
||
3. Fill in **Title** and **Content** (required)
|
||
4. Tap **Get Location** → fills Lat/Lng, then reverse-geocodes City + Country for you
|
||
5. Tap **Get Weather** → fills weather fields using those coordinates
|
||
6. Optional: open **More location details** to search for a place by name, or drag the pin on the map to place it exactly
|
||
7. Optional: open **More options** for transport mode, publish state, connector and highlight toggles
|
||
8. Tap **Submit** → entry appears in the feed immediately
|
||
|
||
> **Photos are mandatory (1–6).** This changed during the 2026-07 post-form work — an entry with no
|
||
> photo will not submit. The first photo in the grid is the hero; reorder by dragging to change it.
|
||
> See [`../reference/superseded-decisions.md`](../reference/superseded-decisions.md) → R7, R8.
|
||
|
||
---
|
||
|
||
## Form fields reference
|
||
|
||
| Field | Required | Notes |
|
||
|---|---|---|
|
||
| Photos | ✅ | **1–6 per entry.** HEIC is converted to JPEG in the browser. First photo = hero; drag to reorder |
|
||
| Title | ✅ | Entry headline |
|
||
| Content | ✅ | Markdown body |
|
||
| Date | ✅ | Defaults to now — adjust if posting later |
|
||
| Lat / Lng | — | Filled by Get Location, by place search, or by dragging the map pin |
|
||
| City | — | Auto-filled by reverse geocoding after Get Location; shown as `📍 Kyoto, Japan` on feed cards |
|
||
| Country | — | Combined with City in the location badge |
|
||
| Weather | — | Filled by Get Weather (Open-Meteo, free, no key) |
|
||
| How I got here | — | `transport_mode`: walking · bicycle · bus · train · car · plane |
|
||
| Published | — | Advanced. Default **Yes**. Set No to keep a draft, or to unpublish on edit |
|
||
| Force connector line | — | Advanced. Default No. Forces a map connector to this entry even when suppressed |
|
||
| Featured highlight | — | Advanced. Default No. Opts the entry into the home highlights grid |
|
||
|
||
The advanced three sit behind **More options**. There is **no `hero_image` field** — see the note above.
|
||
|
||
**Weather descriptions** (must be one of these if entered manually):
|
||
`Sunny` · `Partly cloudy` · `Cloudy` · `Foggy` · `Drizzle` · `Rain` · `Snow` · `Thunderstorm`
|
||
|
||
---
|
||
|
||
## How it works (for debugging)
|
||
|
||
```
|
||
Browser → /post (post-form.md)
|
||
└─ Grav Form plugin validates fields
|
||
└─ cache-on-save injects parent from site.active_trip
|
||
└─ and sets overwrite_mode: edit when edit_path is filled, else false
|
||
└─ add-page-by-form plugin (patched — see deploy/patches/)
|
||
├─ writes user/pages/01.trips/<active_trip>/01.dailies/<slug>.entry/entry.md
|
||
└─ moves uploaded photos into the page folder
|
||
└─ cache-on-save plugin
|
||
└─ calls $grav['cache']->deleteAll() → entry visible immediately
|
||
└─ form shows success message
|
||
```
|
||
|
||
**Slug format:** `<YYYY-MM-DD-HHmm>-<slugified-title>.entry`
|
||
Example: `2026-07-20-0930-first-day-in-kyoto.entry`
|
||
|
||
**Entry folder structure:**
|
||
```
|
||
user/pages/01.trips/denmark-2026/01.dailies/
|
||
└─ 2026-07-20-0930-first-day-in-kyoto.entry/
|
||
├─ entry.md ← frontmatter + markdown body
|
||
├─ photo-01.jpg ← first in order, so this is the hero
|
||
└─ photo-02.jpg ← additional gallery image
|
||
```
|
||
|
||
Photos are stored as `photo-01…NN` in display order — the numbering *is* the order, so reordering in
|
||
the form renames files on disk, and `photo-01` is always the hero. Names are **zero-padded** so
|
||
lexical sort matches numeric order (otherwise `photo-1, photo-10, photo-2…`); the pad width grows for
|
||
100+ photos. `PhotoRenumberer` in `cache-on-save` is the single source of truth for this invariant and
|
||
is shared with `entry-actions`.
|
||
|
||
---
|
||
|
||
## Admin panel — drafts and scheduling
|
||
|
||
Use the Admin panel at `/admin` for **scheduling** (`publish_date`) and bulk or structural edits. For ordinary edits — text, photos, location, publish state — the `/post` form is quicker; see [Editing an entry](#editing-an-entry).
|
||
|
||
1. Log in at `/admin`
|
||
2. **Pages → Add Page**
|
||
3. Set **Parent Page** to `/trips/<active_trip>/dailies` and **Template** to `entry`
|
||
4. Fill in the **Entry** tab (city, country, lat/lng, weather)
|
||
5. Write content in the **Content** tab
|
||
6. Upload photos in the **Media** tab
|
||
7. **Drafts:** set `published: false` — won't appear until you flip it to `true`
|
||
8. **Scheduling:** set `publish_date` in **Options → Scheduling**
|
||
9. Save
|
||
|
||
The Admin form fields are defined by `user/themes/intotheeast/blueprints/entry.yaml`.
|
||
|
||
---
|
||
|
||
## Frontmatter reference
|
||
|
||
Every entry supports these frontmatter fields:
|
||
|
||
| Field | Type | Notes |
|
||
|---|---|---|
|
||
| `title` | string | Required |
|
||
| `date` | datetime | Format: `Y-m-d H:i` (e.g. `2026-06-17 10:00`) |
|
||
| `template` | string | Always `entry` |
|
||
| `published` | bool | `true` to show in feed |
|
||
| `lat` | string | Decimal degrees (e.g. `52.3676`) |
|
||
| `lng` | string | Decimal degrees (e.g. `4.9041`) |
|
||
| `location_city` | string | e.g. `Kyoto` |
|
||
| `location_country` | string | e.g. `Japan` |
|
||
| `weather_desc` | string | One of the allowed values above |
|
||
| `weather_temp_c` | number | Celsius, displayed rounded |
|
||
| `transport_mode` | string | `walking` · `bicycle` · `bus` · `train` · `car` · `plane` |
|
||
| `force_connect` | bool | Force a map connector line to this entry even where it would be suppressed |
|
||
| `featured` | bool | Opt into the home page highlights grid |
|
||
|
||
> **No `hero_image` on journal entries.** The hero is whichever photo sorts first
|
||
> (`entry-journal.html.twig` uses `entry.media.images|first`), which the owner controls by
|
||
> reordering photos. **Stories still use `hero_image`** — they are not posted through this form.
|
||
> See [`../reference/superseded-decisions.md`](../reference/superseded-decisions.md) → R7.
|
||
|
||
---
|
||
|
||
## Editing an entry
|
||
|
||
The `/post` form doubles as the editor — you do not need Admin for ordinary edits.
|
||
|
||
1. Open the entry (or find it in the feed) while logged in
|
||
2. Use the entry's **Edit** action → `/post` opens pre-filled, with the hidden `edit_path` set to that
|
||
entry's path
|
||
3. Existing photos load into the grid. You can **add**, **remove**, and **drag to reorder** them
|
||
4. Submit → `cache-on-save` sets `overwrite_mode: edit`, so the entry is rewritten **in place**
|
||
rather than creating a new dated folder
|
||
|
||
Photo files on disk are renumbered to `photo-1…N` to match the displayed order, so the first photo is
|
||
always the hero. Reordering is a real file rename, handled server-side by `PhotoRenumberer` in the
|
||
`entry-actions` plugin via `POST /api/v1/entry/{slug}/photos/order`.
|
||
|
||
To **unpublish** an entry, edit it and set **Published** to No under *More options*.
|
||
|
||
Deleting an entry is also an entry action (`DELETE /api/v1/entry/{slug}`), owner-only and scoped to
|
||
the active trip.
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
**Entry doesn't appear in feed after submit**
|
||
→ Check `active_trip` in `user/config/site.yaml` — the write target is derived from it at submit time, so a wrong value sends entries to the wrong trip's dailies. See [trip switching guide](trip-switching.md).
|
||
|
||
**Get Weather button shows an error**
|
||
→ Fill in Lat/Lng first (tap Get Location or enter manually). Open-Meteo requires coordinates.
|
||
|
||
**Photos not showing in gallery**
|
||
→ Verify files were uploaded (check the entry folder in Admin → Media). Only jpg, jpeg, png, webp, gif are rendered.
|
||
|
||
**Submit button does nothing**
|
||
→ Check you have at least one photo attached, and that every upload has finished. The form blocks
|
||
submit while an upload is still in flight, and requires 1–6 photos.
|
||
|
||
**500 error after posting**
|
||
→ Run `make fix-perms` to restore container file ownership.
|
||
|
||
**Edits create a new entry instead of updating**
|
||
→ The hidden `edit_path` was empty, so `overwrite_mode` fell back to `false`. Re-enter via the entry's
|
||
Edit action rather than opening `/post` directly.
|