mirror of
https://github.com/Theodor-Springmann-Stiftung/lenz-web.git
synced 2025-10-28 16:55:32 +00:00
Next/Prev stuff
This commit is contained in:
@@ -19,9 +19,10 @@ func GetLetter(c *fiber.Ctx) error {
|
|||||||
if meta == nil {
|
if meta == nil {
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
np := lib.NextPrev(meta)
|
||||||
|
|
||||||
text := lib.Letters.Item(letter)
|
text := lib.Letters.Item(letter)
|
||||||
tradition := lib.Traditions.Item(letter)
|
tradition := lib.Traditions.Item(letter)
|
||||||
|
|
||||||
return c.Render("/brief/", map[string]any{"meta": meta, "text": text, "tradition": tradition})
|
return c.Render("/brief/", map[string]any{"meta": meta, "text": text, "tradition": tradition, "next": np.Next, "prev": np.Prev})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
const DEFAULT_YEAR = 1765
|
const DEFAULT_YEAR = 1765
|
||||||
|
|
||||||
func GetIndex(c *fiber.Ctx) error {
|
func GetIndex(c *fiber.Ctx) error {
|
||||||
return c.Redirect("/" + strconv.Itoa(DEFAULT_YEAR))
|
return c.Redirect(JAHRGAENGE_URL + "/" + strconv.Itoa(DEFAULT_YEAR))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetIndexYear(c *fiber.Ctx) error {
|
func GetIndexYear(c *fiber.Ctx) error {
|
||||||
@@ -23,5 +23,5 @@ func GetIndexYear(c *fiber.Ctx) error {
|
|||||||
return c.SendStatus(fiber.StatusNotFound)
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Render("/", map[string]any{"years": years, "yearmap": yearmap, "year": year, "all": y == "all"})
|
return c.Render(JAHRGAENGE_URL+"/", map[string]any{"years": years, "yearmap": yearmap, "year": year, "all": y == "all"})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,20 @@ import (
|
|||||||
"github.com/gofiber/fiber/v2/middleware/compress"
|
"github.com/gofiber/fiber/v2/middleware/compress"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ASSETS_URL = "/assets"
|
|
||||||
const INDEX_URL = "/"
|
const INDEX_URL = "/"
|
||||||
|
const ASSETS_URL = "/assets"
|
||||||
|
const DATENSCHUTZ_URL = "/datenschutz"
|
||||||
|
const JAHRGAENGE_URL = "/jahrgang"
|
||||||
|
const ZITATION_URL = "/ausgabe/zitation"
|
||||||
|
const EDITION_URL = "/ausgabe/edition"
|
||||||
|
const KONTAKT_URL = "/kontakt"
|
||||||
|
|
||||||
|
var INDEX_YEAR_URL = JAHRGAENGE_URL + "/:" + YEAR_PARAM
|
||||||
|
var LETTER_URL = "/brief/:" + LETTER_PARAM
|
||||||
|
|
||||||
const YEAR_PARAM = "year"
|
const YEAR_PARAM = "year"
|
||||||
const LETTER_PARAM = "letter"
|
const LETTER_PARAM = "letter"
|
||||||
|
|
||||||
var INDEX_YEAR_URL = "/:" + YEAR_PARAM
|
|
||||||
var LETTER_URL = "/brief/:" + LETTER_PARAM
|
|
||||||
|
|
||||||
func Register(server server.Server, cfg config.Config) {
|
func Register(server server.Server, cfg config.Config) {
|
||||||
server.Server.Use(ASSETS_URL, compress.New(compress.Config{
|
server.Server.Use(ASSETS_URL, compress.New(compress.Config{
|
||||||
Level: compress.LevelBestSpeed,
|
Level: compress.LevelBestSpeed,
|
||||||
@@ -25,6 +31,7 @@ func Register(server server.Server, cfg config.Config) {
|
|||||||
server.Server.Get(INDEX_URL, GetIndex)
|
server.Server.Get(INDEX_URL, GetIndex)
|
||||||
server.Server.Get(INDEX_YEAR_URL, GetIndexYear)
|
server.Server.Get(INDEX_YEAR_URL, GetIndexYear)
|
||||||
server.Server.Get(LETTER_URL, GetLetter)
|
server.Server.Get(LETTER_URL, GetLetter)
|
||||||
|
server.Server.Get(DATENSCHUTZ_URL, Static(DATENSCHUTZ_URL+"/"))
|
||||||
|
|
||||||
// INFO: we map the webhook when a secret was provided
|
// INFO: we map the webhook when a secret was provided
|
||||||
if cfg.WebHookSecret != "" {
|
if cfg.WebHookSecret != "" {
|
||||||
|
|||||||
16
controllers/static.go
Normal file
16
controllers/static.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Static(url string) fiber.Handler {
|
||||||
|
if !strings.HasSuffix(url, "/") {
|
||||||
|
url += "/"
|
||||||
|
}
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
return c.Render(url, map[string]any{})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,8 @@ func New(engine *templating.Engine, storage fiber.Storage, debug bool) Server {
|
|||||||
EnablePrintRoutes: debug,
|
EnablePrintRoutes: debug,
|
||||||
ViewsLayout: templating.DEFAULT_LAYOUT_NAME,
|
ViewsLayout: templating.DEFAULT_LAYOUT_NAME,
|
||||||
UnescapePath: true,
|
UnescapePath: true,
|
||||||
|
// BUG: does not work rn:
|
||||||
|
PassLocalsToViews: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
|
|||||||
BIN
stuff/favicon.png
Normal file
BIN
stuff/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
stuff/logollenz.png
Normal file
BIN
stuff/logollenz.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
stuff/logollenz.xcf
Normal file
BIN
stuff/logollenz.xcf
Normal file
Binary file not shown.
@@ -188,6 +188,7 @@ func (e *Engine) AddFuncs(funcs template.FuncMap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) Render(out io.Writer, path string, data any, layout ...string) error {
|
func (e *Engine) Render(out io.Writer, path string, data any, layout ...string) error {
|
||||||
|
slog.Debug("Rendering template", "path", path, "layout", layout, "data", data)
|
||||||
e.mu.RLock()
|
e.mu.RLock()
|
||||||
ld := data.(map[string]any)
|
ld := data.(map[string]any)
|
||||||
if e.GlobalData != nil {
|
if e.GlobalData != nil {
|
||||||
@@ -195,6 +196,10 @@ func (e *Engine) Render(out io.Writer, path string, data any, layout ...string)
|
|||||||
}
|
}
|
||||||
e.mu.RUnlock()
|
e.mu.RUnlock()
|
||||||
|
|
||||||
|
if e.debug {
|
||||||
|
slog.Debug("Rendering template", "path", path, "layout", layout, "data", ld)
|
||||||
|
}
|
||||||
|
|
||||||
e.regmu.RLock()
|
e.regmu.RLock()
|
||||||
defer e.regmu.RUnlock()
|
defer e.regmu.RUnlock()
|
||||||
var l *template.Template
|
var l *template.Template
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,53 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html class="w-full h-full" {{ if .lang }}lang="{{ .lang }}"{{ end }}>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta
|
|
||||||
name="htmx-config"
|
|
||||||
content='{"defaultSwapStyle":"outerHTML", "scrollBehavior": "instant"}' />
|
|
||||||
|
|
||||||
{{ block "head" . }}
|
|
||||||
<!-- Default Head elements -->
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if .isDev }}
|
|
||||||
<link rel="icon" href="/assets/logo/dev_favicon.png" />
|
|
||||||
<meta name="robots" content="noindex" />
|
|
||||||
{{ else }}
|
|
||||||
{{ if .url }}
|
|
||||||
<link rel="canonical" href="{{ .url }}" />
|
|
||||||
{{ end }}
|
|
||||||
<link rel="icon" href="/assets/logo/favicon.png" />
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
|
|
||||||
<script src="/assets/js/alpine.min.js" defer></script>
|
|
||||||
<script src="/assets/js/htmx.min.js" defer></script>
|
|
||||||
<script src="/assets/js/htmx-response-targets.js" defer></script>
|
|
||||||
<script src="/assets/js/mark.min.js" defer></script>
|
|
||||||
|
|
||||||
<script type="module" src="/assets/scripts.js"></script>
|
|
||||||
<link href="/assets/css/remixicon.css" rel="stylesheet" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/assets/css/fonts.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/assets/style.css" />
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
document.body.addEventListener("htmx:responseError", function (event) {
|
|
||||||
const config = event.detail.requestConfig;
|
|
||||||
if (config.boosted) {
|
|
||||||
document.body.innerHTML = event.detail.xhr.responseText;
|
|
||||||
const newUrl = event.detail.xhr.responseURL || config.url;
|
|
||||||
window.history.pushState(null, "", newUrl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="w-full min-h-full" hx-ext="response-targets" hx-boost="true">
|
|
||||||
<div class="pb-12">
|
|
||||||
{{ block "body" . }}
|
|
||||||
<!-- Default app body... -->
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1 +1,10 @@
|
|||||||
{{ $model := . }}
|
{{ $model := . }}
|
||||||
|
|
||||||
|
|
||||||
|
<nav class="flex flex-row gap-x-1 justify-between">
|
||||||
|
<div>
|
||||||
|
<a class="inline-block px-0.5" href="/"> J.M.R. Lenz: Kritische Briefausgabe </a>
|
||||||
|
</div>
|
||||||
|
<a href="/jahrgang/1765" class="inline-block px-0.5">Jahrgänge </a>
|
||||||
|
{{ .path }}
|
||||||
|
</nav>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
<script type="module" src="/assets/scripts.js"></script>
|
<script type="module" src="/assets/scripts.js"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="/assets/style.css" />
|
<link rel="stylesheet" type="text/css" href="/assets/style.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="/assets/css/remixicon.css" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="w-full text-lg" hx-ext="response-targets" hx-boost="true">
|
<body class="w-full text-lg" hx-ext="response-targets" hx-boost="true">
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="grow">
|
<main class="grow container-normal" id="main">
|
||||||
{{ block "body" . }}
|
{{ block "body" . }}
|
||||||
<!-- Default app body... -->
|
<!-- Default app body... -->
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@@ -1 +1,8 @@
|
|||||||
{{- template "_letterhead" .meta -}}
|
{{- template "_letterhead" .meta -}}
|
||||||
|
|
||||||
|
{{ if .prev }}
|
||||||
|
<a href="/brief/{{ .prev.Letter }}" class="stdlink">Vorheriger</a>
|
||||||
|
{{ end }}
|
||||||
|
{{ if .next }}
|
||||||
|
<a href="/brief/{{ .next.Letter }}" class="stdlink">Nächster</a>
|
||||||
|
{{ end }}
|
||||||
|
|||||||
238
views/routes/datenschutz/body.gohtml
Normal file
238
views/routes/datenschutz/body.gohtml
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
<div class="container-normal">
|
||||||
|
<div class="text [&_*]:!indent-0 border px-8 py-7">
|
||||||
|
<h1 class="!mt-0">Impressum</h1>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<strong>Telemedienanbieter im Sinne des § 5 TMG:</strong><br />Theodor Springmann
|
||||||
|
Stiftung<br />Hirschgasse 2<br />69120 Heidelberg<br /><br />Telefon +49 6221 436235<br />Email <a
|
||||||
|
href="mailto:info@theodor-springmann-stiftung.de"
|
||||||
|
>info@theodor-springmann-stiftung.de</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Rechtsform und Sitz:</strong><br />Die Theodor Springmann Stiftung ist eine
|
||||||
|
rechtsfähige Stiftung bürgerlichen Rechts. Sitz der Stiftung ist Heidelberg.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Vorstand der Theodor Springmann Stiftung:</strong><br />Dr. Randolf Straky
|
||||||
|
(Präsident)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Geschäftsführung:</strong><br />Dr. Randolf Straky<br />Theodor Springmann
|
||||||
|
Stiftung<br />Hirschgasse 2<br />69120 Heidelberg
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Zuständige Aufsichtsbehörde:</strong><br />Regierungspräsidium Karlsruhe<br />Schlossplatz
|
||||||
|
1-3<br />76131 Karlsruhe<br /><br /><a
|
||||||
|
href="https://rp.baden-wuerttemberg.de/Themen/Stiftung/Seiten/Ansprechpartner.aspx"
|
||||||
|
>Ansprechpartner</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Redaktionelle Verantwortung nach § 55 Abs. 2 RStV:</strong><br />
|
||||||
|
Gregor Babelotzky<br />Theodor Springmann Stiftung<br />Hirschgasse 2<br />69120 Heidelberg
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
2024-10-17 09:52:17.412Z
|
||||||
|
</div>
|
||||||
|
<div class="text">
|
||||||
|
<h1 class="mt-12">Datenschutzerklärung</h1>
|
||||||
|
<div class="ma-prose-prose">
|
||||||
|
<div>
|
||||||
|
<h2>Präambel</h2>
|
||||||
|
<p>
|
||||||
|
Diese Datenschutzerklärung informiert Sie über die Art, den Umfang und den Zweck der
|
||||||
|
personenbezogenen Daten, die im Rahmen dieser Onlinepräsenz von Ihnen erhoben und von uns
|
||||||
|
verarbeitet werden, sowie die Ihnen zustehenden Rechte.<br />Personenbezogene Daten sind
|
||||||
|
alle Informationen, die sich auf eine identifizierte oder identifizierbare natürliche
|
||||||
|
Person beziehen. Als identifizierbar wird eine natürliche Person angesehen, die direkt
|
||||||
|
oder indirekt identifiziert werden kann. Im Hinblick auf weitere verwendete
|
||||||
|
Begrifflichkeiten verweisen wir auf die Definitionen der Datenschutz-Grundverordnung
|
||||||
|
(DSGVO), Artikel 4.<br />Erfolgt die Verarbeitung personenbezogener Daten auf Grundlage
|
||||||
|
des Art. 6 Abs. 1 lit. f DSGVO, so besteht unser berechtigtes Interesse in der Erfüllung
|
||||||
|
unseres satzungsgemäßen Stiftungszwecks. Zweck der Stiftung ist es, in gemeinnütziger
|
||||||
|
Weise Wissenschaft und Kunst, Völkerverständigung und Entwicklungshilfe zu fördern und zum
|
||||||
|
menschlichen Selbstverständnis sowie zum Erkennen und Lindern strukturell bedingter Not
|
||||||
|
und Bedürftigkeit von Menschen in aller Welt beizutragen.
|
||||||
|
</p>
|
||||||
|
<h2>Verantwortlicher</h2>
|
||||||
|
<p>
|
||||||
|
Verantwortlich im Sinne von Art. 4 Abs. 7 DSGVO für die Verarbeitung personenbezogener
|
||||||
|
Daten ist:<br />Theodor Springmann Stiftung<br />Hirschgasse 2<br />69120 Heidelberg<br /><br /><a
|
||||||
|
href="mailto:info@theodor-springmann-stiftung.de"
|
||||||
|
>info@theodor-springmann-stiftung.de</a
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
<h2>Automatisch bei Nutzung unserer Onlinepräsenz erfasste Daten</h2>
|
||||||
|
<p>
|
||||||
|
Mit der Nutzung unserer Onlinepräsenz werden automatisch personenbezogene und allgemeine
|
||||||
|
Daten vom Nutzer übermittelt und von uns erfasst und gespeichert. Die von uns erhobenen
|
||||||
|
Daten umfassen:
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
die IP-Adresse des ans Internet angeschlossenen Netzwerkgeräts (Computer oder Router des
|
||||||
|
Nutzers),
|
||||||
|
</li>
|
||||||
|
<li>den verwendeten Browsertyp und dessen Version,</li>
|
||||||
|
<li>das verwendete Betriebssystem und dessen Version,</li>
|
||||||
|
<li>die Internetseite, die den Nutzer auf unsere Onlinepräsenz verweist (Referrer),</li>
|
||||||
|
<li>die Unterwebseiten, die der Nutzer auf unserer Onlinepräsenz aufruft,</li>
|
||||||
|
<li>das Datum und die Uhrzeit des Aufrufs,</li>
|
||||||
|
<li>den Internet-Service-Provider des Nutzers,</li>
|
||||||
|
<li>sonstige ähnliche Daten.</li>
|
||||||
|
</ol>
|
||||||
|
<p>
|
||||||
|
Die Theodor Springmann Stiftung zieht aus diesen Daten keine Rückschlüsse auf die
|
||||||
|
betroffenen Nutzer. Diese Informationen werden benötigt, um
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li>die vom Nutzer angeforderten Inhalte korrekt auszuliefern,</li>
|
||||||
|
<li>
|
||||||
|
technische Probleme zu diagnostizieren, unsere IT-Systeme vor Angriffen zu schützen und
|
||||||
|
im Falle eines Angriffs den zuständigen Behörden notwendige Informationen zur
|
||||||
|
Strafverfolgung bereitstellen zu können,
|
||||||
|
</li>
|
||||||
|
<li>die Inhalte und die Bedienung unserer Onlinepräsenz zu optimieren.</li>
|
||||||
|
</ol>
|
||||||
|
<p>
|
||||||
|
Die oben genannten Verarbeitungszwecke werden von Subsystemen erfüllt, die unabhängig von
|
||||||
|
anderen Subsystemen ihre jeweils eigene Kopie der vom Nutzer erhobenen Daten erhalten,
|
||||||
|
verarbeiten und löschen. Dabei werden den Subsystemen lediglich die zur Ausführung ihrer
|
||||||
|
Aufgabe erforderlichen Daten übergeben. Alle Subsysteme befinden sich auf Servern der
|
||||||
|
Theodor Springmann Stiftung.
|
||||||
|
</p>
|
||||||
|
<h3>Auslieferung der vom Nutzer angeforderten Inhalte</h3>
|
||||||
|
<p>
|
||||||
|
Mit der Anforderung einer Seite dieser Onlinepräsenz übermittelt der Browser des Nutzers
|
||||||
|
automatisch die IP-Adresse seines ans Internet angeschlossenen Netzwerkgeräts (Computer
|
||||||
|
oder Router) und andere Daten. Ohne diese IP-Adresse können die Inhalte dieser
|
||||||
|
Online-Präsenz nicht an den Nutzer zurückgesendet werden. Daher ist die Speicherung und
|
||||||
|
Verarbeitung der IP-Adresse für den Betrieb dieser Onlinepräsenz notwendig. Ebenfalls
|
||||||
|
übermittelte Daten über den verwendeten Browser usw. werden gegebenenfalls verwendet, um
|
||||||
|
die Anzeige der Webseite an das Anzeigegerät oder den Browser anzupassen. Die zum Zwecke
|
||||||
|
der Auslieferung von Inhalten gesammelten Daten werden direkt nach Übertragung der Inhalte
|
||||||
|
vom Subsystem gelöscht. Die Verarbeitung dieser Daten erfolgt auf der Grundlage eines
|
||||||
|
berechtigten Interesses nach Art. 6 Abs. 1 lit. f DSGVO.
|
||||||
|
</p>
|
||||||
|
<h3>Diagnose und Schutz der IT-Systeme</h3>
|
||||||
|
<p>
|
||||||
|
Daneben erfolgt eine Speicherung der oben genannten Daten in Diagnose-Protokollen. Die
|
||||||
|
Protokollierung ist notwendig, um etwaige technische Probleme analysieren oder Angriffe
|
||||||
|
erkennen und abwehren zu können. Bei Angriffen auf unsere IT-Systeme übergeben wir die
|
||||||
|
Diagnose-Protokolle den zuständigen Strafverfolgungsbehörden. Die Diagnose-Protokolle
|
||||||
|
werden nach 14 Tagen automatisch gelöscht. Die Speicherung und Verarbeitung dieser Daten
|
||||||
|
erfolgt auf Grundlage eines berechtigten Interesses nach Art. 6 Abs. 1 lit. f DSGVO.
|
||||||
|
</p>
|
||||||
|
<h3>Analyse zur Optimierung der Inhalte und der Bedienung</h3>
|
||||||
|
<p>
|
||||||
|
Die oben genannten Daten werden von einem Webanalyseprogramm verarbeitet. Dabei werden die
|
||||||
|
Daten pseudonymisiert und aggregiert, so dass sie einzelnen Nutzern nicht mehr zugeordnet
|
||||||
|
werden können. Das Analyseprogramm wird auf einem von uns betriebenen Server ausgeführt,
|
||||||
|
daher werden keine Daten an Dritte übermittelt. Der Zweck dieser Erfassung besteht in der
|
||||||
|
Analyse der Nutzung unseres Angebots, durch die eine Verbesserung unserer Webseiten, der
|
||||||
|
Inhalte und der Bedienung ermöglicht wird. Das Analyseprogramm speichert die
|
||||||
|
anonymisierten Daten ohne zeitliche Begrenzung. Die Verarbeitung dieser Daten erfolgt auf
|
||||||
|
der Grundlage eines berechtigten Interesses (Art. 6 Abs. 1 lit. f DSGVO).
|
||||||
|
</p>
|
||||||
|
<h2>Sonstige Daten</h2>
|
||||||
|
<p>
|
||||||
|
Sämtliche Daten, die mit dem Aufruf einer Webseite von unserer Onlinepräsenz an den Nutzer
|
||||||
|
übertragen werden, werden von unseren Servern bereitgestellt. Wir nutzen kein von Dritten
|
||||||
|
bereitgestelltes Content Delivery Network (CDN), um Teile unserer Onlinepräsenz (z. B.
|
||||||
|
Javascript- oder Webfont-Dateien) von dort an den Nutzer zu übermitteln. Wir verlinken
|
||||||
|
auch nicht in soziale Netzwerke. Insofern können von Dritten keine personenbezogenen Daten
|
||||||
|
über unsere Onlinepräsenz erhoben werden, es sei denn, die Datenerfassung durch Dritte
|
||||||
|
basiert auf einer gesetzlichen Grundlage und/oder wurde behördlich angeordnet.<br />In
|
||||||
|
unseren Inhalten können sich jedoch Hyperlinks („Links“) auf fremde Onlineangebote
|
||||||
|
befinden. Mit dem Anklicken eines solchen Links verlässt der Nutzer unsere Onlinepräsenz
|
||||||
|
und damit den Geltungsbereich dieser Datenschutzerklärung.
|
||||||
|
</p>
|
||||||
|
<h2>Erhobene Daten bei Kontakt</h2>
|
||||||
|
<p>
|
||||||
|
Unsere Onlinepräsenz hält unter anderem aufgrund gesetzlicher Vorgaben verschiedene
|
||||||
|
Möglichkeiten bereit, mit uns in Kontakt zu treten. Sofern eine betroffene Person Kontakt
|
||||||
|
zu uns aufnimmt, werden die von der betroffenen Person übermittelten personenbezogenen
|
||||||
|
Daten automatisch gespeichert (z. B. Telefonnummer, E-Mail-Adresse). Diese Angaben werden
|
||||||
|
zum Zwecke der Bearbeitung sowie für sich möglicherweise anschließende Kommunikation von
|
||||||
|
uns gespeichert. Sobald die Speicherung dieser Daten nicht mehr erforderlich ist und keine
|
||||||
|
gesetzlichen Archivierungsgründe vorliegen, werden die Daten gelöscht. Die
|
||||||
|
Erforderlichkeit wird alle zwei Jahre überprüft. Es erfolgt keine Weitergabe dieser
|
||||||
|
personenbezogenen Daten an Dritte.<br />Von betroffenen Personen übermittelte
|
||||||
|
Informationen zur Bearbeitung einer Kontaktanfrage werden gemäß Art. 6 Abs. 1 lit. b
|
||||||
|
(vertragliche und vorvertragliche Beziehungen) oder lit. f (andere Anfragen) der DSGVO
|
||||||
|
verarbeitet.
|
||||||
|
</p>
|
||||||
|
<h2>Speicherung und Löschung von personenbezogenen Daten</h2>
|
||||||
|
<p>
|
||||||
|
Personenbezogene Daten werden von uns für die Dauer der entsprechenden gesetzlichen
|
||||||
|
Aufbewahrungspflichten oder für den zur Vertragserfüllung erforderlichen Zeitraum
|
||||||
|
gespeichert. Liegen solche Gründe nicht vor, werden personenbezogene Daten für den
|
||||||
|
Zeitraum, der zur Erreichung des Speicherzwecks erforderlich ist, verarbeitet und
|
||||||
|
gespeichert, sofern in dieser Datenschutzerklärung nicht ausdrücklich anderes angegeben
|
||||||
|
ist. Sobald die Daten für ihre Zweckbestimmung nicht mehr erforderlich sind oder der
|
||||||
|
Speicherungszweck entfällt, werden sie nach Maßgabe der gesetzlichen Vorschriften gelöscht
|
||||||
|
oder in ihrer Verarbeitung eingeschränkt.<br />Sollten die Daten nicht gelöscht werden
|
||||||
|
dürfen, weil sie einer gesetzlichen Aufbewahrungspflicht unterliegen, wird deren
|
||||||
|
Verarbeitung durch Archivierung eingeschränkt. Die Daten werden erst nach Ablauf der
|
||||||
|
gesetzlich vorgeschriebenen Speicherfrist gelöscht.<br />Alle sechs Monate wird
|
||||||
|
routinemäßig geprüft, ob der Speicherungszweck weggefallen bzw. die Aufbewahrungspflicht
|
||||||
|
abgelaufen ist. Anschließend wird gegebenenfalls die Löschung durchgeführt.
|
||||||
|
</p>
|
||||||
|
<h2>Rechte der betroffenen Personen</h2>
|
||||||
|
<p>
|
||||||
|
Unter den angegebenen Kontaktdaten können betroffene Personen jederzeit nachgenannte
|
||||||
|
Rechte ausüben. Eine betroffene Person kann von uns verlangen, dass
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Auskunft über sie betreffende, bei uns gespeicherte Daten und deren Verarbeitung erteilt
|
||||||
|
wird (Art. 15 DSGVO),
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
sie betreffende unrichtige personenbezogene Daten berichtigt werden (Art. 16 DSGVO),
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
sie betreffende, bei uns gespeicherte personenbezogene Daten gelöscht werden (Art. 17
|
||||||
|
DSGVO),
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
die Verarbeitung sie betreffender, bei uns gespeicherter Daten, die aufgrund
|
||||||
|
gesetzlicher Vorschriften oder anderer Gründe nicht gelöscht werden dürfen,
|
||||||
|
eingeschränkt wird (Art. 18 DSGVO),
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
sie betreffende Daten übertragbar sind, soweit sie in die Datenverarbeitung eingewilligt
|
||||||
|
oder einen Vertrag mit uns geschlossen hat (Art. 20 DSGVO),
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
sie betreffende Daten nach einem Widerspruch nicht weiter von uns verarbeitet werden
|
||||||
|
(Art. 21 DSGVO).
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Eine betroffene Person hat ferner jederzeit das Recht,</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
eine erteilte Einwilligung in die Erhebung und Verarbeitung personenbezogener Daten nach
|
||||||
|
Art. 6 Abs. 1 lit. a oder Art. 9 Abs. 2 lit. a DSGVO für die Zukunft zu widerrufen (Art.
|
||||||
|
7 Abs. 3 DSGVO),
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
sich mit einer Beschwerde an eine Aufsichtsbehörde zu wenden (Art. 15 Abs. 1 lit. f
|
||||||
|
DSGVO). Eine Liste der Aufsichtsbehörden lässt sich unter <a
|
||||||
|
href="https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html"
|
||||||
|
>diesem Link</a
|
||||||
|
> abrufen.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h2>Änderung unserer Datenschutzerklärung</h2>
|
||||||
|
<p>
|
||||||
|
Wir behalten uns vor, diese Datenschutzerklärung ohne vorherige Ankündigung an neue
|
||||||
|
rechtliche oder technische Sachverhalte sowie an Änderungen unserer Leistungen oder
|
||||||
|
Prozesse anzupassen. Es gilt die jeweils auf der Onlinepräsenz veröffentlichte Version der
|
||||||
|
Datenschutzerklärung.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
1
views/routes/datenschutz/head.gohtml
Normal file
1
views/routes/datenschutz/head.gohtml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<title>Musenalm – Impressum & Datenschutz</title>
|
||||||
0
views/routes/edition/zitation/head.gohtml
Normal file
0
views/routes/edition/zitation/head.gohtml
Normal file
@@ -1,12 +1,22 @@
|
|||||||
{{ $model := . }}
|
{{ $model := . }}
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<nav>
|
||||||
{{- range $y := .years -}}
|
{{- range $y := .years -}}
|
||||||
<a class="inline-block px-0.5" href="/{{ $y }}">{{ $y }}</a>
|
<a
|
||||||
|
class="inline-block stdlink px-0.5"
|
||||||
|
href="/jahrgang/{{ $y }}"
|
||||||
|
{{ if eq $model.year $y -}}aria-current="page"{{- end }}
|
||||||
|
>{{ $y }}</a
|
||||||
|
>
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
<a class="inline-block px-0.5" href="/all">Alle</a>
|
<a
|
||||||
</div>
|
class="inline-block stdlink px-0.5"
|
||||||
|
href="/jahrgang/all"
|
||||||
|
{{ if .all -}}aria-current="page"{{- end }}
|
||||||
|
>Alle</a
|
||||||
|
>
|
||||||
|
</nav>
|
||||||
|
|
||||||
{{- if .years -}}
|
{{- if .years -}}
|
||||||
{{- if .year -}}
|
{{- if .year -}}
|
||||||
0
views/routes/jahrgang/head.gohtml
Normal file
0
views/routes/jahrgang/head.gohtml
Normal file
0
views/routes/kontakt/body.gohtml
Normal file
0
views/routes/kontakt/body.gohtml
Normal file
0
views/routes/kontakt/head.gohtml
Normal file
0
views/routes/kontakt/head.gohtml
Normal file
@@ -1,7 +1,6 @@
|
|||||||
// INFO: We import this so vite processes the stylesheet
|
// INFO: We import this so vite processes the stylesheet
|
||||||
import "../public/css/fonts.css";
|
import "../public/css/fonts.css";
|
||||||
import "./site.css";
|
import "./site.css";
|
||||||
import "../public/css/remixicon.css";
|
|
||||||
import "../public/js/alpine.min.js";
|
import "../public/js/alpine.min.js";
|
||||||
import "../public/js/htmx.min.js";
|
import "../public/js/htmx.min.js";
|
||||||
import "../public/js/htmx-response-targets.js";
|
import "../public/js/htmx-response-targets.js";
|
||||||
|
|||||||
@@ -62,4 +62,16 @@
|
|||||||
body {
|
body {
|
||||||
@apply bg-stone-50;
|
@apply bg-stone-50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container-normal {
|
||||||
|
@apply w-full max-w-(--breakpoint-xl) mx-auto px-3 py-4 relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stdlink {
|
||||||
|
@apply underline decoration-dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a[aria-current="page"] {
|
||||||
|
@apply font-bold text-red-500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,6 +240,39 @@ func (l *Library) cleanup(meta xmlparsing.ParseMeta) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NextPrev struct {
|
||||||
|
Next, Prev *Meta
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Library) NextPrev(meta *Meta) *NextPrev {
|
||||||
|
year := meta.Earliest().Sort().Year
|
||||||
|
years, yearmap := l.Years()
|
||||||
|
var next, prev *Meta
|
||||||
|
for i, y := range yearmap[year] {
|
||||||
|
if y.Letter == meta.Letter {
|
||||||
|
if i > 0 {
|
||||||
|
prev = &yearmap[year][i-1]
|
||||||
|
} else {
|
||||||
|
index := slices.Index(years, year)
|
||||||
|
if index > 0 {
|
||||||
|
prev = &yearmap[years[index-1]][len(yearmap[years[index-1]])-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i < len(yearmap[year])-1 {
|
||||||
|
next = &yearmap[year][i+1]
|
||||||
|
} else {
|
||||||
|
index := slices.Index(years, year)
|
||||||
|
if index < len(years)-1 {
|
||||||
|
next = &yearmap[years[index+1]][0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NextPrev{Next: next, Prev: prev}
|
||||||
|
}
|
||||||
|
|
||||||
func (l *Library) Years() ([]int, map[int][]Meta) {
|
func (l *Library) Years() ([]int, map[int][]Meta) {
|
||||||
if years, ok := l.cache.Load("years"); ok {
|
if years, ok := l.cache.Load("years"); ok {
|
||||||
if yearmap, ok := l.cache.Load("yearmap"); ok {
|
if yearmap, ok := l.cache.Load("yearmap"); ok {
|
||||||
|
|||||||
Reference in New Issue
Block a user