erster brauchbarer stand.

This commit is contained in:
maik
2026-08-18 15:32:41 +02:00
commit 553247cdfb
460 changed files with 13751 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
{{ define "main" }}
<section class="op-detail-hero uk-section uk-section-large">
<div class="uk-container">
<p class="op-breadcrumb"><a href="{{ "/" | relLangURL }}">{{ i18n "home" }}</a></p>
<h1 class="uk-margin-small-top uk-margin-remove-bottom">{{ i18n "notFoundTitle" }}</h1>
<p class="uk-text-lead uk-margin-small-top">{{ i18n "notFoundText" }}</p>
<div class="uk-margin-top">
<a class="uk-button uk-button-primary" href="{{ "/" | relLangURL }}">{{ i18n "toMap" }}</a>
<a class="uk-button uk-button-default uk-margin-small-left" href="{{ "/schauplaetze/" | relLangURL }}">{{ i18n "allLocations" }}</a>
</div>
</div>
</section>
{{ end }}
+23
View File
@@ -0,0 +1,23 @@
<!doctype html>
<html lang="{{ site.Language.LanguageCode | default "de" }}">
<head>
{{ partial "head.html" . }}
</head>
<body{{ if eq .Section "erinnerungsorte" }} class="op-theme-blau"{{ end }}>
<!-- 1. SKIP-LINK -->
<a class="op-skip-link" href="#hauptinhalt">{{ i18n "skipLink" }}</a>
{{ partial "navbar.html" . }}
{{ partial "offcanvas.html" . }}
<main id="hauptinhalt">
{{ block "main" . }}{{ end }}
</main>
{{ partial "footer.html" . }}
{{ partial "scripts.html" . }}
</body>
</html>
+21
View File
@@ -0,0 +1,21 @@
{{ define "main" }}
<section class="uk-section">
<div class="uk-container">
<h1>{{ .Title }}</h1>
{{ with .Content }}<div class="uk-margin-medium">{{ . }}</div>{{ end }}
<div class="uk-child-width-1-2@s uk-child-width-1-3@l uk-grid-match uk-margin-medium-top" uk-grid>
{{ range .Pages }}
<div>
<div class="uk-card uk-card-default uk-card-body">
{{ with .Params.kategorie }}<span class="op-kategorie">{{ . }}</span>{{ end }}
{{ if not .Date.IsZero }}<p class="op-card-datum uk-margin-small-top uk-margin-remove-bottom">{{ time.Format "Mon, 2. Jan 2006" .Date }}</p>{{ end }}
<h2 class="uk-h5 op-card-titel uk-margin-small"><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
<p class="op-meta uk-margin-remove">{{ .Params.teaser | default .Summary }}</p>
</div>
</div>
{{ end }}
</div>
</div>
</section>
{{ end }}
+22
View File
@@ -0,0 +1,22 @@
{{ define "main" }}
<section class="op-detail-hero uk-section uk-section-small">
<div class="uk-container uk-container-small">
{{ with .Params.kategorie }}<span class="op-kategorie">{{ . }}</span>{{ end }}
<h1 class="uk-margin-remove-bottom">{{ .Title }}</h1>
{{ if or .Params.author (not .Date.IsZero) }}
<p class="op-meta uk-margin-small-top uk-margin-remove-bottom">
{{ with .Params.author }}von {{ . }}{{ if not $.Date.IsZero }} · {{ end }}{{ end }}
{{ if not .Date.IsZero }}{{ time.Format "2. Jan 2006" .Date }}{{ end }}
</p>
{{ end }}
</div>
</section>
<article class="uk-section">
<div class="uk-container uk-container-small">
{{ $img := .Resources.GetMatch "{cover,*featured*,image}.*" }}
{{ with $img }}<img class="uk-margin-bottom" src="{{ .RelPermalink }}" alt="">{{ end }}
{{ .Content }}
</div>
</article>
{{ end }}
+9
View File
@@ -0,0 +1,9 @@
{{ define "main" }}
<section class="op-detail-hero uk-section uk-section-small">
<div class="uk-container">
<p class="op-breadcrumb"><a href="{{ "/schauplaetze/" | relLangURL }}">{{ i18n "breadcrumbLocations" }}</a> &raquo; {{ partial "kat-label.html" .Title }}</p>
<h1 class="uk-margin-remove-top uk-margin-remove-bottom">{{ partial "kat-label.html" .Title }}</h1>
</div>
</section>
{{ partial "explorer.html" (dict "pages" .Pages) }}
{{ end }}
@@ -0,0 +1,10 @@
{{ define "main" }}
<section class="op-detail-hero op-hero-home uk-section uk-section-small">
<div class="uk-container uk-container-expand">
<h1 class="uk-margin-remove">{{ with .Params.heroTitle }}{{ . | safeHTML }}{{ else }}{{ .Title }}{{ end }}</h1>
{{ with .Params.heroLead }}<p class="uk-text-lead uk-margin-small-top uk-margin-remove-bottom uk-width-2-3@l">{{ . }}</p>{{ end }}
</div>
</section>
{{ partial "explorer.html" (dict "pages" .Pages "showFilter" false "markerColor" "#1e2758") }}
{{ end }}
@@ -0,0 +1,59 @@
{{ define "main" }}
<!-- Hero-Band -->
<section class="op-detail-hero uk-section uk-section-small">
<div class="uk-container">
<p class="op-breadcrumb">
<a href="{{ "/erinnerungsorte/" | relLangURL }}">{{ i18n "breadcrumbMemorials" }}</a>
</p>
<h1 class="uk-margin-small-top uk-margin-remove-bottom">{{ .Title }}</h1>
{{ with .Params.subtitle }}<p class="uk-text-lead uk-margin-small-top">{{ . }}</p>{{ end }}
</div>
</section>
<section class="uk-section">
<div class="uk-container">
<div class="uk-grid-large" uk-grid>
<!-- Inhalt -->
<div class="uk-width-2-3@m">
<div class="op-content-box">
{{ $img := .Resources.GetMatch "{cover,*featured*,image}.*" }}
{{ with $img }}<img class="uk-margin-small-bottom" src="{{ .RelPermalink }}" alt="{{ $.Title }}" loading="lazy">{{ end }}
{{ with .Params.bildnachweis }}<p class="op-bildnachweis uk-margin-bottom">{{ . | safeHTML }}</p>{{ end }}
{{ .Content }}
{{ with .Params.quelle }}
<p class="op-quelle-head">{{ i18n "externalSource" }}</p>
<p class="op-meta uk-margin-remove-top"><a href="{{ . }}" target="_blank" rel="noopener">{{ . }}</a></p>
{{ end }}
</div>
</div>
<!-- Sidebar -->
<div class="uk-width-1-3@m">
{{ if and .Params.lat .Params.lng }}
<div class="op-side-box">
{{ partial "karte.html" (dict "pages" (slice .) "klein" true "markerColor" "#1e2758") }}
<div class="op-side-box__pad">
{{ with .Params.address }}<p class="uk-margin-remove"><span uk-icon="icon: location"></span> {{ . }}</p>{{ end }}
<a class="op-directions" target="_blank" rel="noopener"
href="https://www.openstreetmap.org/?mlat={{ .Params.lat }}&mlon={{ .Params.lng }}#map=17/{{ .Params.lat }}/{{ .Params.lng }}">↳ {{ i18n "directions" }}</a>
</div>
</div>
{{ end }}
{{ if or .Params.art .Params.datum }}
<div class="op-side-box">
<div class="op-side-box__pad">
{{ with .Params.art }}<span class="op-kategorie op-kategorie--gelb">{{ . }}</span>{{ end }}
{{ with .Params.datum }}<p class="op-side-box__date uk-margin-small-top uk-margin-remove-bottom">{{ . }}</p>{{ end }}
</div>
</div>
{{ end }}
</div>
</div>
<p class="uk-margin-medium-top"><a class="uk-button uk-button-text" href="{{ "/erinnerungsorte/" | relLangURL }}">← {{ i18n "allMemorials" }}</a></p>
</div>
</section>
{{ end }}
+161
View File
@@ -0,0 +1,161 @@
{{ define "main" }}
<!-- HERO -->
<section class="op-section-gelb uk-section uk-section-large">
<div class="uk-container">
<div class="uk-grid-large uk-flex-middle" uk-grid>
<div class="uk-width-2-3@m">
<h1>{{ with .Params.heroTitle }}{{ . | safeHTML }}{{ else }}Wie erinnern wir <span class="op-marker">gemeinsam</span> an das, was nicht vergessen werden darf?{{ end }}</h1>
</div>
<div class="uk-width-1-3@m">
<div class="op-oeffnungsbox">
<h2 class="uk-h4 uk-margin-small-bottom">Öffnungszeiten</h2>
<ul class="uk-list uk-margin-small">
{{ range site.Params.openingHours }}
<li><strong>{{ .label }}</strong> · {{ .time }}</li>
{{ end }}
</ul>
{{ with site.Params.openingNote }}<p class="op-meta uk-margin-small">{{ . }}</p>{{ end }}
<a class="uk-button uk-button-primary" href="{{ site.Params.anfahrtURL | default "#" }}">Anfahrt</a>
</div>
</div>
</div>
</div>
<!-- Vollbreiter Wellen-Divider („Vorhang"-Motiv) -->
<svg class="op-divider uk-margin-large-top" viewBox="0 0 1200 46" preserveAspectRatio="none" aria-hidden="true" focusable="false">
<path d="M0,46 L0,20 C60,4 120,4 180,20 C240,36 300,36 360,20 C420,4 480,4 540,20 C600,36 660,36 720,20 C780,4 840,4 900,20 C960,36 1020,36 1080,20 C1140,4 1170,4 1200,20 L1200,46 Z" fill="#edf489"/>
</svg>
</section>
<!-- VERANSTALTUNGEN -->
{{ $veranstaltungen := where site.RegularPages "Section" "veranstaltungen" }}
{{ with $veranstaltungen }}
<section class="uk-section">
<div class="uk-container">
<h2>Veranstaltungen</h2>
<div class="uk-child-width-1-2@s uk-child-width-1-4@l uk-grid-match uk-margin-medium-top" uk-grid>
{{ range first 4 (sort . "Date" "asc") }}
<div>
<div class="uk-card uk-card-default uk-card-body">
{{ with .Params.kategorie }}<span class="op-kategorie">{{ . }}</span>{{ end }}
<p class="op-card-datum uk-margin-small-top uk-margin-remove-bottom">{{ time.Format "Mon, 2. Jan · 15:04 Uhr" .Date }}</p>
<h3 class="uk-h5 op-card-titel uk-margin-small"><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
<p class="op-meta uk-margin-remove">{{ .Params.teaser | default .Summary }}</p>
</div>
</div>
{{ end }}
</div>
<div class="uk-margin-medium-top">
<a class="uk-button uk-button-default" href="{{ "/veranstaltungen/" | relLangURL }}">Alle Veranstaltungen</a>
</div>
</div>
</section>
{{ end }}
<!-- LEITBILD -->
<section class="op-section-muted uk-section">
<div class="uk-container">
<div class="uk-grid-large uk-flex-middle" uk-grid>
<div class="uk-width-3-5@m">
<h2>{{ .Params.leitbildTitle | default "Unser Leitbild" }}</h2>
{{ with .Params.leitbildLead }}<p class="uk-text-lead">{{ . }}</p>{{ end }}
{{ .Content }}
{{ with .Params.leitbildMehrURL }}<a class="uk-button uk-button-text" href="{{ . }}">Mehr erfahren</a>{{ end }}
</div>
<div class="uk-width-2-5@m">
<!-- Bogen-Illustration (Formen-Asset) -->
<img class="op-bogen" src="{{ "images/formen/BogenGroup_nacht.svg" | relURL }}"
alt="" role="presentation" width="420" height="290">
</div>
</div>
</div>
</section>
<!-- NEUIGKEITEN -->
{{ $neuigkeiten := where site.RegularPages "Section" "neuigkeiten" }}
{{ with $neuigkeiten }}
<section class="uk-section">
<div class="uk-container">
<h2>Neuigkeiten</h2>
<div class="uk-child-width-1-3@m uk-grid-match uk-margin-medium-top" uk-grid>
{{ range first 3 . }}
<div>
<div class="uk-card uk-card-default">
<div class="uk-card-media-top">
{{ $img := .Resources.GetMatch "{cover,*featured*,image}.*" }}
{{ with $img }}
<img src="{{ .RelPermalink }}" alt="" loading="lazy">
{{ else }}
<div class="op-bild op-bild--16-9"><span class="op-bild__label">Bild 16:9</span></div>
{{ end }}
</div>
<div class="uk-card-body">
<h3 class="uk-h5 op-card-titel"><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
<p class="op-meta uk-margin-small">{{ with .Params.author }}von {{ . }} · {{ end }}{{ time.Format "2. Jan 2006" .Date }}</p>
<p class="uk-margin-remove">{{ .Params.teaser | default .Summary }}</p>
</div>
</div>
</div>
{{ end }}
</div>
<div class="uk-margin-medium-top">
<a class="uk-button uk-button-default" href="{{ "/neuigkeiten/" | relLangURL }}">Alle Neuigkeiten</a>
</div>
</div>
</section>
{{ end }}
<!-- BILDERGALERIE -->
<section class="op-section-muted uk-section">
<div class="uk-container">
<h2>Aus der Bildergalerie</h2>
</div>
<div class="uk-margin-medium-top uk-container uk-container-expand">
<div uk-slider="container-expand: true">
<div class="uk-position-relative">
<ul class="uk-slider-items uk-child-width-1-2 uk-child-width-1-3@m uk-grid">
{{ range seq (site.Params.galerieCount | default 6) }}
<li><div class="op-bild op-bild--4-3"><span class="op-bild__label">Galerie {{ . }}</span></div></li>
{{ end }}
</ul>
<a class="uk-position-center-left uk-position-small op-slidenav" href="#" uk-slidenav-previous uk-slider-item="previous" aria-label="Vorheriges Bild"></a>
<a class="uk-position-center-right uk-position-small op-slidenav" href="#" uk-slidenav-next uk-slider-item="next" aria-label="Nächstes Bild"></a>
</div>
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin-medium-top"></ul>
</div>
</div>
</section>
<!-- NEWSLETTER -->
<section class="op-section-gelb uk-section">
<div class="uk-container">
<div class="uk-grid-large uk-flex-middle" uk-grid>
<div class="uk-width-1-2@m">
<h2>Newsletter</h2>
<p class="uk-text-lead">{{ site.Params.newsletterText | default "Platzhaltersatz: Bleiben Sie über Veranstaltungen und Neuigkeiten auf dem Laufenden." }}</p>
</div>
<div class="uk-width-1-2@m">
<form action="{{ site.Params.newsletterAction | default "#" }}" method="post" novalidate>
<div class="uk-margin">
<label class="uk-form-label" for="op-newsletter-mail">E-Mail-Adresse</label>
<div class="uk-form-controls">
<input class="uk-input" id="op-newsletter-mail" type="email" name="email"
autocomplete="email" placeholder="name@beispiel.de" required>
</div>
</div>
<div class="uk-margin">
<label>
<input class="uk-checkbox" type="checkbox" name="datenschutz" required>
Ich habe die <a href="{{ site.Params.datenschutzURL | default "#" }}">Datenschutzerklärung</a> zur Kenntnis genommen und stimme der Verarbeitung meiner Daten zu.
</label>
</div>
<div class="uk-margin">
<button class="uk-button uk-button-primary" type="submit">Anmelden</button>
</div>
</form>
</div>
</div>
</div>
</section>
{{ end }}
@@ -0,0 +1,56 @@
{{/*
Split-View "Explorer": links Card-Liste mit Suche & Kategorie-Filter,
rechts sticky Karte. Aufruf: (dict "pages" <slice>)
*/}}
{{ $pages := sort .pages "Title" "asc" }}
{{ $cats := site.Data.kategorien | default dict }}
{{ $showFilter := true }}{{ if isset . "showFilter" }}{{ $showFilter = .showFilter }}{{ end }}
{{ $markerColor := .markerColor }}
<div class="op-split">
<div class="op-split__list">
<div class="op-listhead">
<div class="op-listhead__count" aria-live="polite"><span data-op-count>{{ len $pages }}</span>&nbsp;{{ i18n "results" }}</div>
<div class="op-search">
<input type="search" data-op-search placeholder="{{ i18n "searchPlaceholder" }}" aria-label="{{ i18n "searchAria" }}">
</div>
</div>
{{ if $showFilter }}
<details class="op-filter">
<summary class="op-filter__summary">
<span class="op-filter__label">{{ i18n "filterToggle" }}</span>
<span class="op-filter__state" data-op-filter-state
data-word-all="{{ i18n "wordAll" }}" data-word-of="{{ i18n "wordOf" }}"></span>
</summary>
<div class="op-filter__panel">
<div class="op-filter-actions">
<button type="button" class="op-filter-btn" data-op-filter-all>{{ i18n "filterSelectAll" }}</button>
<button type="button" class="op-filter-btn" data-op-filter-none>{{ i18n "filterDeselectAll" }}</button>
</div>
<div class="op-map-filter" data-op-map-filter role="group" aria-label="{{ i18n "filterGroupAria" }}">
{{ range $cat, $data := $cats }}
<label class="op-map-filter__item">
<input type="checkbox" value="{{ $cat }}" checked>
<span class="op-map-filter__swatch" style="background:{{ $data.color }}"></span>
{{ partial "kat-label.html" $cat }}
</label>
{{ end }}
</div>
</div>
</details>
{{ end }}
<div class="op-scards">
{{ range $pages }}
{{ partial "schauplatz-card.html" . }}
{{ end }}
</div>
</div>
<div class="op-split__map">
{{ partial "karte.html" (dict "pages" $pages) }}
</div>
</div>
+80
View File
@@ -0,0 +1,80 @@
<!-- FOOTER -->
<footer class="op-footer op-section-blau uk-section">
<div class="uk-container">
<!-- Spalten aus dem Hauptmenü (Einträge mit Unterpunkten) -->
<div class="uk-child-width-1-2@s uk-child-width-1-4@m uk-grid-large" uk-grid>
{{ range site.Menus.main }}
{{ if .HasChildren }}
<div>
<nav aria-label="Footer: {{ .Name }}">
<p class="op-footer-head">{{ .Name }}</p>
<ul class="uk-nav uk-nav-default">
{{ range .Children }}
<li><a href="{{ partial "menu-url.html" .URL }}">{{ .Name }}</a></li>
{{ end }}
</ul>
</nav>
</div>
{{ end }}
{{ end }}
</div>
<hr class="uk-margin-large">
<div class="uk-grid-large uk-flex-middle" uk-grid>
<div class="uk-width-auto">
<a class="op-logo" href="{{ site.Home.RelPermalink }}" aria-label="{{ site.Title }} Startseite">
<img class="op-logo__img" src="{{ "images/logos/Logo_OP_DZ_negativ.png" | relURL }}"
alt="{{ site.Title }}" height="40">
</a>
</div>
<div class="uk-width-expand@s">
<address style="font-style:normal;">
{{ with site.Params.address }}
{{ with .street }}{{ . }}<br>{{ end }}
{{ with .city }}{{ . }}<br>{{ end }}
{{ end }}
{{ with site.Params.email }}<a href="mailto:{{ . }}">{{ . }}</a>{{ end }}
{{ with site.Params.phone }} · {{ . }}{{ end }}
</address>
</div>
{{ with site.Params.instagramURL }}
<div class="uk-width-auto">
<a href="{{ . }}" target="_blank" rel="noopener" aria-label="Instagram: Offener Prozess" uk-icon="icon: instagram; ratio: 1.3"></a>
</div>
{{ end }}
{{ with site.Menus.meta }}
<div class="uk-width-auto">
<nav aria-label="Weitere Links">
<ul class="uk-subnav uk-margin-remove">
{{ range . }}<li><a href="{{ partial "menu-url.html" .URL }}"{{ if hasPrefix .URL "http" }} target="_blank" rel="noopener"{{ end }}>{{ .Name }}</a></li>{{ end }}
</ul>
</nav>
</div>
{{ end }}
</div>
{{ with site.Params.foerderLogo }}
<div class="op-foerder op-foerder--logo uk-margin-large-top">
<img src="{{ . | relURL }}" alt="Gefördert durch den Freistaat Sachsen Sächsisches Staatsministerium für Soziales, Gesundheit und gesellschaftlichen Zusammenhalt; Weltoffenes Sachsen" loading="lazy">
</div>
{{ else }}
<div class="op-foerder uk-margin-large-top">
{{ site.Params.foerderHinweis | default "Platzhalterfläche für Förderlogos" }}
</div>
{{ end }}
<hr class="uk-margin-large">
<div class="uk-flex uk-flex-between uk-flex-wrap uk-text-small">
<span>© {{ now.Year }} {{ site.Title }}</span>
{{ with site.Menus.legal }}
<nav aria-label="Rechtliches">
{{ range $i, $e := . }}{{ if $i }} · {{ end }}<a href="{{ partial "menu-url.html" $e.URL }}">{{ $e.Name }}</a>{{ end }}
</nav>
{{ end }}
</div>
</div>
</footer>
+32
View File
@@ -0,0 +1,32 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ .Title }} {{ site.Title }}{{ end }}</title>
{{/* Startseite zeigt denselben Karten-Explorer wie /schauplaetze/ → dort ist die kanonische URL */}}
{{ if .IsHome }}<link rel="canonical" href="{{ "/schauplaetze/" | absLangURL }}">{{ end }}
{{ with .Description | default site.Params.description }}<meta name="description" content="{{ . }}">{{ end }}
{{/* hreflang-Alternates für Sprachversionen */}}
{{ range .AllTranslations }}
<link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
{{ end }}
{{/* UIkit 3 lokal gehostet (DSGVO: keine Third-Party-Requests) */}}
<link rel="stylesheet" href="{{ "vendor/uikit/css/uikit.min.css" | relURL }}">
<script defer src="{{ "vendor/uikit/js/uikit.min.js" | relURL }}"></script>
<script defer src="{{ "vendor/uikit/js/uikit-icons.min.js" | relURL }}"></script>
{{/* Theme-CSS: Fonts + Styles gebündelt, minifiziert, fingerprinted */}}
{{ $fonts := resources.Get "css/fonts.css" }}
{{ $main := resources.Get "css/main.css" }}
{{ $css := slice $fonts $main | resources.Concat "css/theme.css" }}
{{ if hugo.IsProduction }}{{ $css = $css | minify | fingerprint }}{{ end }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}"{{ with $css.Data.Integrity }} integrity="{{ . }}"{{ end }}>
{{/* Leaflet-CSS nur auf Karten-Seiten (Home + Schauplätze) */}}
{{ if or .IsHome (eq .Type "schauplaetze") (eq .Type "kategorien") (eq .Type "erinnerungsorte") }}
<link rel="stylesheet" href="{{ "vendor/leaflet/leaflet.css" | relURL }}">
<link rel="stylesheet" href="{{ "vendor/markercluster/MarkerCluster.css" | relURL }}">
<link rel="stylesheet" href="{{ "vendor/markercluster/MarkerCluster.Default.css" | relURL }}">
{{ end }}
{{ block "head" . }}{{ end }}
+45
View File
@@ -0,0 +1,45 @@
{{/*
Karten-Partial. Aufruf mit dict:
(dict "pages" <slice von Schauplatz-Seiten> "klein" false)
Baut den Leaflet-Container und bettet die Marker-Daten als JSON ein
(kein externer Request → CORS-frei, statisch). Der Filter kommt aus explorer.html.
*/}}
{{ $pages := .pages }}
{{ $klein := .klein }}
{{ $default := .markerColor | default site.Params.kategorieFarbeDefault | default "#1e2758" }}
{{/* Farb-Map (Kategorie → Hex) für map.js aus data/kategorien.yaml */}}
{{ $colorMap := dict }}
{{ range $k, $v := site.Data.kategorien }}{{ $colorMap = merge $colorMap (dict $k $v.color) }}{{ end }}
{{/* Marker-Daten aufbauen */}}
{{ $places := slice }}
{{ range $pages }}
{{ $img := "" }}
{{ with .Resources.GetMatch "{cover,*featured*,image}.*" }}{{ $img = .RelPermalink }}
{{ else }}{{ with .Params.image }}{{ $img = . | relURL }}{{ end }}{{ end }}
{{ if and .Params.lat .Params.lng }}
{{ $places = $places | append (dict
"title" .Title
"subtitle" (.Params.subtitle | default "")
"url" .RelPermalink
"lat" .Params.lat
"lng" .Params.lng
"categories" (.Params.kategorien | default slice)
"img" $img
) }}
{{ end }}
{{ end }}
{{ $payload := dict
"places" $places
"colors" $colorMap
"defaultColor" $default
"tileUrl" (site.Params.map.tileURL | default "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
"attribution" (site.Params.map.attribution | default `&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>-Mitwirkende`)
}}
<div id="op-map" class="op-map{{ if $klein }} op-map--klein{{ end }}"
role="application" aria-label="{{ i18n "mapAria" }}"></div>
<script type="application/json" id="op-map-data">{{ $payload | jsonify | safeJS }}</script>
@@ -0,0 +1,4 @@
{{- /* Gibt die Markerfarbe für eine Kategorie (String als Kontext) zurück */ -}}
{{- $c := site.Params.kategorieFarbeDefault | default "#1e2758" -}}
{{- with index site.Data.kategorien . -}}{{- with .color -}}{{- $c = . -}}{{- end -}}{{- end -}}
{{- $c -}}
@@ -0,0 +1,6 @@
{{- /* Gibt das lokalisierte Anzeige-Label für eine Kategorie (String als Kontext) zurück */ -}}
{{- $lbl := . -}}
{{- if eq site.Language.Lang "en" -}}
{{- with index site.Data.kategorien . -}}{{- with .en -}}{{- $lbl = . -}}{{- end -}}{{- end -}}
{{- end -}}
{{- $lbl -}}
@@ -0,0 +1,46 @@
{{- /* Sprachumschalter. Aufruf: (dict "page" . "variant" "dropdown"|"list") */ -}}
{{ $cur := .page }}
{{ $variant := .variant | default "dropdown" }}
{{ if eq $variant "list" }}
{{/* Einfache Liste (mobiles Offcanvas) */}}
<nav class="op-langswitch op-langswitch--list" aria-label="Sprache / Language">
{{ range site.Sites }}
{{ $s := . }}
{{ $link := $s.Home.RelPermalink }}
{{ range $cur.AllTranslations }}{{ if eq .Language.Lang $s.Language.Lang }}{{ $link = .RelPermalink }}{{ end }}{{ end }}
{{ $isCurrent := eq $s.Language.Lang site.Language.Lang }}
<a class="op-langswitch__item{{ if $isCurrent }} is-current{{ end }}" href="{{ $link }}"
hreflang="{{ $s.Language.Lang }}" lang="{{ $s.Language.Lang }}"{{ if $isCurrent }} aria-current="true"{{ end }}>
<span class="op-langswitch__flag" aria-hidden="true">{{ $s.Language.Params.flag }}</span>
<span class="op-langswitch__name">{{ $s.Language.LanguageName }}</span>
</a>
{{ end }}
</nav>
{{ else }}
{{/* Dropdown (Navbar) */}}
<div class="op-langswitch">
<button class="op-langswitch__toggle" type="button" aria-haspopup="true"
aria-label="{{ site.Language.LanguageName }} Sprache wählen / choose language">
<span class="op-langswitch__flag" aria-hidden="true">{{ site.Language.Params.flag }}</span>
<span class="op-langswitch__code">{{ upper site.Language.Lang }}</span>
<span class="op-langswitch__caret" aria-hidden="true"></span>
</button>
<div class="op-langswitch__drop" uk-dropdown="mode: click; pos: bottom-right; offset: 4; boundary: .op-navbar">
<ul class="uk-nav uk-dropdown-nav">
{{ range site.Sites }}
{{ $s := . }}
{{ $link := $s.Home.RelPermalink }}
{{ range $cur.AllTranslations }}{{ if eq .Language.Lang $s.Language.Lang }}{{ $link = .RelPermalink }}{{ end }}{{ end }}
{{ $isCurrent := eq $s.Language.Lang site.Language.Lang }}
<li class="{{ if $isCurrent }}uk-active{{ end }}">
<a href="{{ $link }}" hreflang="{{ $s.Language.Lang }}" lang="{{ $s.Language.Lang }}"{{ if $isCurrent }} aria-current="true"{{ end }}>
<span class="op-langswitch__flag" aria-hidden="true">{{ $s.Language.Params.flag }}</span>
<span class="op-langswitch__name">{{ $s.Language.LanguageName }}</span>
</a>
</li>
{{ end }}
</ul>
</div>
</div>
{{ end }}
@@ -0,0 +1,4 @@
{{- /* Interne Menü-URLs (beginnen mit /) bekommen das Sprach-Präfix; externe bleiben unverändert */ -}}
{{- $u := . -}}
{{- if hasPrefix $u "/" -}}{{- $u = $u | relLangURL -}}{{- end -}}
{{- $u -}}
+51
View File
@@ -0,0 +1,51 @@
<!-- STICKY NAVBAR -->
<header>
<div uk-sticky="animation: uk-animation-slide-top; sel-target: .op-navbar; cls-active: uk-navbar-sticky">
<nav class="op-navbar uk-navbar-container" aria-label="Hauptnavigation">
<div class="uk-container uk-container-expand">
<div uk-navbar="mode: click; dropbar: false">
<!-- Logo -->
<div class="uk-navbar-left">
<a class="op-logo uk-navbar-item uk-logo" href="{{ site.Home.RelPermalink }}" aria-label="{{ site.Title }}">
<img class="op-logo__img" src="{{ "images/logos/Logo_OP_DZ_blau.svg" | relURL }}"
alt="{{ site.Title }}" width="115" height="44">
</a>
</div>
<!-- Desktop-Navigation -->
<div class="uk-navbar-right uk-visible@m">
<ul class="uk-navbar-nav">
{{ range site.Menus.main }}
{{ if .HasChildren }}
<li class="{{ if $.IsMenuCurrent "main" . }}uk-active{{ end }}">
<a href="{{ partial "menu-url.html" .URL }}" aria-haspopup="true">{{ .Name }} <span uk-navbar-parent-icon></span></a>
<div class="uk-navbar-dropdown">
<ul class="uk-nav uk-navbar-dropdown-nav">
{{ range .Children }}
<li><a href="{{ partial "menu-url.html" .URL }}">{{ .Name }}</a></li>
{{ end }}
</ul>
</div>
</li>
{{ else }}
<li class="{{ if $.IsMenuCurrent "main" . }}uk-active{{ end }}">
<a href="{{ partial "menu-url.html" .URL }}"{{ if $.IsMenuCurrent "main" . }} aria-current="page"{{ end }}>{{ .Name }}</a>
</li>
{{ end }}
{{ end }}
</ul>
<div class="uk-navbar-item">{{ partial "language-switcher.html" (dict "page" . "variant" "dropdown") }}</div>
</div>
<!-- Mobile-Toggle -->
<div class="uk-navbar-right uk-hidden@m">
<a class="uk-navbar-toggle" href="#op-offcanvas" uk-toggle
uk-navbar-toggle-icon aria-label="Menü öffnen"></a>
</div>
</div>
</div>
</nav>
</div>
</header>
@@ -0,0 +1,27 @@
<!-- OFFCANVAS (mobil) -->
<div id="op-offcanvas" uk-offcanvas="overlay: true; flip: true">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close" type="button" uk-close aria-label="Menü schließen"></button>
<nav aria-label="Mobile Navigation">
<ul class="uk-nav uk-nav-primary uk-nav-parent-icon" uk-nav>
{{ range site.Menus.main }}
{{ if .HasChildren }}
<li class="uk-parent">
<a href="{{ partial "menu-url.html" .URL }}">{{ .Name }}</a>
<ul class="uk-nav-sub">
{{ range .Children }}
<li><a href="{{ partial "menu-url.html" .URL }}">{{ .Name }}</a></li>
{{ end }}
</ul>
</li>
{{ else }}
<li class="{{ if $.IsMenuCurrent "main" . }}uk-active{{ end }}">
<a href="{{ partial "menu-url.html" .URL }}"{{ if $.IsMenuCurrent "main" . }} aria-current="page"{{ end }}>{{ .Name }}</a>
</li>
{{ end }}
{{ end }}
</ul>
<div class="op-offcanvas-lang uk-margin-top">{{ partial "language-switcher.html" (dict "page" . "variant" "list") }}</div>
</nav>
</div>
</div>
@@ -0,0 +1,41 @@
{{/* Erwartet eine Schauplatz-Seite als Kontext (.) */}}
{{ $default := site.Params.kategorieFarbeDefault | default "#1e2758" }}
{{ $cat := "" }}
{{ with .Params.kategorien }}{{ $cat = index . 0 }}{{ end }}
{{ $color := $default }}
{{ with $cat }}{{ $color = partial "kat-color.html" . }}{{ end }}
{{ $img := "" }}
{{ with .Resources.GetMatch "{cover,*featured*,image}.*" }}{{ $img = .RelPermalink }}
{{ else }}{{ with .Params.image }}{{ $img = . | relURL }}{{ end }}{{ end }}
<a class="op-scard" data-op-card
href="{{ .RelPermalink }}"
data-url="{{ .RelPermalink }}"
data-text="{{ .Title }} {{ .Params.subtitle }} {{ .Params.address }}"
data-cats="{{ delimit (.Params.kategorien | default slice) `|` }}">
{{ if $img }}
<span class="op-scard__img">
<img class="op-scard__photo" src="{{ $img }}" alt="" loading="lazy">
{{ if .Params.featured }}<span class="op-scard__tipp">Tipp!</span>{{ end }}
</span>
{{ else }}
<span class="op-scard__img op-scard__img--ph" style="color:{{ $color }}">
<svg class="op-scard__bogen" viewBox="0 0 210 105" aria-hidden="true" focusable="false">
<path d="M0,105 A105,105 0 0 1 210,105" fill="none" stroke="currentColor" stroke-width="14" opacity=".55"/>
<path d="M40,105 A65,65 0 0 1 170,105" fill="none" stroke="currentColor" stroke-width="14" opacity=".28"/>
</svg>
{{ if .Params.featured }}<span class="op-scard__tipp">Tipp!</span>{{ end }}
</span>
{{ end }}
<span class="op-scard__body">
{{ if $cat }}<span class="op-scard__cat">{{ partial "kat-label.html" $cat }}</span>
{{ else }}{{ with .Params.art }}<span class="op-scard__cat">{{ . }}</span>{{ end }}{{ end }}
<span class="op-scard__title">{{ .Title }}</span>
{{ with .Params.subtitle }}<span class="op-scard__sub">{{ . }}</span>{{ end }}
{{ with .Params.address }}
<span class="op-scard__addr">
<span class="op-scard__dot" style="background:{{ $color }}"></span>
<span>{{ . }}</span>
</span>
{{ end }}
</span>
</a>
@@ -0,0 +1,8 @@
{{/* Karten-JS nur auf Karten-Seiten (Home + Schauplätze) laden */}}
{{ if or .IsHome (eq .Type "schauplaetze") (eq .Type "kategorien") (eq .Type "erinnerungsorte") }}
<script src="{{ "vendor/leaflet/leaflet.js" | relURL }}"></script>
<script src="{{ "vendor/markercluster/leaflet.markercluster.js" | relURL }}"></script>
{{ $map := resources.Get "js/map.js" }}
{{ if hugo.IsProduction }}{{ $map = $map | minify | fingerprint }}{{ end }}
<script src="{{ $map.RelPermalink }}"{{ with $map.Data.Integrity }} integrity="{{ . }}"{{ end }}></script>
{{ end }}
@@ -0,0 +1,16 @@
<!-- SUCH-MODAL (vollflächig) -->
<div id="op-suche" class="uk-modal-full" uk-modal>
<div class="uk-modal-dialog uk-flex uk-flex-center uk-flex-middle" style="min-height:100vh;" uk-height-viewport>
<button class="uk-modal-close-full uk-close-large" type="button" uk-close aria-label="Suche schließen"></button>
<div class="uk-width-2-3@m uk-text-center">
<form action="{{ site.Home.RelPermalink }}" method="get" role="search" aria-label="Schauplätze durchsuchen">
<label class="uk-form-label uk-margin-small-bottom uk-display-block" for="op-suchfeld">Schauplätze durchsuchen</label>
<div class="uk-search uk-search-large uk-width-1-1">
<span uk-search-icon></span>
<input id="op-suchfeld" class="uk-search-input" type="search" name="q" placeholder="Nach Titel, Person oder Ort suchen …" aria-label="Suchbegriff">
</div>
<p class="uk-text-meta uk-margin-small-top">Enter drücken die Karte zeigt dann die passenden Schauplätze.</p>
</form>
</div>
</div>
</div>
+18
View File
@@ -0,0 +1,18 @@
<!-- TOPBAR (nur ab @m) -->
{{ with site.Params.languages }}
<div class="op-topbar uk-visible@m">
<div class="uk-container uk-container-expand">
<div class="uk-flex uk-flex-right uk-flex-middle" style="min-height:44px;">
<nav aria-label="Sprachauswahl">
<ul class="uk-subnav uk-margin-remove">
{{ range . }}
<li{{ if .active }} class="uk-active"{{ end }}>
<a href="{{ .url | default "#" }}" lang="{{ .lang }}"{{ if .active }} aria-current="true"{{ end }}>{{ .name }}</a>
</li>
{{ end }}
</ul>
</nav>
</div>
</div>
</div>
{{ end }}
@@ -0,0 +1,11 @@
{{ define "main" }}
<section class="op-detail-hero op-hero-home uk-section uk-section-small">
<div class="uk-container uk-container-expand">
{{/* Hero-Texte kommen aus content/_index.md, damit / und /schauplaetze/ identisch bleiben */}}
<h1 class="uk-margin-remove">{{ with site.Home.Params.heroTitle }}{{ . | safeHTML }}{{ else }}{{ $.Title }}{{ end }}</h1>
{{ with site.Home.Params.heroLead }}<p class="uk-text-lead uk-margin-small-top uk-margin-remove-bottom uk-width-2-3@l">{{ . }}</p>{{ end }}
</div>
</section>
{{ partial "explorer.html" (dict "pages" .Pages) }}
{{ end }}
@@ -0,0 +1,65 @@
{{ define "main" }}
{{ $cats := .Params.kategorien | default slice }}
{{ $cat := index $cats 0 }}
<!-- Hero-Band -->
<section class="op-detail-hero uk-section uk-section-small">
<div class="uk-container">
<p class="op-breadcrumb">
<a href="{{ "/schauplaetze/" | relLangURL }}">{{ i18n "breadcrumbLocations" }}</a>
{{ with $cat }} &raquo; <a href="{{ (printf "/kategorien/%s/" (urlize .)) | relLangURL }}">{{ partial "kat-label.html" . }}</a>{{ end }}
</p>
<h1 class="uk-margin-small-top uk-margin-remove-bottom">{{ .Title }}</h1>
{{ with .Params.subtitle }}<p class="uk-text-lead uk-margin-small-top">{{ . }}</p>{{ end }}
</div>
</section>
<section class="uk-section">
<div class="uk-container">
<div class="uk-grid-large" uk-grid>
<!-- Inhalt -->
<div class="uk-width-2-3@m">
<div class="op-content-box">
{{ $img := .Resources.GetMatch "{cover,*featured*,image}.*" }}
{{ with $img }}<img class="uk-margin-small-bottom" src="{{ .RelPermalink }}" alt="{{ $.Title }}" loading="lazy">{{ end }}
{{ with .Params.bildnachweis }}<p class="op-bildnachweis uk-margin-bottom">{{ . | safeHTML }}</p>{{ end }}
{{ .Content }}
{{ with .Params.quelle }}
<p class="op-quelle-head">{{ i18n "externalSource" }}</p>
<p class="op-meta uk-margin-remove-top">{{ . | safeHTML }}</p>
{{ end }}
</div>
</div>
<!-- Sidebar -->
<div class="uk-width-1-3@m">
{{ if and .Params.lat .Params.lng }}
<div class="op-side-box">
{{ partial "karte.html" (dict "pages" (slice .) "klein" true) }}
<div class="op-side-box__pad">
{{ with .Params.address }}<p class="uk-margin-remove"><span uk-icon="icon: location"></span> {{ . }}</p>{{ end }}
<a class="op-directions" target="_blank" rel="noopener"
href="https://www.openstreetmap.org/?mlat={{ .Params.lat }}&mlon={{ .Params.lng }}#map=17/{{ .Params.lat }}/{{ .Params.lng }}">↳ {{ i18n "directions" }}</a>
</div>
</div>
{{ end }}
{{ if or $cats .Params.datum }}
<div class="op-side-box">
<div class="op-side-box__pad">
{{ range $cats }}
<span class="op-kategorie" style="background:{{ partial "kat-color.html" . }};color:#fff">{{ partial "kat-label.html" . }}</span>
{{ end }}
{{ with .Params.datum }}<p class="op-side-box__date uk-margin-small-top uk-margin-remove-bottom">{{ . }}</p>{{ end }}
</div>
</div>
{{ end }}
</div>
</div>
<p class="uk-margin-medium-top"><a class="uk-button uk-button-text" href="{{ "/schauplaetze/" | relLangURL }}">← {{ i18n "allLocations" }}</a></p>
</div>
</section>
{{ end }}