srhinow/simple-map-bundle

simple maps width pins for Contao CMS based on OSM and Mapbox

Maintainers

Package info

gitlab.com/srhinow/simple-map-bundle

Issues

Type:contao-bundle

pkg:composer/srhinow/simple-map-bundle

Statistics

Installs: 641

Dependents: 0

Suggesters: 0

Stars: 0

5.4.1 2026-05-13 21:19 UTC

README

Interaktive Karten mit Markern für Contao CMS — zentral verwaltet im Backend, eingebunden per Inhaltselement oder Frontend-Modul. Basiert auf OpenStreetMap-Kacheln (oder optional Mapbox), der Leaflet-JavaScript-Bibliothek und der Nominatim-API für automatische Geocodierung.

Anforderungen

AbhängigkeitVersion
PHP≥ 8.3
Contao Core Bundle^5.3
league/csv^9.16
menatwork/contao-multicolumnwizard-bundle^3.6.8
ext-json*

Installation

composer require srhinow/simple-map-bundle

Nach der Installation die Datenbank-Migration ausführen:

php bin/console contao:migrate

Leaflet CSS/JS wird automatisch über $GLOBALS['TL_HEAD'] aus dem Bundle-Public-Verzeichnis (bundles/srhinowsimplemap/leaflet/) eingebunden — keine manuelle Asset-Konfiguration erforderlich.

Backend

Das Bundle fügt im Contao-Backend die Gruppe „OSM Maps" hinzu mit drei Verwaltungsbereichen:

1. Karten (tl_simple_map)

Jede Karte definiert Mittelpunkt, Zoom-Stufe, Kartenlayer (OSM oder Mapbox) und optionalen benutzerdefinierten Leaflet-Code. Marker werden als Kindeinträge zur Karte verwaltet.

Felder:

FeldBeschreibung
TitelEindeutige Bezeichnung der Karte (Pflichtfeld)
AliasURL-freundlicher Bezeichner (automatisch generiert)
Straße / Nr.Adresse des Kartenzentrums
PLZ / OrtAdresse des Kartenzentrums
SpracheLocale für die Adressauflösung (Standard: de)
Koordinaten auflösenCheckbox: löst mapLat/mapLon per Nominatim aus der Adresse auf
Pin erzeugenCheckbox: legt automatisch einen Marker aus der Kartenadresse an
Breitengrad / LängengradKartenmittelpunkt (DECIMAL(10,8) / DECIMAL(11,8))
ZoomInitiale Zoom-Stufe (Ganzzahl, typisch 5–18)
Leaflet-ScriptEigener JavaScript-Code, der nach der Karteninitialisierung ausgeführt wird (ACE-Editor, JS-Syntax). Erhält mymap und L als Parameter. Standard: mymap.scrollWheelZoom.disable();
Mapbox aktivierenCheckbox: wechselt den Tile-Layer von OSM auf Mapbox (klappt Unterpalette auf)
Mapbox API-KeyPflicht wenn Mapbox aktiv, eindeutig pro Installation
Mapbox-StyleStyle-Identifier, z. B. mapbox/streets-v12

2. Kategorien (tl_simple_map_category)

Optionale Kategorien für die Gruppierung von Markern in der Kategorielisten-Ansicht.

FeldBeschreibung
TitelEindeutiger Kategoriename (Pflichtfeld)
AliasAutomatisch generiert, alphanumerisch
SortierungNumerischer Sortierwert für die Reihenfolge in der Kategorieliste

3. Marker / Pins (tl_simple_map_pin)

Marker sind Kindeinträge einer Karte und werden in der Karten-Listenansicht über die Operation „Pins" aufgerufen. Die Listenansicht zeigt Titel, Straße, Nr., PLZ, Ort und Kategorie als Spalten.

Felder:

FeldBeschreibung
TitelBezeichnung des Markers (max. 255 Zeichen)
KategorieOptionale Zuweisung zu einer tl_simple_map_category
Straße / Nr.Adresse des Markers
PLZ / OrtAdresse des Markers
SpracheLocale für die Adressauflösung
Koordinaten auflösenCheckbox: löst mapLat/mapLon per Nominatim aus der Adresse auf
Breitengrad / LängengradMarker-Position (DECIMAL)
Popup-TextHTML-Inhalt des Leaflet-Popups (TinyMCE-Editor, Insert-Tags werden geparst)
Popup geöffnetCheckbox: Popup wird beim Laden der Karte sofort geöffnet
Online sichtbarVeröffentlichungs-Flag

