From 04bcab2d55e9c240a1410e0ecd9930086742c0fc Mon Sep 17 00:00:00 2001 From: Mischa Date: Tue, 23 Jun 2026 23:57:54 +0200 Subject: [PATCH] refactor: extract stats and cycling panels to Twig macros Move stats computation and both panel HTML divs out of trip.html.twig into dedicated macros/stats.html.twig and macros/cycling.html.twig. trip.html.twig imports both at the top of {% block content %} and calls them via stats_m.stats_panel() and cycling_m.cycling_panel(). Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01Vgmzx8VTTTmCskSpQtsLTr --- .../templates/macros/cycling.html.twig | 41 ++++++ .../templates/macros/stats.html.twig | 93 ++++++++++++ themes/intotheeast/templates/trip.html.twig | 138 +----------------- 3 files changed, 138 insertions(+), 134 deletions(-) create mode 100644 themes/intotheeast/templates/macros/cycling.html.twig create mode 100644 themes/intotheeast/templates/macros/stats.html.twig diff --git a/themes/intotheeast/templates/macros/cycling.html.twig b/themes/intotheeast/templates/macros/cycling.html.twig new file mode 100644 index 0000000..22e6155 --- /dev/null +++ b/themes/intotheeast/templates/macros/cycling.html.twig @@ -0,0 +1,41 @@ +{% macro cycling_panel() %} +
+
+
+ ๐Ÿšด + Cycling Stats +
+
+
+ โ€” + km distance +
+
+ โ€” + m โ†‘ gain +
+
+ โ€” + m โ†“ loss +
+
+ โ€” + m highest +
+
+ โ€” + m lowest +
+
+ โ€” + moving time +
+
+ โ€” + km/h avg speed +
+
+ +
+
+{% endmacro %} diff --git a/themes/intotheeast/templates/macros/stats.html.twig b/themes/intotheeast/templates/macros/stats.html.twig new file mode 100644 index 0000000..3f757d5 --- /dev/null +++ b/themes/intotheeast/templates/macros/stats.html.twig @@ -0,0 +1,93 @@ +{% macro stats_panel(journal_entries, page, journal_count, has_gpx) %} +{% set days_on_road = 0 %} +{% if page.header.date_end is not empty %} + {% set start_ts = page.header.date_start|date('U') %} + {% set end_ts = page.header.date_end|date('U') %} + {% set days_on_road = ((end_ts - start_ts) / 86400)|round(0, 'ceil') %} +{% else %} + {% set first_ts = null %} + {% for entry in journal_entries %} + {% set ts = entry.date|date('U') %} + {% if first_ts is null or ts < first_ts %}{% set first_ts = ts %}{% endif %} + {% endfor %} + {% if first_ts is not null %} + {% set diff_seconds = "now"|date('U') - first_ts %} + {% set days_raw = (diff_seconds / 86400)|round(0, 'floor') %} + {% set days_on_road = days_raw < 1 ? 1 : days_raw %} + {% endif %} +{% endif %} + +{% set seen_lower = [] %} +{% set country_display = [] %} +{% for entry in journal_entries %} + {% if entry.header.location_country is not empty %} + {% set lower = entry.header.location_country|trim|lower %} + {% if lower not in seen_lower %} + {% set seen_lower = seen_lower|merge([lower]) %} + {% set country_display = country_display|merge([entry.header.location_country|trim]) %} + {% endif %} + {% endif %} +{% endfor %} + +{% set seen_city_lower = [] %} +{% set city_display = [] %} +{% for entry in journal_entries %} + {% if entry.header.location_city is not empty %} + {% set lower = entry.header.location_city|trim|lower %} + {% if lower not in seen_city_lower %} + {% set seen_city_lower = seen_city_lower|merge([lower]) %} + {% set city_display = city_display|merge([entry.header.location_city|trim]) %} + {% endif %} + {% endif %} +{% endfor %} + +{% set temp_min = null %} +{% set temp_max = null %} +{% for entry in journal_entries %} + {% if entry.header.weather_temp_c is defined and entry.header.weather_temp_c is not empty %} + {% set t = entry.header.weather_temp_c %} + {% if temp_min is null or t < temp_min %}{% set temp_min = t %}{% endif %} + {% if temp_max is null or t > temp_max %}{% set temp_max = t %}{% endif %} + {% endif %} +{% endfor %} + +
+
+
+
+ {{ days_on_road }} + {{ days_on_road == 1 ? 'day' : 'days' }} on the road +
+
+ {{ journal_count }} + {{ journal_count == 1 ? 'entry' : 'entries' }} posted +
+
+ {{ country_display|length }} + {{ country_display|length == 1 ? 'country' : 'countries' }} visited +
+
+ {{ city_display|length }} + {{ city_display|length == 1 ? 'city' : 'cities' }} visited +
+
+ โ€” + {{ has_gpx ? '๐Ÿšด km cycled' : '๐Ÿงญ km roamed' }} +
+
+ {% if temp_min is not null %} + {{ temp_min == temp_max ? temp_min : temp_min ~ ' โ†’ ' ~ temp_max }} + {% else %} + โ€” + {% endif %} + ยฐC range +
+
+ {% if country_display|length > 0 %} +

{{ country_display|join(' ยท ') }}

+ {% endif %} +

{{ has_gpx ? 'Distance based on GPS track data.' : 'Distance is approximate โ€” straight lines between entry locations.' }}

