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.

RSS | ATOM


Kommentar hinzufügen

Die Felder Name und Kommentar sind Pflichtfelder.


BBCode Hilfe