travelling was only set to false in user/env/localhost/config/site.yaml,
which Grav reads only when the request hostname is literally "localhost",
and which is git-ignored. So the home page still rendered Denmark 2026 as
an active trip on every other hostname, and the setting could never reach
production. Set it in the tracked config instead.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
system.pages.expires was 604800 (Grav default), so browsers cached feed HTML and
entry media for a week with no revalidation — deleted entries lingered as ghost
cards (images 404), and edited/new photos didn't appear until a hard refresh. Set
expires: 0 → Cache-Control: no-cache, must-revalidate. With etag already on, an
unchanged page returns a cheap 304; changed content shows immediately. Also fixes
reorder staleness (photo-N.jpg is reused across reorders at the same URL). The
server-side page cache (cache.enabled) is untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds 83.135.64.30 to popularity.exclude_ips so local/manual testing
against prod doesn't inflate real-visitor page-view stats. IP is
dynamic — a stopgap; smoke tests should target the test instance.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
- gitignore config/security-private.php (CSRF/nonce + rate-limit signing
salt); it is a per-install secret Grav auto-generates and its own header
says not to commit. Each environment now keeps its own uncommitted salt.
- drop the runtime-generated popularity.salt from api.yaml; Grav re-derives
it per install.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
versions.yaml records each install's Grav schema-migration state and
differs per environment (dev 2.0.4, prod 2.0.7). Tracking it in the
shared content repo caused cross-env drift; with git-sync enabled it
would push one env's version stamp to all others. Gitignore + untrack so
each install owns its own (Grav regenerates it). Mirrors the existing
treatment of security.yaml / api-private.php.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
One /post form now drives both create and edit (KTD1, Alt B): cache-on-save
toggles add-page-by-form's overwrite_mode per submit — 'edit' when the new hidden
edit_path field is filled (write back in place, stable URL), 'false' when empty
(fresh dated folder via slug_field). add-page-by-form stays stock (no fork);
the toggle lives in cache-on-save, which reads edit_path and mutates the /post
page header's pageconfig before add-page-by-form's onFormProcessed runs.
- post-form.md: overwrite_mode:false (create-safe fallback), hidden edit_path,
authoritative published toggle (default on), removed the static
pagefrontmatter.published so the field wins on every submit (KTD3).
- cache-on-save.php: editPathFromForm + setOverwriteMode helpers.
- site.yaml: owner_username (single source of truth for the KTD8 owner gate).
Verified against the 2.0.4 container: create writes a fresh dated folder with
published:true/false as a real boolean (V1, V2); edit writes in place with the
slug/URL unchanged; save-as-draft-on-create works.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H1FrCYNq6RXdGYbn5PFrhM
The API plugin's enabled/route/session_enabled/cors/rate_limit config
lived only in the untracked user/plugins/api/api.yaml, so a fresh install
(prod) had no working /api — Admin2, which authenticates via /api/v1,
could not log in. Move the functional config into the tracked override
user/config/plugins/api.yaml (merged over the plugin defaults). Secrets
(JWT) stay in the gitignored api-private.php; the auto-generated
popularity salt is intentionally not committed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
Grav 2.0's schema migration replaces the 1.7-era twig_compat with
twig2_compat/twig3_compat. Matching the repo to what the upgraded server
already generated so a content reset doesn't revert it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
- active_trip: italy-2026-demo in site.yaml (was japan-korea-2026)
- post-form.md parent updated to /trips/italy-2026-demo/dailies
- Remove japan-korea-2026 trip pages (no real trip exists)
- Remove stale old italy-2026-demo entries/stories/GPX from git tracking
(these were leftover from before the demo-source approach)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr
Adds leaflet-gpx@2.1.2 CDN script to map template, collects *.gpx
media files from the trip page, and renders them as teal polylines
beneath entry pins. Also fixes user/config/media.yaml to use the
required types: key so Grav's Media class correctly discovers .gpx
files. Map remains functional when no GPX files are present.
Changes dateformat.default from 'd M Y' to 'Y-m-d H:i' so dates
submitted via the post form are stored as '2026-06-19 10:30' rather
than '18 Jun 2026'. This ensures add-page-by-form generates slugs in
YYYY-MM-DD-HHmm-title order, preserving chronological sort.
All templates use explicit |date() filters so display is unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add blueprints.yaml for cache-on-save plugin with Grav 2.0 support
- Update system.yaml GPM setting from stable to testing channel
- Update .gitignore to allow cache-on-save plugin tracking
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- entry.html.twig: add |raw to page.content (autoescape: true in
system.yaml was escaping all HTML output including rendered markdown)
- tracker.html.twig: use |striptags|slice(0,250) for clean plain-text
excerpts instead of raw HTML summary
- Both templates: fix location display whitespace (Tokyo , Japan → Tokyo, Japan)
using parts array pattern with Twig whitespace control
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
BUG-001: cache-on-save plugin clears page cache on onFormProcessed so
new entries appear in the tracker feed immediately after submission.
BUG-002: disabled Twig template cache (twig.cache: false) so theme
file changes take effect without a manual cache flush.
Also adds bugs-and-fixes.md, corrects TC-P test URLs (.entry suffix),
fixes TC-P.1 expectation (inline login form, not a redirect), and
creates the QA test entry for automated scenario verification.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>