Replace OSM iframe with Leaflet map: marker, zoom, geocoding via Nominatim
- Add event-map.js module: loads Leaflet dynamically, geocodes address, renders map with marker at zoom 16 - Remove iframe, address text and OSM link below map - Add CSP entries for unpkg (Leaflet), tile.openstreetmap.org (tiles), nominatim (geocoding) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { initMobileMenu } from "./modules/mobile-menu.js"
|
||||
import { initTabs } from "./modules/tabs.js"
|
||||
import { registerEditor } from "./modules/editor.js"
|
||||
import { initCookieConsent } from "./modules/cookie-consent.js"
|
||||
import { initEventMap } from "./modules/event-map.js"
|
||||
|
||||
function initCopyUrl() {
|
||||
const btn = document.getElementById('copy-url-btn')
|
||||
@@ -24,4 +25,5 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
registerEditor()
|
||||
initCookieConsent()
|
||||
initCopyUrl()
|
||||
initEventMap()
|
||||
})
|
||||
|
||||
47
assets/modules/event-map.js
Normal file
47
assets/modules/event-map.js
Normal file
@@ -0,0 +1,47 @@
|
||||
export function initEventMap() {
|
||||
const mapEl = document.getElementById('event-map')
|
||||
if (!mapEl) return
|
||||
|
||||
const address = mapEl.dataset.address
|
||||
if (!address) return
|
||||
|
||||
const link = document.createElement('link')
|
||||
link.rel = 'stylesheet'
|
||||
link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'
|
||||
document.head.appendChild(link)
|
||||
|
||||
const script = document.createElement('script')
|
||||
script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'
|
||||
script.onload = () => geocodeAndRender(address, mapEl)
|
||||
document.head.appendChild(script)
|
||||
}
|
||||
|
||||
function geocodeAndRender(address, mapEl) {
|
||||
const url = 'https://nominatim.openstreetmap.org/search?format=json&limit=1&q=' + encodeURIComponent(address)
|
||||
|
||||
globalThis.fetch(url)
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.length === 0) {
|
||||
mapEl.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100%;background:#f3f4f6;"><p style="font-weight:700;color:#9ca3af;">Adresse introuvable sur la carte</p></div>'
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const lat = parseFloat(data[0].lat)
|
||||
const lon = parseFloat(data[0].lon)
|
||||
|
||||
/* global L */
|
||||
const map = L.map(mapEl).setView([lat, lon], 16)
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||
maxZoom: 19,
|
||||
}).addTo(map)
|
||||
|
||||
L.marker([lat, lon]).addTo(map).bindPopup('<b>' + address + '</b>').openPopup()
|
||||
})
|
||||
.catch(() => {
|
||||
mapEl.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100%;background:#f3f4f6;"><p style="font-weight:700;color:#9ca3af;">Carte indisponible</p></div>'
|
||||
})
|
||||
}
|
||||
@@ -28,20 +28,23 @@ nelmio_security:
|
||||
- 'https://cloudflare.com'
|
||||
- 'https://*.cloudflareinsights.com'
|
||||
- 'https://challenges.cloudflare.com'
|
||||
- 'https://www.openstreetmap.org'
|
||||
script-src:
|
||||
- 'self'
|
||||
- 'https://static.cloudflareinsights.com'
|
||||
- 'https://challenges.cloudflare.com'
|
||||
- 'https://unpkg.com'
|
||||
- 'unsafe-inline'
|
||||
style-src:
|
||||
- 'self'
|
||||
- 'https://fonts.googleapis.com'
|
||||
- 'https://cdnjs.cloudflare.com'
|
||||
- 'https://unpkg.com'
|
||||
- 'unsafe-inline'
|
||||
img-src:
|
||||
- 'self'
|
||||
- 'data:'
|
||||
- 'https://*.tile.openstreetmap.org'
|
||||
- 'https://unpkg.com'
|
||||
worker-src:
|
||||
- 'self'
|
||||
- 'blob:'
|
||||
@@ -51,6 +54,7 @@ nelmio_security:
|
||||
- 'https://static.cloudflareinsights.com'
|
||||
- 'https://tools-security.esy-web.dev'
|
||||
- 'https://challenges.cloudflare.com'
|
||||
- 'https://nominatim.openstreetmap.org'
|
||||
font-src:
|
||||
- 'self'
|
||||
- 'https://cdnjs.cloudflare.com'
|
||||
|
||||
@@ -74,19 +74,7 @@
|
||||
<div class="section-header">
|
||||
<h2 class="text-sm font-black uppercase tracking-widest text-white">Emplacement</h2>
|
||||
</div>
|
||||
<iframe
|
||||
class="w-full h-[300px] border-0"
|
||||
loading="lazy"
|
||||
referrerpolicy="no-referrer-when-downgrade"
|
||||
src="https://www.openstreetmap.org/export/embed.html?bbox=&layer=mapnik#map=14&query={{ (event.address ~ ', ' ~ event.zipcode ~ ' ' ~ event.city)|url_encode }}"
|
||||
></iframe>
|
||||
<div class="p-4 bg-gray-50 border-t-2 border-gray-200">
|
||||
<p class="text-sm font-bold text-gray-600">
|
||||
<svg class="w-4 h-4 inline-block mr-1 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
{{ event.address }}, {{ event.zipcode }} {{ event.city }}
|
||||
</p>
|
||||
<a href="https://www.openstreetmap.org/search?query={{ (event.address ~ ', ' ~ event.zipcode ~ ' ' ~ event.city)|url_encode }}" target="_blank" class="text-xs font-bold text-indigo-600 hover:underline mt-1 inline-block">Ouvrir dans OpenStreetMap</a>
|
||||
</div>
|
||||
<div id="event-map" class="w-full h-[300px]" data-address="{{ event.address }}, {{ event.zipcode }} {{ event.city }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user