Seit dem ersten Artikel über dieses Blog-System hat sich einiges getan. Hier eine Übersicht über alles was neu dazugekommen ist.

Theme-Switcher

Das Blog kennt jetzt sechs verschiedene Designs, zwischen denen man jederzeit wechseln kann – der Button sitzt unten rechts auf jeder Seite. Das gewählte Theme wird im Browser gespeichert.

Theme Charakter
ESP Dark Dunkler Hacker-Look (Original)
Cupertino Hell, clean, Apple-typisch
Museum Cremeweiß, elegant, viel Luft
Terminal Grüner Phosphor, CRT-Scanlines
Zeitung Altdeutsche Schrift, schwarzweiß
Neon Tokyo Hot Pink & Cyan, Cyberpunk

Neue Post-Tags

Zwei neue Einbettungs-Tags sind dazugekommen:

HTML-Demos einbetten


⚠ Datei nicht gefunden: demo.html

Bettet eine HTML-Datei als Live-Vorschau ein. Ein Klick öffnet sie in einem Vollbild-Popup. Nützlich für interaktive Simulationen, Visualisierungen oder kleine Web-Tools.

Code automatisch einklappen

Code-Blöcke mit mehr als 20 Zeilen werden automatisch eingeklappt und zeigen nur eine Vorschau. Ein Klick auf „alle N Zeilen anzeigen” klappt den Block aus. Die Anzahl der Vorschau-Zeilen lässt sich in generate.py mit CODE_PREVIEW_LINES anpassen.

Nicht erwähnte Dateien automatisch einbinden

Liegen im Post-Ordner Dateien die in der post.md nicht erwähnt werden, trägt generate.py sie beim nächsten Build automatisch am Ende ein – mit dem passenden Tag je nach Dateityp:

  • Bilder → [BILD datei.jpg]
  • Videos → [VIDEO datei.mp4]
  • Code → [CODE datei.cpp]
  • Alles andere → [DOWNLOAD datei.bin]

Im Terminal erscheint dabei eine Meldung wie:

📎 2 Datei(en) in post.md eingetragen: schaltung.jpg, firmware.bin

Upload-System (Admin-Interface)

Unter /admin.html gibt es jetzt ein passwortgeschütztes Upload-Interface. Es läuft als Flask-Container neben dem nginx-Webserver.

Damit kann man direkt vom Browser aus:
- Neuen Post anlegen – Titel, Datum, Tags, Markdown-Text und Dateien in einem Formular
- Dateien zu bestehendem Post hinzufügen – Dropdown mit allen Posts, Drag & Drop
- Freie Dateien hochladen – ohne Post-Zuordnung, landen im Drop-Ordner mit Timestamp
- Incoming-Übersicht – zeigt was bereits hochgeladen wurde aber noch nicht gebaut ist

Hochgeladene Dateien landen sofort in einem konfigurierbaren Drop-Ordner (bei mir /mnt/coding/upload/) – der Webserver hat darauf keinen Zugriff. Nach dem nächsten Build per Strg+Shift+B sind sie online.

Der Passwortschutz läuft über nginx Basic Auth – eine .htpasswd-Datei die mit htpasswd erstellt wird.

Markdown-Editor

Unter /editor/ gibt es jetzt einen eingebetteten Markdown-Editor direkt im Browser – kein VSCode nötig.

Der Editor bietet:
- Live-Vorschau – rechts neben dem Editor, synchron gescrollt
- Dateiliste mit Upload per Drag & Drop
- Einfüge-Buttons für [BILD], [VIDEO], [CODE] etc. – kein Tippen nötig
- Post-Auswahl – alle Posts in einer Seitenleiste, Wechsel mit einem Klick

So kann man Posts auch vom Handy oder Tablet aus bearbeiten.

VSCode Task-Picker

Strg+Shift+B zeigt jetzt einen Picker mit drei Optionen:

Option Was passiert
HTML generieren + live deployen generate.py lokal → rsync direkt auf den Server
Nur HTML neu generieren generate.py lokal → nur output/ (Vorschau)
Kompletter Rebuild generate + git commit + push → Portainer deployt automatisch

Docker-Setup

Der Blog-Stack läuft als vier Container in Docker, verwaltet über Portainer:

Container Aufgabe Port
blog-web nginx – serviert statische HTML-Dateien 4000
blog-upload Flask – Upload-API für neue Dateien intern
blog-editor Flask – Markdown-Editor intern
blog-builder Python – baut HTML aus den Posts (Watcher)

nginx routet /api/-Anfragen an blog-upload und /editor/-Anfragen an blog-editor weiter. Nach außen ist nur Port 4000 nötig.

Bei jedem git push werden blog-builder und blog-editor automatisch neu gestartet (via DEPLOY_TIME in der Stack-Konfiguration).

Windows-Support

Strg+Shift+B funktioniert unter Windows über PowerShell-Scripts. Der schnelle Deploy (deploy-html.ps1) nutzt WSL für rsync – das NAS-Share wird als WSL-Mount eingebunden und der output/-Ordner direkt übertragen.

Voraussetzungen unter Windows:
- Python, Git, WSL (wsl --install)
- In WSL: sudo apt install sshpass rsync
- Python-Pakete: pip install Pillow pygments markdown

Passwort sicher auslagern

Das DiskStation-Passwort für rsync liegt in einer .env-Datei die nie committed wird:

DISKSTATION_PASS=meinPasswort

Die .env ist in .gitignore eingetragen – sie liegt nur lokal auf dem jeweiligen Rechner.

Abhängigkeiten (aktuell)

pip install Pillow pygments markdown
sudo apt install sshpass rsync   # für den Deploy
Der Blog-Stack in Portainer mit allen vier Containern
Der Blog-Stack in Portainer mit allen vier Containern