Mittwoch, Juli 22, 2026

Bug - Flatpress rendert Codeblöcke scheinbar nicht richtig

Mir ist aufgefallen, dass Flatpress Probleme hat bestimmte Zeichen korrekt darzustellen. Das ist fatal, weil alle Codeblöcke, die man per Copy&Paste übernimmt, mit hoher Wahrscheinlichkeit nicht funktionieren werden. Sehr ärgerlich!!! Statt ruhig zu bleiben und erst mal zu überlegen, habe ich natürlich mit diversen Frickel-Workarounds versucht die Sonderzeichen zu escapen. Das Problem ließ sich mit der Korrektur einer PHP-Datei bei Flatpress lösen. Evtl. ein Bug…?

Konkret ging es um gerade Anführungszeichen (”), doppelte Bindestriche (–), drei Bindestriche (—) und Auslassungspunkte (…) innerhalb von Codeblöcken. Die wurden beim Anzeigen des Artikels munter in typografische Zeichen umgewandelt: aus “central” wurde “central” mit krummen Anführungszeichen, aus — wurde ein einzelner Gedankenstrich –. Copy&Paste in ein Terminal funktioniert so natürlich nicht mehr.

Ich habe die Zeichen in den Codeblöcken durch HTML-Entities ersetzt (" statt “, -- statt –), in der Hoffnung, dass die beim Rendern wieder in normale Zeichen zurückverwandelt werden. Hat nicht geklappt - Flatpress escaped den Inhalt von Codeblöcken beim Anzeigen nochmal selbst, wodurch aus meinen Entities literaler Text wie " wurde, sichtbar im Artikel. Danach habe ich es mit einem unsichtbaren Zero-Width-Space zwischen den beiden Bindestrichen probiert, um die Zeichenerkennung auszutricksen, ohne dass man optisch einen Unterschied sieht. Hat für die Bindestriche sogar funktioniert, für Anführungszeichen aber nicht zuverlässig, und war obendrein viel zu fragil (Copy&Paste durch verschiedene Programme killt Zero-Width-Zeichen gerne mal).

Irgendwann habe ich dann doch aufgehört zu frickeln und mit Claude systematisch nach der eigentlichen Ursache gesucht. Claude meint zu dem Problem:

Flatpress nutzt (wie sich herausstellte) eine portierte Funktion aus WordPress namens wptexturize(), die genau für diese typografische Umwandlung zuständig ist. Diese Funktion soll eigentlich Inhalte innerhalb der “pre”- und “code”-Tags unangetastet lassen - das ist Standardverhalten und auch so dokumentiert. Bei Flatpress hat das aber nicht funktioniert, und der Grund dafür ist ein Logikfehler im Code:

} elseif (strstr($curl, '</') || strstr($curl, '>')) {
    if ($skip > 0) {
        $skip--;
    }
} elseif (strstr($curl, '<code') || strstr($curl, '<pre') || strstr($curl, '<kbd') || strstr($curl, '<style') || strstr($curl, '<script')) {
    // strstr is fast
    $skip++;
} else {

Der Text wird an den HTML-Tags aufgesplittet, und jedes Tag-Fragment enthält immer eine schließende spitze Klammer - auch ein öffnendes “pre”-Tag. Die erste Bedingung hier prüft aber zuerst auf diese schließende Klammer, und trifft deshalb schon bei einem öffnenden “pre”-Tag zu. Der eigentlich richtige Zweig, der $skip hochzählen sollte, sobald ein “pre”/”code”-Block beginnt, wird dadurch nie erreicht - toter Code. Die Variable $skip, die eigentlich signalisieren soll “wir sind gerade innerhalb eines Codeblocks, hier bitte nichts texturizen”, bleibt also bei 0, und der komplette Inhalt eines Codeblocks wird ganz normal mitbehandelt, obwohl er es nicht sollte.

Wäre ich alleine jedenfalls nie im Leben drauf gekommen. Der Fix war dann erstaunlich simpel: einfach die Reihenfolge der beiden elseif-Zweige vertauschen, sodass die Prüfung auf ein öffnendes “pre”/”code”/”kbd”/”style”/”script”-Tag zuerst kommt:

} elseif (strstr($curl, '<code') || strstr($curl, '<pre') || strstr($curl, '<kbd') || strstr($curl, '<style') || strstr($curl, '<script')) {
    // strstr is fast
    $skip++;
} elseif (strstr($curl, '</') || strstr($curl, '>')) {
    if ($skip > 0) {
        $skip--;
    }
} else {

Die Datei dazu ist core.wp-formatting.php, betroffen ist die Funktion wptexturize().

Ein wichtiger Nebeneffekt dieser Änderung: wptexturize() ist ein reiner Anzeige-Filter, kein Speicher-Filter. Der ursprüngliche, roh eingegebene Artikeltext lag also die ganze Zeit über unangetastet und korrekt in Flatpress - der Fehler trat erst beim Rendern der Seite auf. Das bedeutet, dass sich dieser Fix rückwirkend auf alle bisherigen Artikel auswirkt, ganz ohne dass ich sie erneut anfassen musste: Sobald die Datei korrigiert war, haben auch alte Codeblöcke wieder korrekt gerendert. Einzige Ausnahme waren die Artikel, bei denen ich vorher schon mit meinen (untauglichen) Workarounds händisch nachgebessert und den kaputten Text dadurch fest abgespeichert hatte - die musste ich anschließend nochmal auf ihren sauberen Originaltext zurücksetzen.

Ich hoffe, dass das in Zukunft dafür sorgt, dass Code korrekt dargestellt wird und Copy&Paste funktioniert. Sollten noch weitere Zeichen betroffen sein, bitte einen Kommentar hinterlassen. Ich habe mir noch einen Prompt für die Problematik erstellen lassen und werde alle zukünftigen Artikel da zusätzlich drüber laufen lassen.

Freitag, Juli 3, 2026

Umzug auf ein Blog

Hallo zusammen,
ich habe bisher einen kleinen Dokumentationsfundus zu FOSS und im Speziellen zu Proxmox auf diversen Ugreen-NAS-Geräten aufgebaut. Ich habe bisher einen Discord-Server mit Tagebuchcharakter dazu genutzt. Ich schaue oft in den Channels nach, wie ich gewisse Dinge eingerichtet habe, da ich sowas nach einer erfolgreichen Einrichtung schnell wieder vergesse. Bei Discord wird es nun leider immer unübersichtlicher, und es gibt diverse Limitierungen (z. B. maximale Nachrichtenlänge, schlechte Verlinkungsmöglichkeiten zwischen den Beiträgen usw.). Außerdem ist der Umgang mit den Nutzerdaten bei Discord eigentlich vollkommen inakzeptabel, von daher habe ich schon länger überlegt, auf einen (selbstgehosteten) Blog umzuziehen.
Der Blog dient dabei primär meiner persönlichen Gedächtnisstütze, und ich mache ihn öffentlich, damit das eine oder andere evtl. irgendjemandem ebenfalls weiterhilft. Ich mache IT nicht beruflich, bin aber seit meinem ersten C64 begeistert dabei. Manche Dinge löse ich vermutlich eher unkonventionell, und ich bin ja – wie schon gesagt – kein Profi, von daher sind die Anleitungen immer mit Vorsicht zu genießen. Über Verbesserungshinweise freue ich mich immer sehr.
Ich nutze für Softwareprojekte, Analysen und zur Recherche häufig KIs; meine Favoriten sind Mistral (Recherche und datenschutzsensible Dinge) und Anthropic Claude (für Codeanalyse und kleine Programmierprojekte). Im richtigen Leben arbeite ich als Selbstständiger im Gesundheitsbereich und wohne mit meiner Familie in der Nähe von München.
Natürlich möchte ich in meinem ersten Beitrag auch gleich ein paar Funktionen des neuen Blogs testen, daher zeige ich zwei Fotos von meinem „Homelab“ in der Waschküche.

signal-2026-07-03-141630.jpeg
signal-2026-07-03-141626.jpeg

Ich habe zwei Geräte mit PVE (Proxmox Virtual Environment): einmal ein refurbished ThinkCentre mit Intel i7-7700T und 32 GB RAM sowie ein Ugreen DXP 8800 Plus. Das Ugreen ist aktuell mit 64 GB RAM und 2×1 TB SSD ZFS Mirror für VMs und LXCs und 6×6 TB HDDs bestückt. Die beiden Controller, an denen die HDDs hängen, werden per PCI-Passthrough an eine TrueNAS-VM durchgereicht.
Aktuell laufen auf beiden Geräten insgesamt 29 LXCs und 2 VMs. Auf dem zweiten Foto sieht man meinen Router, ein OpenWRT One.
Für meine Computeraktivitäten nutze ich einen Desktop-PC mit wassergekühlter Nvidia GTX 3080 12 GB DDRAM und einem AMD Ryzen 9 7900X als CPU. Als Laptops nutze ich einen Framework 13” mit 32 GB RAM und dem AMD Ryzen 5 7640U-Board und dem ausgezeichneten 2,8k-Display. Auf beiden Geräten läuft als Betriebssystem Arch Linux. Für die Arbeit nutze ich ein MacBook Air M2.
Ach ja, ich tracke natürlich niemanden, der hier liest (zumindest nicht wissentlich), und schicke auch alle Bots, die vorbeikommen, in die Wüste (soweit ich das technisch kann/hinkriege). Das Blog ist aktuell bei All-inkl, also in Deutschland gehostet. Meine Datenschutzerklärung findet ihr hier. Ich schalte weder Werbung, noch nutze ich Affiliatelinks auf dieser Seite. Ich habe keinen Account bei Patreon o. ä. und ich akzeptiere keine Spenden. Dies ist also ein rein privates Blog, in dem andere einfach mitlesen können. Solche Details werden ja leider immer wichtiger.