WordPress: Statische (Bild-)URLs in Posts dynamisch anpassen


Fügt man in WordPress ein Bild in einen Post ein, dann wird dieses dort mit seiner absoluten URL eingefügt, also zum Beispiel http://www.domainname.com/wp-content/uploads/restlicher/pfad/zum/bild.jpg. Ob ganz allgemein solche absoluten URLs sinnig sind, oder „relative“ Pfade (ohne http und Domain) besser sind, wird scheinbar viel diskutiert.

Dafür spricht bei WordPress unter anderem, dass die reine Verwendung relativer Pfade Probleme bei Feeds bereitet: Denn dann würde die relative angabe auf die Domain angewendet, von der aus der Feeds aufgerufen wurde – und das läuft mit Sicherheit ins Leere.

Dagegen spricht, dass Domainumzüge mit Inhalt so aufwändiger sind. Denn man muss dann in der Datenbank alle Links auf die neue Domain anpassen. Das ist besonders ärgerlich, wenn man zum Beispiel eine Seite in einer lokalen Testinstallation inklusive Inhalte vorbereitet (was ich gerade mache, weshalb ich auch auf dieses Thema gekommen bin). Oder wenn man nachträglich in den Einstellungen den Basispfad zu den Dateien ändert (um z.B. Bilder über eine Subdomain bereitszustellen – das habe ich beim GCP gemacht, um kürzere Bild-URLs zu haben, für optimierte, parallele Downloads der Bilder und damit bei den Anfragen keine Cookies mitgesendet werden).

Also: Nur relative URLs sind nicht gut, aber nur statische sind auch irgendwie unschön.

Mein momentaner Lösungsansatz: In der Datenbank in Posts den Basispfad für Downloads durch einen Platzhalter ersetzen, der dann beim Anzeigen wieder ersetzt wird. Beim Speichern einen Posts wird der Upload-Basispfad einfach durch {uploads} ersetzt. Beim Auslesen wird dann der Platzhalter wieder durch den Basispfad ersetzt. Vorteil: Die Datenbank wird kleiner, Domain-Wechsel und Änderungen am Basispfad werden dynamisch übernommen. Und da es für das Lesen der Posts aus der Datenbank verschiedene Filter gibt, ließe sich das ganze so auch noch anpassen, dass z.B. auf der Seite selbst relative Pfade verwendet werden, in Feeds aber absolute.

Hier die Quick-And-Dirty Lösung:

function content_substitute_uploadbase ($content) {
  $uploads = wp_upload_dir();
  $content = str_replace('href=\"'.$uploads['baseurl'], 'href=\"{uploads}', $content);
  $content = str_replace('src=\"'.$uploads['baseurl'], 'src=\"{uploads}', $content);
  return $content;
}

function content_set_uploadbase ($content) {
  $uploads = wp_upload_dir();
  $content = str_replace('{uploads}', $uploads['baseurl'], $content);
  return $content;
}

add_filter('content_save_pre','content_substitute_uploadbase',99);
add_filter('the_content','content_set_uploadbase',99);
add_filter('the_content_rss','content_set_uploadbase',99);
add_filter('the_content_feed','content_set_uploadbase',99);
add_filter('the_editor_content','content_set_uploadbase',99);