fix(trip-cover): restrict cover picker to images + guard non-image selection
The header.cover_image pagemediaselect field had no accept filter, so the Admin media picker listed every file in the trip page folder — including the GPX files placed there by the GPX manager. On a typical trip page (photos live on the journal entries, not the trip page) the picker offered *only* GPX, and selecting one routed a non-image Medium into cropResize, rendering a broken <img> on both the trips list and the trip banner. - Blueprint: add `accept: ['.jpg','.jpeg','.png','.webp','.gif']` so the picker only offers images (prevention at source). - Macro: resolve cover_image against `media.images` instead of all media, so a non-image or unresolvable selection falls through to the entry-photo auto-pick (defence-in-depth; also hardens the R11 fallback). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RDS6t8wcpbwKvvrxykVQ5K
This commit is contained in:
@@ -39,6 +39,7 @@ form:
|
|||||||
|
|
||||||
header.cover_image:
|
header.cover_image:
|
||||||
type: pagemediaselect
|
type: pagemediaselect
|
||||||
|
accept: ['.jpg', '.jpeg', '.png', '.webp', '.gif']
|
||||||
label: 'Cover Image'
|
label: 'Cover Image'
|
||||||
help: 'Pick from images uploaded to this trip page. Shown on the trips listing and the trip-page banner. Falls back to the first journal entry photo if left unset.'
|
help: 'Pick from images uploaded to this trip page. Shown on the trips listing and the trip-page banner. Falls back to the first journal entry photo if left unset.'
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
3. else nothing.
|
3. else nothing.
|
||||||
A set-but-missing cover_image (deleted/moved file) is `is not defined` in
|
A set-but-missing cover_image (deleted/moved file) is `is not defined` in
|
||||||
page media, so it falls through to the auto-pick rather than rendering a
|
page media, so it falls through to the auto-pick rather than rendering a
|
||||||
broken image (R11).
|
broken image (R11). Resolution matches against `media.images` (not all
|
||||||
|
media), so a non-image selection — e.g. a `.gpx` from the trip page's own
|
||||||
|
media, which the picker used to offer — also falls through instead of
|
||||||
|
routing a non-image Medium into cropResize.
|
||||||
|
|
||||||
Twig macros can only emit strings — they cannot return a Medium object —
|
Twig macros can only emit strings — they cannot return a Medium object —
|
||||||
so resolution and rendering live together in one macro: it emits the
|
so resolution and rendering live together in one macro: it emits the
|
||||||
@@ -22,8 +25,8 @@
|
|||||||
#}
|
#}
|
||||||
{% macro render(trip_page, alt, w, h, wrapper_class, sizes) %}
|
{% macro render(trip_page, alt, w, h, wrapper_class, sizes) %}
|
||||||
{%- set cover = null -%}
|
{%- set cover = null -%}
|
||||||
{%- if trip_page.header.cover_image and trip_page.media[trip_page.header.cover_image] is defined -%}
|
{%- if trip_page.header.cover_image and trip_page.media.images[trip_page.header.cover_image] is defined -%}
|
||||||
{%- set cover = trip_page.media[trip_page.header.cover_image] -%}
|
{%- set cover = trip_page.media.images[trip_page.header.cover_image] -%}
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{%- set dailies_page = grav.pages.find(trip_page.route ~ '/dailies') -%}
|
{%- set dailies_page = grav.pages.find(trip_page.route ~ '/dailies') -%}
|
||||||
{%- if dailies_page -%}
|
{%- if dailies_page -%}
|
||||||
|
|||||||
Reference in New Issue
Block a user