From 1a99a306ae044625e3f89e16d1d6f809ce8c12e0 Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 9 Dec 2025 17:48:21 +0100 Subject: Website-Erzeugung aus Nixpkgs-Modul statt Paket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Dateien für die Website mit Nix zu erzeugen ist zur Zeit der kleinste Schritt, um repetitive Muster weg zu abstrahieren. Alles andere bräuchte mehr Infrastruktur, während Nix bereits da ist und direkt verwendet werden kann. Es erlaubt jetzt einen nahtlosen Übergang zu einer strukturierteren Darstellung. Selbst falls das System sehr komplex wird, bevor es auf einen Anwendungsserver mit Datenbank usw. migriert werden kann, können im Prinzip Datentypen für die Sprache der Anwendung und sogar Nutzdaten im Zielformat aus den Modulsystem-Typen generiert werden. Das würde diese spätere Migration zumindest abmildern. Wichtig: Dateinamen dürfen keine Leerzeichen mehr enthalten, um genau zu sein siehe [0]. [0]: --- default.nix | 17 ++- www/caddy.nix | 24 ++-- www/flake-module.nix | 46 +++++++ www/framework/default.nix | 134 +++++++++++++++++++ www/html.nix | 57 ++++++++ .../Kalender/Kindertag in der Mehrwertkultur.html | 147 --------------------- ...in der Mehrwertkultur_html_290e08fdf9314385.jpg | Bin 33207 -> 0 bytes ...in der Mehrwertkultur_html_7312c2696b940296.png | Bin 325031 -> 0 bytes .../Kalender/Kindertag-in-der-Mehrwertkultur.html | 147 +++++++++++++++++++++ ...in-der-Mehrwertkultur_html_290e08fdf9314385.jpg | Bin 0 -> 33207 bytes ...in-der-Mehrwertkultur_html_7312c2696b940296.png | Bin 0 -> 325031 bytes .../img/Stadtteilbeirat Heimfeld Oktober 20.pdf | Bin 51362 -> 0 bytes .../img/Stadtteilbeirat-Heimfeld-Oktober-20.pdf | Bin 0 -> 51362 bytes 13 files changed, 409 insertions(+), 163 deletions(-) create mode 100644 www/flake-module.nix create mode 100644 www/framework/default.nix create mode 100644 www/html.nix delete mode 100644 www/html/Kalender/Kindertag in der Mehrwertkultur.html delete mode 100644 www/html/Kalender/Kindertag in der Mehrwertkultur_html_290e08fdf9314385.jpg delete mode 100644 www/html/Kalender/Kindertag in der Mehrwertkultur_html_7312c2696b940296.png create mode 100644 www/html/Kalender/Kindertag-in-der-Mehrwertkultur.html create mode 100644 www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_290e08fdf9314385.jpg create mode 100644 www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_7312c2696b940296.png delete mode 100644 www/html/img/Stadtteilbeirat Heimfeld Oktober 20.pdf create mode 100644 www/html/img/Stadtteilbeirat-Heimfeld-Oktober-20.pdf diff --git a/default.nix b/default.nix index 1e20ba6..0e8e2d5 100644 --- a/default.nix +++ b/default.nix @@ -23,15 +23,26 @@ flake-parts.lib.mkFlake inherit (flake) self; } ( - { self, lib, ... }: + { + self, + lib, + options, + config, + ... + }: { flake.inputs = flake.inputs; imports = with lib.fileset; toList ( # Alle Nix-Dateien in diesem Projekt sind Flake-Parts-Module - difference (fileFilter (file: file.hasExt "nix" && file.name != "flake.nix") ./.) ./default.nix - ); + difference (fileFilter (file: file.hasExt "nix") ./.) (unions [ + ./flake.nix + ./default.nix + ./www/framework + ]) + ) + ++ [ flake-parts.flakeModules.modules ]; systems = [ "x86_64-linux" ]; } ) diff --git a/www/caddy.nix b/www/caddy.nix index 6721316..9a5bd50 100644 --- a/www/caddy.nix +++ b/www/caddy.nix @@ -1,16 +1,11 @@ { self, lib, ... }: -let - html = - with lib.fileset; - toSource { - root = ./html; - fileset = ./html; - }; -in { flake.machines.tharos = { nixos = - { lib, ... }: + { config, lib, ... }: + let + website = self.websites.${config.nixpkgs.hostPlatform.system}.${self.domain}; + in { services.caddy.virtualHosts.${self.domain} = { serverAliases = [ "www.${self.domain}" ]; @@ -18,13 +13,15 @@ in file_server root * /var/www/${self.domain} encode gzip + + ${website.redirects.caddy} ''; }; systemd.tmpfiles.rules = [ # Verzeichnis für Web-Inhalte sofort anlegen, da der Webserver sonst nicht startet, # aber nur wenn es noch nicht existiert. - "C /var/www/${self.domain} - - - - ${html}" + "C /var/www/${self.domain} - - - - ${website.result}" ]; }; vm = @@ -52,10 +49,14 @@ in pkgs, lib, system, + config, self', ... }: { + # Website aus Quellcode generiert + packages.html = self'.websites.${self.domain}.result; + # Website-Inhalte auf den Server hochladen packages.publish = pkgs.writeShellApplication { name = "publish"; @@ -66,9 +67,6 @@ in }; # Lokale Vorschau - packages.html = pkgs.runCommand "source" { } '' - cp -r ${html} $out - ''; packages.preview = pkgs.devmode.override { buildArgs = '' "$(${lib.getExe pkgs.git} rev-parse --show-toplevel)" -A packages.${system}.html -vv diff --git a/www/flake-module.nix b/www/flake-module.nix new file mode 100644 index 0000000..880b395 --- /dev/null +++ b/www/flake-module.nix @@ -0,0 +1,46 @@ +{ + self, + config, + lib, + flake-parts-lib, + ... +}: +let + inherit (lib) + filterAttrs + mapAttrs + mkOption + optionalAttrs + types + ; + inherit (flake-parts-lib) + mkSubmoduleOptions + mkPerSystemOption + ; +in +{ + options = { + flake = mkSubmoduleOptions { + websites = mkOption { }; + }; + + perSystem = mkPerSystemOption ( + { pkgs, ... }: + { + _file = ./option.nix; + options = { + websites = mkOption { + type = + with types; + lazyAttrsOf (submoduleWith { + specialArgs = { inherit pkgs; }; + modules = [ ./framework ]; + }); + }; + }; + } + ); + }; + + config.transposition.websites = { }; +} diff --git a/www/framework/default.nix b/www/framework/default.nix new file mode 100644 index 0000000..92e1ed8 --- /dev/null +++ b/www/framework/default.nix @@ -0,0 +1,134 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (lib) mkOption types; +in +{ + imports = + with lib.fileset; + toList (difference (fileFilter (file: file.hasExt "nix") ./.) ./default.nix); + + options = { + types = mkOption { + description = "Datentypen für Website-Inhalte"; + type = with types; lazyAttrsOf deferredModule; + default = { }; + }; + + files = mkOption { + description = '' + Dateien, aus denen die Website besteht, als Abbildung vom Dateipfad zum Inhalt + ''; + type = with types; attrsOf (either path (submodule config.types.file)); + }; + + redirects.raw = mkOption { + description = '' + Weiterleitungen aller historischen Dateipfade auf Kanonische Pfade + ''; + type = with types; lazyAttrsOf str; + readOnly = true; + default = + with lib; + listToAttrs ( + concatMap ( + name: + if config.files.${name} ? locations then + map (loc: { + name = "/" + loc; + value = "/" + name; + }) (tail config.files.${name}.locations) + else + [ ] + ) (attrNames config.files) + ); + }; + + redirects.caddy = mkOption { + description = '' + Weiterleitungen im Caddyfile-Format + ''; + type = types.str; + readOnly = true; + default = + with lib; + let + lines = mapAttrsToList (name: value: ''redir "${name}" ${value} permanent'') config.redirects.raw; + in + concatStringsSep "\n" lines; + }; + + result = mkOption { + description = '' + Fertige Website als Verzeichnis + ''; + type = types.package; + readOnly = true; + default = + let + script = '' + mkdir $out + '' + + lib.concatStringsSep "\n" copy; + copy = lib.mapAttrsToList ( + path: file: + let + content = if file ? path then file.path else file; + in + '' + mkdir -p $out/$(dirname '${toString path}') + ${ + "" # `--no-preserve-mode` ist erforderlich da Nix store paths read-only sind, und man andernfalls `cp -r` nicht durchführen kann. + }cp -r --no-preserve=mode ${content} $out/'${toString path}' + '' + ) config.files; + in + pkgs.runCommand "source" { } script; + }; + }; + + config.types.document = + { lib, ... }: + let + inherit (lib) mkOption types; + in + { + options = { + locations = mkOption { + description = '' + Frühere Pfade dieses Dokuments + + Einträge sind relative Pfade. + Der erste Eintrag ist der kanonische Pfad. + Alle anderen Elemente werden für Weiterleitungen zum kanonischen Pfad benutzt. + ''; + type = with types; nonEmptyListOf str; + example = [ + "about/overview" + "index" + ]; + }; + }; + }; + + config.types.file = + { lib, ... }: + let + inherit (lib) mkOption types; + in + { + imports = [ config.types.document ]; + options = { + path = mkOption { + type = types.path; + description = '' + Datei mit manuell gesteuertem Pfad + ''; + }; + }; + }; +} diff --git a/www/html.nix b/www/html.nix new file mode 100644 index 0000000..6e48e2f --- /dev/null +++ b/www/html.nix @@ -0,0 +1,57 @@ +{ self, ... }: +{ + perSystem = + { ... }: + { + websites.${self.domain} = + { lib, ... }: + let + inherit (lib) mkOption types; + in + { + files = + let + root = ./html; + files = lib.fileset.toList root; + redirects = + with lib; + mapAttrsToList + (name: value: { + name = head value.locations; + inherit value; + }) + { + kindertag = { + path = ./html/Kalender/Kindertag-in-der-Mehrwertkultur.html; + locations = [ + "Kalender/Kindertag-in-der-Mehrwertkultur.html" + "Kalender/Kindertag in der Mehrwertkultur.html" + ]; + }; + kinder-banner = { + path = ./html/Kalender/Kindertag-in-der-Mehrwertkultur_html_7312c2696b940296.png; + locations = [ + "Kalender/Kindertag-in-der-Mehrwertkultur_html_7312c2696b940296.png" + "Kalender/Kindertag in der Mehrwertkultur_html_7312c2696b940296.png" + ]; + }; + contraZt-logo = { + path = ./html/Kalender/Kindertag-in-der-Mehrwertkultur_html_290e08fdf9314385.jpg; + locations = [ + "Kalender/Kindertag-in-der-Mehrwertkultur_html_290e08fdf9314385.jpg" + "Kalender/Kindertag in der Mehrwertkultur_html_290e08fdf9314385.jpg" + ]; + }; + }; + in + lib.listToAttrs ( + redirects + ++ map (file: { + name = lib.path.removePrefix root file; + value = file; + }) files + ); + }; + + }; +} diff --git a/www/html/Kalender/Kindertag in der Mehrwertkultur.html b/www/html/Kalender/Kindertag in der Mehrwertkultur.html deleted file mode 100644 index 39b693d..0000000 --- a/www/html/Kalender/Kindertag in der Mehrwertkultur.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Zurück
-

-

-

-
Kindertag - in - der MehrWertKultur* -
-

-

-
-
Am - 1. Juni ist unser Laden MehrWertKultur in der - Nobléestraße 13a
- extra für die - Kinder geöffnet!
- 14 – 17 - Uhr 
-

-

-
-
    -
  • Es gibt jede Menge Bücher im Laden
    -
  • -
  • Vor dem Laden steht ein „Lesemobil“ mit - ordentlich Lesestoff für die Kleinen
    -
  • -
  • Modellierballons
    -
  • -
-

-

-
*Zum Schutz vor Verbreitung des - Coronavirus gelten in den Räumen der MWK folgende - Regeln: Der Abstand von 1,5 Meter muss eingehalten - werden; In den Räumen der Mehrwertkultur ist eine - Nase-Mund-Bedeckung zu tragen;
-

-
Fragen und Info unter: - post@contrazt.de -
-

-
-
-
contraZt e.V.
-
-

-

-

-
Zurück
-
-


-

-
- - diff --git a/www/html/Kalender/Kindertag in der Mehrwertkultur_html_290e08fdf9314385.jpg b/www/html/Kalender/Kindertag in der Mehrwertkultur_html_290e08fdf9314385.jpg deleted file mode 100644 index aae5162..0000000 Binary files a/www/html/Kalender/Kindertag in der Mehrwertkultur_html_290e08fdf9314385.jpg and /dev/null differ diff --git a/www/html/Kalender/Kindertag in der Mehrwertkultur_html_7312c2696b940296.png b/www/html/Kalender/Kindertag in der Mehrwertkultur_html_7312c2696b940296.png deleted file mode 100644 index e558cae..0000000 Binary files a/www/html/Kalender/Kindertag in der Mehrwertkultur_html_7312c2696b940296.png and /dev/null differ diff --git a/www/html/Kalender/Kindertag-in-der-Mehrwertkultur.html b/www/html/Kalender/Kindertag-in-der-Mehrwertkultur.html new file mode 100644 index 0000000..39b693d --- /dev/null +++ b/www/html/Kalender/Kindertag-in-der-Mehrwertkultur.html @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Zurück
+

+

+

+
Kindertag + in + der MehrWertKultur* +
+

+

+
+
Am + 1. Juni ist unser Laden MehrWertKultur in der + Nobléestraße 13a
+ extra für die + Kinder geöffnet!
+ 14 – 17 + Uhr 
+

+

+
+
    +
  • Es gibt jede Menge Bücher im Laden
    +
  • +
  • Vor dem Laden steht ein „Lesemobil“ mit + ordentlich Lesestoff für die Kleinen
    +
  • +
  • Modellierballons
    +
  • +
+

+

+
*Zum Schutz vor Verbreitung des + Coronavirus gelten in den Räumen der MWK folgende + Regeln: Der Abstand von 1,5 Meter muss eingehalten + werden; In den Räumen der Mehrwertkultur ist eine + Nase-Mund-Bedeckung zu tragen;
+

+
Fragen und Info unter: + post@contrazt.de +
+

+
+
+
contraZt e.V.
+
+

+

+

+
Zurück
+
+


+

+
+ + diff --git a/www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_290e08fdf9314385.jpg b/www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_290e08fdf9314385.jpg new file mode 100644 index 0000000..aae5162 Binary files /dev/null and b/www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_290e08fdf9314385.jpg differ diff --git a/www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_7312c2696b940296.png b/www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_7312c2696b940296.png new file mode 100644 index 0000000..e558cae Binary files /dev/null and b/www/html/Kalender/Kindertag-in-der-Mehrwertkultur_html_7312c2696b940296.png differ diff --git a/www/html/img/Stadtteilbeirat Heimfeld Oktober 20.pdf b/www/html/img/Stadtteilbeirat Heimfeld Oktober 20.pdf deleted file mode 100644 index a57f18c..0000000 Binary files a/www/html/img/Stadtteilbeirat Heimfeld Oktober 20.pdf and /dev/null differ diff --git a/www/html/img/Stadtteilbeirat-Heimfeld-Oktober-20.pdf b/www/html/img/Stadtteilbeirat-Heimfeld-Oktober-20.pdf new file mode 100644 index 0000000..a57f18c Binary files /dev/null and b/www/html/img/Stadtteilbeirat-Heimfeld-Oktober-20.pdf differ -- cgit v1.2.3 From ab36912ee135d4897730b31d6e767d51bcf54e40 Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 16 Dec 2025 21:42:38 +0100 Subject: Titel auf allen Seiten aus Konfiguration generiert --- www/framework/default.nix | 6 ++++++ www/html.nix | 3 ++- www/html/datenschutz.html | 2 +- www/html/impressum.html | 2 +- www/html/index.html | 2 +- www/html/vergangene-termine.html | 2 +- www/index.nix | 33 +++++++++++++++++++++++++++++++++ 7 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 www/index.nix diff --git a/www/framework/default.nix b/www/framework/default.nix index 92e1ed8..0cc9049 100644 --- a/www/framework/default.nix +++ b/www/framework/default.nix @@ -19,6 +19,12 @@ in default = { }; }; + title = mkOption { + description = "Titel, der bei allen Seiten vorangestellt wird"; + type = types.singleLineStr; + readOnly = true; + }; + files = mkOption { description = '' Dateien, aus denen die Website besteht, als Abbildung vom Dateipfad zum Inhalt diff --git a/www/html.nix b/www/html.nix index 6e48e2f..729ea12 100644 --- a/www/html.nix +++ b/www/html.nix @@ -9,10 +9,11 @@ inherit (lib) mkOption types; in { + title = "Stadtteilbeirat Heimfeld"; files = let root = ./html; - files = lib.fileset.toList root; + files = with lib.fileset; toList root; redirects = with lib; mapAttrsToList diff --git a/www/html/datenschutz.html b/www/html/datenschutz.html index e5876e7..b9d1963 100644 --- a/www/html/datenschutz.html +++ b/www/html/datenschutz.html @@ -4,7 +4,7 @@ - Datenschutz + @title@ – Datenschutz diff --git a/www/html/impressum.html b/www/html/impressum.html index e6872db..cdf864e 100644 --- a/www/html/impressum.html +++ b/www/html/impressum.html @@ -4,7 +4,7 @@ - Impressum + @title@ – Impressum diff --git a/www/html/index.html b/www/html/index.html index 967522b..00ec727 100644 --- a/www/html/index.html +++ b/www/html/index.html @@ -6,7 +6,7 @@ - Stadtteilbeirat Heimfeld + @title@ diff --git a/www/html/vergangene-termine.html b/www/html/vergangene-termine.html index cc9c576..29b711c 100644 --- a/www/html/vergangene-termine.html +++ b/www/html/vergangene-termine.html @@ -6,7 +6,7 @@ - Stadtteilbeirat Heimfeld – Vergangene Termine + @title@ – Vergangene Termine diff --git a/www/index.nix b/www/index.nix new file mode 100644 index 0000000..0d84ec3 --- /dev/null +++ b/www/index.nix @@ -0,0 +1,33 @@ +{ self, ... }: +{ + perSystem = + { ... }: + { + websites.${self.domain} = + { config, lib, ... }: + let + inherit (lib) mkOption types; + replacements = { + "@title@" = config.title; + }; + replace = file: with lib; replaceStrings (attrNames replacements) (attrValues replacements) file; + in + { + files = + with lib; + listToAttrs ( + map + (path: rec { + name = baseNameOf path; + value = with builtins; toFile "index.html" (replace (readFile path)); + }) + [ + ./html/index.html + ./html/vergangene-termine.html + ./html/impressum.html + ./html/datenschutz.html + ] + ); + }; + }; +} -- cgit v1.2.3 From 6c54d824d64a752e48d03e98477047629b392003 Mon Sep 17 00:00:00 2001 From: Valentin Date: Tue, 16 Dec 2025 22:31:29 +0100 Subject: Stylesheet auf allen Seiten angeglichen Dabei kleine Vereinfachungen vorgenommen. --- www/html/datenschutz.html | 31 +++++++++++++------ www/html/impressum.html | 66 +++++++++++++++++++--------------------- www/html/index.html | 2 +- www/html/style.css | 4 +++ www/html/vergangene-termine.html | 3 +- www/index.nix | 1 + 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/www/html/datenschutz.html b/www/html/datenschutz.html index b9d1963..ce5e608 100644 --- a/www/html/datenschutz.html +++ b/www/html/datenschutz.html @@ -5,17 +5,23 @@ @title@ – Datenschutz - + @stylesheet@ - Zurück
+
+ +
- -

+

Datenschutzerklärung

Personenbezogene Daten (nachfolgend zumeist nur „Daten“ genannt) werden von uns nur im Rahmen der Erforderlichkeit @@ -164,16 +170,21 @@ href="https://www.ratgeberrecht.eu/leistungen/muster-datenschutzerklaerung.html" href="https://www.ratgeberrecht.eu/datenschutz/datenschutzerklaerung-generator-dsgvo.html">Anwaltskanzlei Weiß & Partner

Zurück  +
-


-

-
-

 
-

+ diff --git a/www/html/impressum.html b/www/html/impressum.html index cdf864e..e7cd775 100644 --- a/www/html/impressum.html +++ b/www/html/impressum.html @@ -5,37 +5,35 @@ @title@ – Impressum - + @stylesheet@ - Zurück
-
-
-

Impressum / - Kontakt

-
-
- Nicolas Stuebs
- Bansenstraße 5A
- D-21075 Hamburg-Heimfeld
- nicolas.stuebs (at) tharos-net.de
-
-

- - Inhaltlich Verantwortlicher gem. § 55 II RStV : Nicolas Stuebs
-
-

-
-
+
+ +

- - - - - -

+ +

Impressum / Kontakt

+ +
+ Nicolas Stuebs
+ Bansenstraße 5A
+ D-21075 Hamburg-Heimfeld
+ nicolas.stuebs (at) tharos-net.de
+
+

+ Inhaltlich Verantwortlicher gem. § 55 II RStV : Nicolas Stuebs +

Nutzungsbedingungen/Copyright/Haftungsausschluss:

1. Inhalt des Onlineangebots
Die Inhalte (Text- und Bildmaterial) werden @@ -155,24 +153,22 @@ Inhalt und ihrer Gültigkeit davon unberührt.

-

Nicolas Stuebs

+

Nicolas Stuebs



-

-
Zurück  -
-
-

-
+ diff --git a/www/html/index.html b/www/html/index.html index 00ec727..70d5b43 100644 --- a/www/html/index.html +++ b/www/html/index.html @@ -8,7 +8,7 @@ @title@ - + @stylesheet@ diff --git a/www/html/style.css b/www/html/style.css index aa80e22..ae35f45 100644 --- a/www/html/style.css +++ b/www/html/style.css @@ -79,6 +79,10 @@ div.column, section { flex-direction: column; gap: 1.5pt; } +.content { + background-color: var(--background-secondary); + padding: 1rem; +} .row { padding: 1rem; border: 1pt inset red; diff --git a/www/html/vergangene-termine.html b/www/html/vergangene-termine.html index 29b711c..2e31b72 100644 --- a/www/html/vergangene-termine.html +++ b/www/html/vergangene-termine.html @@ -8,7 +8,7 @@ @title@ – Vergangene Termine - + @stylesheet@
@@ -331,6 +331,7 @@