CSV-Import

Marker können per CSV-Datei massenimportiert werden. Die Operation „CSV importieren" öffnet ein Import-Formular mit:

  • Auswahl einer CSV-Datei aus files/csv_imports/
  • Feldmapping per Multi-Column-Wizard: linke Spalte = CSV-Spaltenname, mittlere Spalte = Zielfeld in tl_simple_map_pin, rechte Spalte = fester Standardwert
  • Offset / Limit für seitenweisen Import großer Dateien
  • Optionaler Geocodierung aller importierten Marker nach dem Import

Verfügbare Import-Felder:
Alle Spalten der Tabelle tl_simple_map_pin außer id, pid, tstamp — die Optionsliste wird dynamisch aus dem Datenbankschema gelesen.

Frontend

Das Bundle stellt zwei Frontend-Typen bereit, die jeweils als Inhaltselement und als Frontend-Modul verfügbar sind:

simple_map_view — Kartenansicht

Rendert die interaktive Leaflet-Karte mit allen veröffentlichten Markern der ausgewählten Karte.

Backend-Einstellung: simpleMap — Dropdown zur Auswahl einer Karte aus tl_simple_map.

Funktionsweise:

  1. Lädt Kartenkonfiguration aus tl_simple_map
  2. Lädt alle veröffentlichten Pins (published=1) der Karte
  3. Parst Insert-Tags und ersetzt [nbsp] in popupText
  4. Normalisiert Koordinaten (Komma → Punkt, Fallback auf 0)
  5. Bindet Leaflet CSS/JS über $GLOBALS['TL_HEAD'] ein
  6. Schreibt Kartenkonfiguration als JSON in ein data-simple-map-Attribut
  7. Initialisiert die Karte per Inline-Script nach DOMContentLoaded

Templates:

  • Inhaltselement: contao/templates/content_element/simple_map_view.html.twig
  • Frontend-Modul: contao/templates/frontend_module/simple_map_view.html.twig

Template-Variablen:

VariableTypBeschreibung
errorbooltrue wenn Karte oder Pins nicht gefunden
msgstringFehlermeldung (aus TL_LANG['MSC'])
mapIdstringEindeutige HTML-ID des Karten-Containers (map{id})
maparrayKompletter tl_simple_map-Datensatz (alle Felder)
markerarrayArray von Pin-Datensätzen (alle Felder + normalisierte Koordinaten)

data-simple-map JSON-Struktur (automatisch vom Template erstellt):

{
  "lat": 52.5200,
  "lon": 13.4050,
  "zoom": 12,
  "doMapbox": false,
  "mapboxStyle": "",
  "mapboxApiKey": "",
  "customScript": "mymap.scrollWheelZoom.disable();",
  "marker": [
    {
      "lat": 52.5200,
      "lon": 13.4050,
      "popupText": "<b>Mein Ort</b>",
      "popupOpen": false
    }
  ]
}

simple_map_category_list — Kategorieliste

Zeigt die Popup-Texte aller Marker nach Kategorie gruppiert als Accordion-Liste — ohne Karte, als reine Textübersicht.

Backend-Einstellung: wie simple_map_viewsimpleMap-Dropdown.

Templates:

  • Inhaltselement: contao/templates/content_element/simple_map_category_list.html.twig
  • Frontend-Modul: contao/templates/frontend_module/simple_map_category_list.html.twig

Template-Variablen:

VariableTypBeschreibung
errorbooltrue wenn Karte oder Pins nicht gefunden
msgstringFehlermeldung
maparraytl_simple_map-Datensatz
categoriesarraySortiertes Array der Kategorien (nach sorting-Feld)
markerarrayAssoziatives Array: marker[categoryId][] = Pin-Datensätze

Jeder categories-Eintrag enthält alle Felder aus tl_simple_map_category (id, title, alias, sorting).

Templates anpassen

Alle Templates liegen unter contao/templates/. Für projektspezifische Anpassungen die gewünschte Datei in den Projekt-Templates-Ordner kopieren:

templates/
└── bz-niedersachsen/
    ├── content_element/
    │   ├── simple_map_view.html.twig
    │   └── simple_map_category_list.html.twig
    └── frontend_module/
        ├── simple_map_view.html.twig
        └── simple_map_category_list.html.twig

Leaflet-Custom-Script

