{#
Shared trip cover: one source of truth for cover resolution + retina
rendering, used by both the trip-list card (trips.html.twig) and the
trip-page banner strip (trip-feed-col.html.twig) so the two surfaces
cannot drift (KTD2).
Resolution (R7 / R11):
1. author-selected header.cover_image, when it resolves to page media;
2. else the first published journal entry's first image;
3. else nothing.
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
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 —
so resolution and rendering live together in one macro: it emits the
wrapper + retina when a cover exists, and nothing at all when none
does (which gives R9/AE4 a clean text-only header for free).
Retina (R6 / R14): two explicit cropResize derivatives (1x at w×h, 2x at
2w×2h) as an explicit `srcset` with w-descriptors; `alt` is the trip title.
#}
{% macro render(trip_page, alt, w, h, wrapper_class, sizes) %}
{%- set cover = null -%}
{%- if trip_page.header.cover_image and trip_page.media.images[trip_page.header.cover_image] is defined -%}
{%- set cover = trip_page.media.images[trip_page.header.cover_image] -%}
{%- else -%}
{%- set dailies_page = grav.pages.find(trip_page.route ~ '/dailies') -%}
{%- if dailies_page -%}
{%- set first_entry = dailies_page.children.published()|first -%}
{%- if first_entry and first_entry.media.images|length > 0 -%}
{%- set cover = first_entry.media.images|first -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- if cover -%}