feat: trip page matches home layout — sticky map + feed, GPX route, no sidebar
- Same home-layout (45% sticky map / 55% scrollable feed) on every trip page - GPX route overlay loaded from trip page media - Marker click scrolls to entry card (same as home page) - Map sub-nav link removed (map is now embedded) - Separate /map page remains accessible by URL but has no nav link Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RB86BaJBG3eGiMdfhmHRrQ
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
{{ assets.css()|raw }}
|
{{ assets.css()|raw }}
|
||||||
{{ assets.js()|raw }}
|
{{ assets.js()|raw }}
|
||||||
</head>
|
</head>
|
||||||
<body class="{% if page.template == 'map' %}map-page{% endif %}{% if page.template == 'home' %} home-page{% endif %}">
|
<body class="{% if page.template == 'map' %}map-page{% endif %}{% if page.template == 'home' or page.template == 'trip' %} home-page{% endif %}">
|
||||||
<header class="site-header">
|
<header class="site-header">
|
||||||
<a class="site-title" href="{{ base_url_absolute }}">into the east</a>
|
<a class="site-title" href="{{ base_url_absolute }}">into the east</a>
|
||||||
{% block nav %}
|
{% block nav %}
|
||||||
|
|||||||
@@ -18,29 +18,50 @@
|
|||||||
{% set journal_count = journal_entries|length %}
|
{% set journal_count = journal_entries|length %}
|
||||||
{% set story_count = story_entries|length %}
|
{% set story_count = story_entries|length %}
|
||||||
|
|
||||||
<div class="trip-hero">
|
{% set gpx_urls = [] %}
|
||||||
<h1>{{ page.title }}</h1>
|
{% for name, media in page.media.all %}
|
||||||
{% if page.header.date_start %}
|
{% if name|split('.')|last == 'gpx' %}
|
||||||
<p class="trip-dates">
|
{% set gpx_urls = gpx_urls|merge([page.url ~ '/' ~ name]) %}
|
||||||
{{ page.header.date_start|date('d M Y') }}
|
|
||||||
{% if page.header.date_end %} — {{ page.header.date_end|date('d M Y') }}{% endif %}
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="trip-counts">
|
{% endfor %}
|
||||||
{{ journal_count }} journal {{ journal_count == 1 ? 'entry' : 'entries' }}
|
|
||||||
{% if story_count > 0 %} · {{ story_count }} {{ story_count == 1 ? 'story' : 'stories' }}{% endif %}
|
{% set map_entries = [] %}
|
||||||
</p>
|
{% for item in all_items %}
|
||||||
|
{% if item.type == 'journal' and item.page.header.lat is not empty and item.page.header.lng is not empty %}
|
||||||
|
{% set map_entries = map_entries|merge([{
|
||||||
|
'lat': item.page.header.lat|number_format(6, '.', ''),
|
||||||
|
'lng': item.page.header.lng|number_format(6, '.', ''),
|
||||||
|
'slug': item.page.slug,
|
||||||
|
'title': item.page.title
|
||||||
|
}]) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<div class="home-layout">
|
||||||
|
<div class="home-map-col">
|
||||||
|
<div class="home-map" id="trip-map"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="home-feed-col">
|
||||||
|
<div class="home-trip-header">
|
||||||
|
<h1 class="home-trip-name">{{ page.title }}</h1>
|
||||||
|
{% if page.header.date_start %}
|
||||||
|
<p class="trip-dates" style="font-size:var(--text-sm);color:var(--color-ink-muted);margin:var(--space-1) 0 var(--space-2);">
|
||||||
|
{{ page.header.date_start|date('d M Y') }}
|
||||||
|
{% if page.header.date_end %} — {{ page.header.date_end|date('d M Y') }}{% else %} — Ongoing{% endif %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
<span class="home-trip-counts">
|
||||||
|
{{ journal_count }} journal {{ journal_count == 1 ? 'entry' : 'entries' }}
|
||||||
|
{% if story_count > 0 %} · {{ story_count }} {{ story_count == 1 ? 'story' : 'stories' }}{% endif %}
|
||||||
|
</span>
|
||||||
<nav class="trip-nav">
|
<nav class="trip-nav">
|
||||||
<a href="{{ page.route }}/dailies">Journal</a>
|
<a href="{{ page.route }}/dailies">Journal</a>
|
||||||
<a href="{{ page.route }}/map">Map</a>
|
|
||||||
<a href="{{ page.route }}/stats">Stats</a>
|
<a href="{{ page.route }}/stats">Stats</a>
|
||||||
<a href="{{ page.route }}/stories">Stories</a>
|
<a href="{{ page.route }}/stories">Stories</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="trip-layout">
|
|
||||||
<div class="trip-feed">
|
|
||||||
<div class="feed">
|
<div class="feed">
|
||||||
{% if all_items|length > 0 %}
|
{% if all_items|length > 0 %}
|
||||||
{% for item in all_items %}
|
{% for item in all_items %}
|
||||||
@@ -53,7 +74,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if item.type == 'journal' %}
|
{% if item.type == 'journal' %}
|
||||||
<article class="entry-card" id="entry-{{ entry.slug }}">
|
<article class="entry-card" id="entry-{{ entry.slug }}" data-lat="{{ entry.header.lat }}" data-lng="{{ entry.header.lng }}">
|
||||||
<a class="entry-card-inner" href="{{ entry.url }}">
|
<a class="entry-card-inner" href="{{ entry.url }}">
|
||||||
{% if hero %}
|
{% if hero %}
|
||||||
<div class="entry-card-photo">
|
<div class="entry-card-photo">
|
||||||
@@ -115,32 +136,55 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<aside class="trip-sidebar">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.min.css">
|
||||||
{% if journal_entries|length > 0 %}
|
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.min.js"></script>
|
||||||
<div class="trip-sidebar-section">
|
<script src="https://cdn.jsdelivr.net/npm/leaflet-gpx@2.1.2/gpx.min.js"></script>
|
||||||
<h3 class="trip-sidebar-heading">Journal</h3>
|
<script>
|
||||||
<ul class="trip-sidebar-list">
|
var TRIP_ENTRIES = {{ map_entries|json_encode|raw }};
|
||||||
{% for e in journal_entries %}
|
var GPX_URLS = {{ gpx_urls|json_encode|raw }};
|
||||||
<li>
|
|
||||||
<a href="#entry-{{ e.slug }}" class="trip-sidebar-link">
|
var map = L.map('trip-map', { minZoom: 2, maxZoom: 18, zoomControl: true });
|
||||||
<span class="trip-sidebar-date">{{ e.date|date('d M') }}</span>{{ e.title }}
|
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
|
||||||
</a>
|
maxZoom: 20,
|
||||||
</li>
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>'
|
||||||
{% endfor %}
|
}).addTo(map);
|
||||||
</ul>
|
|
||||||
</div>
|
GPX_URLS.forEach(function(url) {
|
||||||
{% endif %}
|
new L.GPX(url, {
|
||||||
{% if story_entries|length > 0 %}
|
async: true,
|
||||||
<div class="trip-sidebar-section">
|
polyline_options: { color: '#1F6B5A', weight: 2, opacity: 0.6 },
|
||||||
<h3 class="trip-sidebar-heading">Stories</h3>
|
marker_options: { startIconUrl: null, endIconUrl: null, shadowUrl: null }
|
||||||
<ul class="trip-sidebar-list">
|
}).addTo(map);
|
||||||
{% for s in story_entries %}
|
});
|
||||||
<li><a href="#entry-{{ s.slug }}" class="trip-sidebar-link">{{ s.title }}</a></li>
|
|
||||||
{% endfor %}
|
if (TRIP_ENTRIES.length === 0) {
|
||||||
</ul>
|
map.setView([20, 0], 2);
|
||||||
</div>
|
} else {
|
||||||
{% endif %}
|
var latLngs = TRIP_ENTRIES.map(function(e) { return [parseFloat(e.lat), parseFloat(e.lng)]; });
|
||||||
</aside>
|
L.polyline(latLngs, { color: '#2A8C73', weight: 3, opacity: 0.7 }).addTo(map);
|
||||||
</div>
|
|
||||||
|
TRIP_ENTRIES.forEach(function(entry, i) {
|
||||||
|
var isLatest = (i === TRIP_ENTRIES.length - 1);
|
||||||
|
var size = isLatest ? 16 : 10;
|
||||||
|
var color = isLatest ? '#155244' : '#1F6B5A';
|
||||||
|
var icon = L.divIcon({
|
||||||
|
className: '',
|
||||||
|
html: '<div style="width:' + size + 'px;height:' + size + 'px;background:' + color + ';border:2px solid #fff;border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,0.35);cursor:pointer;"></div>',
|
||||||
|
iconSize: [size, size],
|
||||||
|
iconAnchor: [size/2, size/2]
|
||||||
|
});
|
||||||
|
L.marker([parseFloat(entry.lat), parseFloat(entry.lng)], { icon: icon })
|
||||||
|
.addTo(map)
|
||||||
|
.on('click', function() {
|
||||||
|
var card = document.getElementById('entry-' + entry.slug);
|
||||||
|
if (card) { card.scrollIntoView({ behavior: 'smooth', block: 'center' }); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
map.fitBounds(L.latLngBounds(latLngs), { padding: [20, 20] });
|
||||||
|
}
|
||||||
|
setTimeout(function() { map.invalidateSize(); }, 100);
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user