Das Feld „Leaflet-Script" erlaubt beliebigen JavaScript-Code, der nach der Karteninitialisierung ausgeführt wird. Der Code wird in eine Funktion eingekapselt, die zwei Parameter erhält:

  • mymap — die Leaflet-Karten-Instanz
  • L — das globale Leaflet-Objekt

Beispiele:

// Scroll-Zoom deaktivieren (Standard)
mymap.scrollWheelZoom.disable();

// Karte auf Marker-Bounds zoomen
mymap.fitBounds(mymap.getBounds().pad(0.2));

// Eigenen Tile-Layer hinzufügen
L.tileLayer('https://...).addTo(mymap);

Fehler werden in der Browser-Konsole als Leaflet Custom Script Error: geloggt.

Geocodierung (Nominatim)

Die Koordinatenauflösung erfolgt über die OpenStreetMap Nominatim API (nominatim.openstreetmap.org/search). Sie wird ausgelöst durch:

  • Aktivieren der Checkbox „Koordinaten auflösen" beim Speichern einer Karte oder eines Markers
  • Automatisch bei neuen Markern ohne vorhandene Koordinaten
  • Optionaler Durchlauf nach dem CSV-Import

Der gesendete Such-String setzt sich zusammen aus: Straße Nr, PLZ Ort (je nach verfügbaren Feldern). Das Ergebnis setzt mapLat und mapLon im Datensatz.

Datenbankstruktur

tl_simple_map

SpalteTypBeschreibung
idint(10) unsignedPrimärschlüssel
tstampint(10) unsignedZeitstempel letzte Änderung
titlevarchar(255)Eindeutiger Kartentitel
aliasvarchar(64)URL-Alias
streetvarchar(128)Straße des Zentrums
nrvarchar(28)Hausnummer
postalvarchar(32)PLZ
cityvarchar(255)Ort
languagevarchar(5)Locale (Standard: de)
setNewGeochar(1)Geocodierungs-Trigger
setNewPinchar(1)Auto-Pin-Trigger
mapLatdecimal(10,8) NULLBreitengrad des Zentrums
mapLondecimal(11,8) NULLLängengrad des Zentrums
mapZoomint(10) unsignedZoom-Stufe (Standard: 5)
leafletCustomScripttextBenutzerdefinierter Leaflet-JS-Code
do_mapboxchar(1)Mapbox-Layer aktiviert
mapboxApiKeyvarchar(255)Mapbox API-Key
mapboxStylevarchar(255)Mapbox Style-ID (Standard: mapbox/streets-v12)

tl_simple_map_pin

SpalteTypBeschreibung
idint(10) unsignedPrimärschlüssel
pidint(10) unsignedEltern-Karte (tl_simple_map.id)
tstampint(10) unsignedZeitstempel
titlevarchar(255)Marker-Bezeichnung
categoryvarchar(64)Kategorie-ID (FK → tl_simple_map_category)
streetvarchar(128)Straße
nrvarchar(28)Hausnummer
postalvarchar(32)PLZ
cityvarchar(255)Ort
languagevarchar(5)Locale
setNewGeochar(1)Geocodierungs-Trigger
mapLatdecimal(10,8) NULLBreitengrad
mapLondecimal(11,8) NULLLängengrad
popupTextblob NULLPopup-Inhalt (HTML, Insert-Tags möglich)
popupOpenchar(1)Popup beim Laden geöffnet
publishedchar(1)Veröffentlicht
importCsvFilevarchar(255)Zuletzt verwendete CSV-Datei (Import)
importMatchMapPinFieldsblob NULLFeldmapping-Konfiguration (Multi-Column-Wizard)
importOffsetint(10) unsignedImport-Offset (Standard: 0)
importLimitint(10) unsignedImport-Limit (Standard: 50)

tl_simple_map_category

SpalteTypBeschreibung
idint(10) unsignedPrimärschlüssel
tstampint(10) unsignedZeitstempel
titlevarchar(255)Eindeutiger Kategorietitel
aliasvarchar(64)URL-Alias
sortingvarchar(255)Sortierungswert

Tests ausführen

Aus dem Haupt-Contao-Verzeichnis:

vendor/bin/phpunit -c vendor/srhinow/simple-map-bundle/phpunit.xml.dist

Aus dem Bundle-Root (wenn vendor/ vorhanden):

vendor/bin/phpunit

Lizenz

LGPL-3.0-or-later

Autor

Sven Rhinowsr-tag.de
Support: kservice@sr-tag.de
Quellcode: gitlab.com/srhinow/simple-map-bundle