Raise the FilePond limit from 4 to 6 and enforce a minimum of one photo.
The photo field is first in the form, so initValidation checks it first: an
empty picker blocks submit, reveals the (possibly collapsed) photo section,
and shows "Add at least one photo." under its header. Labels updated to
"Photos (1–6)".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The stock Grav `datetime` field template is deprecated and falls back to a
plain text box, so `type: datetime` + `default: now` rendered a raw input
showing the literal word "now" — unusable. Add a theme override at
templates/forms/fields/datetime/datetime.html.twig that renders a native
<input type="datetime-local"> (real calendar+clock, great on mobile), drop
the `default: now`, and prefill the current local time from post-form.js.
Also add `date` to the existing client-side validator. Together with the
picker (which can't hold an invalid value) this stops a bad/empty date from
round-tripping to the server — which was the trigger that made Grav re-render
the managed FilePond field from the session flash as filename-only inputs and
resurrect a photo the user had removed. Grav still reformats the submitted
value to the blueprint `format: 'Y-m-d H:i'` on save, so stored dates and
folder slugs are unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Reorder blueprint to Photos → Title → Content; drop title autofocus so the
picker leads (it anchors what you write).
- After upload the photo section auto-collapses to a live summary bar
("✓ N photos ready — tap to review") and re-expands on tap; the field's
own .form-label is hidden so the <summary> is the sole header. Trailing
refreshes settle the summary past FilePond's event/DOM timing gap.
- Replace FilePond's murky completed-thumbnail overlay with a clean green ✓
badge (remove action left intact).
- On a successful post, hide the reset form + location/weather controls so
only the "✓ Saved" confirmation + View-journal CTA remain.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Runtime verification showed the custom picker uploaded to Grav's flash but
never attached photos to the entry — attachment needs FilePond's exact
(undocumented) submit contract. Reverting to type:filepond and hooking its
beforeAddFile: a HEIC item is rejected, converted to JPEG via the lazy heic-to
chunk, then re-added with pond.addFile() so FilePond owns upload + page-attach
(the proven path). Web-format photos pass through; conversion failures fail
closed (inline status, original never added). Removes the custom photos field
template + AJAX uploader.
Verified end-to-end in a browser: HEIC posts as JPEG, corrupt HEIC is skipped,
Submit gated while converting, draft photos-reselect hint intact.
Refs R8, R9, R16, R17, AE1, AE4, KTD4.
Replace /post's managed filepond field with a controlled 'photos' field
(theme forms/fields/photos) + picker logic in post-form.js: magic-byte
sniff (ISO-BMFF ftyp brands, not filename/MIME), lazy import('heic-to')
only for real HEIC (deferred 3MB chunk via ESM splitting), per-thumbnail
converting/uploading/done/error states, in-flight counter gating Submit,
and fail-closed skip on conversion failure. Converted JPEGs POST to Grav's
AJAX file-upload route into the form flash (the only path copyFiles reads),
so add-page-by-form attaches them on submit. Web-format photos pass through.
Refs R8, R9, R16, R17, AE1, AE4, KTD4.
Derive the entry write target from site.active_trip at submit time in
cache-on-save's onFormValidationProcessed handler, and fail closed
(ValidationException) when no active trip is set. Removes the hardcoded
pageconfig.parent that had to be hand-synced with active_trip.
Refs R1, R2, AE2, KTD1.
Match the demo's naming (was 'The Journey' on real trips). These
containers are inert folders now; the title just labels what's below.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 1 of the standalone sub-page cleanup. The trip page consolidated
these views (inline map + filter bar + inline stats), leaving the
standalone pages unreachable and the last consumers of the old map
code path (feed-map inline script + map.html renderGpxJourney variant).
- Delete templates: map, stats, dailies, stories + feed-map partial
- Delete 02.map/03.stats page folders across all trips
- Keep 01.dailies/04.stories as inert data containers (routable:false)
- Fix demo source + Makefile demo-load so reload stays consistent
- Drop dead map-page body class in base.html.twig
Site converges on MapUtils.initEntryMap(); child entries/stories remain
reachable (verified: keepers 200, retired 404, no Twig errors).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move Piran entry out of us-canada-mex-2024 into a new slovenia-2024 trip.
Rename entry folder to match the post title convention.
Fix us-canada-mex-2024 date_start to 2024-07-21 (first actual US entry).
Applied location_city, location_country, lat, lng, weather_temp_c, weather_desc to all
11 entries (pixelfed-2 through pixelfed-12). Renamed folders from pixelfed-N format to
date-title-slug format. pixelfed-1 (Piran/Slovenia) left untouched.
Applied location (city, country, lat, lng) and weather (temp_c, desc) enrichment to all 22
journal entries. Renamed entry folders from pixelfed-N numbering to date-title-slug format.
Bukhara entry (pixelfed-15) had its date corrected from 2023-09-23 to 2023-10-02.
- 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
Reverts text→datetime change. Uses format:'Y-m-d' (date-only) so the
datepicker omits the time component. Strips HH:MM from all Italy demo
story dates for consistency with the new date-only format.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr
Blueprint: end_date format changed to Y-m-d H:i (same as start date) so
Admin2 uses the identical datepicker — avoids ambiguous d-m-Y input being
misread by PHP as m-d-Y.
Template guard: was comparing end_date string against page.date|date('Y-m-d')
which can never match. Now compares date-only parts of both fields:
page.header.end_date|date('Y-m-d') != page.date|date('Y-m-d')
Montalcino live page: removed test end_date '12-09-2026 00:00'.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr
Montalcino demo story had end_date: 2025-09-06 matching its start date,
causing a '06 – 06 Sep' range display. Removed from both the live page
and the demo source.
Template: added guard so end_date equal to the start date never renders
as a range, even if it appears in frontmatter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr
- entry.html.twig: replace hardcoded /tracker href with page.parent().url
- post-form.md: add comment to keep pageconfig.parent in sync with active_trip in site.yaml
- Rename tracker.html.twig to dailies.html.twig; update dailies.md template key
- Fix map.html.twig and stats.html.twig: find dailies via page.parent().route
- Update base.html.twig nav to use config.site.active_trip for all hrefs
- Fix dailies.html.twig mini-map link to use page.parent().url/map
- Create trip.html.twig, trips.html.twig, stories.html.twig
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New demo entry: Arashiyama with single hero image (bamboo.jpg)
- New demo entry: Gyeongbokgung with four gallery images (palace-gate,
throne-hall, hanok-rooftops, bugaksan)
- post-form.md: add upload: true to process block so filepond photo
uploads are handled after page creation; simplify list-of-maps to
flat map (Symfony YAML preserves insertion order)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Seven fixture entries (March 25 Narita through April 1 Seoul) used as
Playwright test fixtures for tracker ordering and entry-page tests.
Removes the leftover June 18 test entry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>