+ +
+
+{% endmacro %} diff --git a/themes/intotheeast/templates/trip.html.twig b/themes/intotheeast/templates/trip.html.twig index b8013a0..eec47c2 100644 --- a/themes/intotheeast/templates/trip.html.twig +++ b/themes/intotheeast/templates/trip.html.twig @@ -1,6 +1,8 @@ {% extends 'partials/base.html.twig' %} {% block content %} +{% import 'macros/stats.html.twig' as stats_m %} +{% import 'macros/cycling.html.twig' as cycling_m %} {% block map_assets %} {% do assets.addCss('theme://css-compiled/map.css') %} {% do assets.addJs('theme://js/map.js', {group: 'bottom'}) %} @@ -22,59 +24,6 @@ {% set journal_count = journal_entries|length %} {% set story_count = story_entries|length %} -{# Stats computation #} -{% set days_on_road = 0 %} -{% if page.header.date_end is not empty %} - {% set start_ts = page.header.date_start|date('U') %} - {% set end_ts = page.header.date_end|date('U') %} - {% set days_on_road = ((end_ts - start_ts) / 86400)|round(0, 'ceil') %} -{% else %} - {% set first_ts = null %} - {% for entry in journal_entries %} - {% set ts = entry.date|date('U') %} - {% if first_ts is null or ts < first_ts %}{% set first_ts = ts %}{% endif %} - {% endfor %} - {% if first_ts is not null %} - {% set diff_seconds = "now"|date('U') - first_ts %} - {% set days_raw = (diff_seconds / 86400)|round(0, 'floor') %} - {% set days_on_road = days_raw < 1 ? 1 : days_raw %} - {% endif %} -{% endif %} - -{% set seen_lower = [] %} -{% set country_display = [] %} -{% for entry in journal_entries %} - {% if entry.header.location_country is not empty %} - {% set lower = entry.header.location_country|trim|lower %} - {% if lower not in seen_lower %} - {% set seen_lower = seen_lower|merge([lower]) %} - {% set country_display = country_display|merge([entry.header.location_country|trim]) %} - {% endif %} - {% endif %} -{% endfor %} - -{% set seen_city_lower = [] %} -{% set city_display = [] %} -{% for entry in journal_entries %} - {% if entry.header.location_city is not empty %} - {% set lower = entry.header.location_city|trim|lower %} - {% if lower not in seen_city_lower %} - {% set seen_city_lower = seen_city_lower|merge([lower]) %} - {% set city_display = city_display|merge([entry.header.location_city|trim]) %} - {% endif %} - {% endif %} -{% endfor %} - -{% set temp_min = null %} -{% set temp_max = null %} -{% for entry in journal_entries %} - {% if entry.header.weather_temp_c is defined and entry.header.weather_temp_c is not empty %} - {% set t = entry.header.weather_temp_c %} - {% if temp_min is null or t < temp_min %}{% set temp_min = t %}{% endif %} - {% if temp_max is null or t > temp_max %}{% set temp_max = t %}{% endif %} - {% endif %} -{% endfor %} - {% set gps_points = [] %} {% for entry in journal_entries %} {% if entry.header.lat is not empty and entry.header.lng is not empty %} @@ -147,86 +96,10 @@ -
-
-
-
- {{ days_on_road }} - {{ days_on_road == 1 ? 'day' : 'days' }} on the road -
-
- {{ journal_count }} - {{ journal_count == 1 ? 'entry' : 'entries' }} posted -
-
- {{ country_display|length }} - {{ country_display|length == 1 ? 'country' : 'countries' }} visited -
-
- {{ city_display|length }} - {{ city_display|length == 1 ? 'city' : 'cities' }} visited -
-
- โ€” - {{ has_gpx ? '๐Ÿšด km cycled' : '๐Ÿงญ km roamed' }} -
-
- {% if temp_min is not null %} - {{ temp_min == temp_max ? temp_min : temp_min ~ ' โ†’ ' ~ temp_max }} - {% else %} - โ€” - {% endif %} - ยฐC range -
-
- {% if country_display|length > 0 %} -

{{ country_display|join(' ยท ') }}

- {% endif %} -

{{ has_gpx ? 'Distance based on GPS track data.' : 'Distance is approximate โ€” straight lines between entry locations.' }}

- -
-
+ {{ stats_m.stats_panel(journal_entries, page, journal_count, has_gpx) }} {% if has_gpx %} -
-
-
- ๐Ÿšด - Cycling Stats -
-
-
- โ€” - km distance -
-
- โ€” - m โ†‘ gain -
-
- โ€” - m โ†“ loss -
-
- โ€” - m highest -
-
- โ€” - m lowest -
-
- โ€” - moving time -
-
- โ€” - km/h avg speed -
-
- -
-
+ {{ cycling_m.cycling_panel() }} {% endif %}
@@ -345,11 +218,9 @@ var HAS_GPX = {{ has_gpx ? 'true' : 'false' }}; if (HAS_GPX) { MapUtils.parseGpxFiles(GPX_URLS, function(result) { - // Mode A: update distance stat if (distEl) { distEl.textContent = result.distance > 0 ? Math.round(result.distance).toLocaleString() : 'โ€”'; } - // Populate cycling panel function setText(id, val) { var el = document.getElementById(id); if (el) el.textContent = val; @@ -363,7 +234,6 @@ var HAS_GPX = {{ has_gpx ? 'true' : 'false' }}; setText('cyc-avg-speed', result.avgSpeed > 0 ? result.avgSpeed.toFixed(1) : 'โ€”'); }); } else { - // Mode B: haversine between entry points var total = 0; for (var i = 1; i < STATS_GPS.length; i++) { total += MapUtils.haversineKm(