Kurz gesagt
- Symptom: Beitrag gespeichert, Seite zeigt weiter den alten Stand. Nur ein kompletter Cache-Reset hilft.
- Ursache: Das Raidboxes-Cache-Plugin schickt den PURGE immer an /pfad/. Bei Permalinks ohne Trailing Slash liegt die Seite in Varnish aber unter /pfad.
- Fix: Ein MU-Plugin mit dem Filter vhp_purgeme_path entfernt den Slash wieder. Code unten.
Das Problem
Ein Kundenprojekt auf Raidboxes, WordPress mit Permalinks ohne Trailing Slash. Die Redaktion ändert einen Beitrag, speichert, lädt die Seite neu. Der alte Text steht immer noch da. Auch nach Minuten. Erst „Cache leeren“ im Raidboxes-Dashboard bringt die neue Version nach vorne.
Das sieht nach einem Caching-Bug aus, ist aber keiner. Der Cache tut genau, was man ihm sagt. Man sagt ihm nur das Falsche.
Warum das passiert
Raidboxes stellt Varnish vor jede Box. Der Purge läuft über ein MU-Plugin, das auf dem bekannten „Varnish HTTP Purge“ basiert. Beim Speichern eines Beitrags schickt es für jede betroffene URL einen PURGE-Request an Varnish.
Bevor der Request rausgeht, normalisiert das Plugin den Pfad. Doppelte Slashes am Ende, wie sie WPML gerne liefert, werden auf einen reduziert. Dabei hängt es aber immer einen Slash an:
// raidboxes-mu-plugins/cache/cache.php
$path = rtrim( $path, '/' ) . '/';
$purgeme = $schema . $one_host . $path . $pregex;
Das ist unauffällig, solange die Permalink-Struktur mit Slash endet. WordPress-Standard ist /%postname%/, und dann stimmt alles. Unser Projekt nutzt aber /%postname% ohne Slash. Dann passiert Folgendes:
- Ein Besucher ruft
/veranstaltung/xyzauf. Varnish cacht die Antwort unter genau diesem Schlüssel. - Die Redaktion speichert den Beitrag. Das Plugin schickt
PURGE /veranstaltung/xyz/. Mit Slash. - Unter diesem Schlüssel liegt nichts. WordPress würde
/xyz/ohnehin auf/xyzumleiten. Varnish antwortet brav, hat aber nichts gelöscht. - Der alte Cache-Eintrag unter
/veranstaltung/xyzbleibt, bis seine TTL abläuft oder jemand den ganzen Cache leert.
Warum der komplette Reset funktioniert
Der Button im Dashboard schickt einen Regex-Purge über alles. Der ignoriert den Slash. Nur der URL-genaue Purge beim Speichern geht daneben. Deshalb fällt das Problem oft erst spät auf.
So prüfst du, ob es dich betrifft
- Permalink-Struktur unter Einstellungen → Permalinks anschauen. Endet sie ohne Slash, bist du betroffen.
- Eine Seite im Browser laden, dann im Backend ändern und speichern. Bleibt der alte Stand, obwohl der Response-Header
X-Cache: HITzeigt, ist es dieser Fall. - Zur Kontrolle
curl -I https://deine-domain.at/pfadundcurl -I https://deine-domain.at/pfad/vergleichen. Die Variante mit Slash liefert einen 301, nicht die gecachte Seite.
Der Fix
Das Cache-Plugin bietet kurz vor dem Request den Filter vhp_purgeme_path an. Dort hängen wir uns ein und nehmen den Slash wieder weg. Der Filter prüft vorher, ob die Site überhaupt betroffen ist, und lässt Regex-Purges, die Startseite und Sprach-Wurzeln wie /en/ in Ruhe.
Die Datei kommt nach wp-content/mu-plugins/. MU-Plugins laden immer, brauchen keine Aktivierung und überleben Plugin-Updates von Raidboxes.
<?php
/**
* Plugin Name: Raidboxes Varnish Purge Trailing-Slash Fix
* Description: Entfernt den Trailing Slash aus URL-Purges, wenn die Permalink-Struktur ohne Slash endet.
*/
if ( ! defined( 'ABSPATH' ) ) {
return;
}
add_filter( 'vhp_purgeme_path', function ( $purgeme, $schema, $host, $path, $pregex, $p ) {
// Regex-Purge (kompletter Cache): unverändert lassen.
if ( '' !== $pregex ) {
return $purgeme;
}
// Nur betroffen, wenn die Permalink-Struktur ohne Slash endet.
$structure = (string) get_option( 'permalink_structure' );
if ( '' === $structure || '/' === substr( $structure, -1 ) ) {
return $purgeme;
}
// Startseite und Sprach-Wurzeln wie /en/ behalten ihren Slash.
if ( '' === $path || '/' === $path || preg_match( '~^/[a-z]{2}/$~i', $path ) ) {
return $purgeme;
}
$fixed = $schema . $host . untrailingslashit( $path );
if ( ! empty( $p['query'] ) && 'vhp-regex' !== $p['query'] ) {
$fixed .= '?' . $p['query'];
}
return $fixed;
}, 10, 6 );
Das war's. Nach dem Ablegen der Datei einmal den Cache komplett leeren, damit keine alten Einträge übrig bleiben. Ab dann trifft jeder Purge beim Speichern die richtige URL.
Idempotent
Sollte Raidboxes das Plugin irgendwann selbst korrigieren, richtet der Filter keinen Schaden an. Er entfernt nur einen Slash, der dann gar nicht mehr da ist.
Wozu das Ganze
Man könnte einfach die Permalink-Struktur auf Slash umstellen. Bei einer bestehenden Site mit Rankings, externen Links und einer Übersetzung heißt das aber: jede URL ändert sich, jede braucht einen Redirect, Canonicals und hreflang müssen nachziehen. Ein Filter mit 30 Zeilen ist der kleinere Eingriff.
Und die Redaktion muss nicht mehr nach jedem Speichern ins Hosting-Dashboard, um den Cache zu leeren.
WordPress zeigt alte Inhalte?
Wir betreuen WordPress-Sites auf Raidboxes, Hetzner und eigenen Servern. Wenn Caching, Redirects oder Übersetzungen nicht zusammenspielen, finden wir die Stelle.
Kontakt aufnehmen
