WordCamp Europe 2020 – Eine unerwartete Reise

Letztes Wochenende endete die achte Ausgabe des WordCamp Europe. Und es war eine beeindruckende Erfahrung. Ich hatte das Vergnügen erneut als Organisator mitzuwirken, aber das Ergebnis war ein ganz anderes als ich erwartet hätte.

WordCamp Europe Porto 2020

Die Reise begann vor 12 Monaten in Berlin. In den „Closing Remarks“ des WCEU 2019 kündigten wir an, dass es im nächsten Jahr nach Porto gehen würde. Ich habe mich erneut bereit erklärt, im vierten Jahr in Folge, als Organisator mitzuhelfen, in der Rolle eines Global Lead. Aber nicht alleine, ich arbeitete Seite and Seite mit Tess und Jonas. Aber das erste Mal in der Geschichte des WCEU, starteten wir mit drei Global Lead Organizern. Das Team wäre aber nicht vollständig ohne José Freitas, den Local Team Lead für Porto

Im September endete unser Call for Organizers und unser Team aus 72 Freiwilligen aus der WordPress Community war ausgewählt und wir konnten mir der Arbeit an einem Event für etwa 3500 Teilnehmende starten. Es würde meine erste Reise nach Porto und auch die erste nach Portugal werden. Doch dann begannen sich Dinge zu verändern.

Die Absage des WordCamp Asia

Der COVID-19 Ausbruch hatte gerade erst begonnen und am 12. Feburar, nur etwas eine Woche vor dem Event, wurde das WordCamp Asia auf das Jahr 2021 verschoben. Das war nicht nur ein Schock für die globale WordPress Community, sondern auch für uns als Organisationsteam des WordCamp Europe. Da wir Event nur dreieinhalb Monate später veranstalten wollten, konnten wir noch nicht absehen, ob es wie geplant stattfinden lassen könnten. Die nächsten Wochen waren sehr intensiv. Andere Events wurden ebenfalls verschoben und es wurde immer klarer, dass wir etwas unternehmen mussten. Letztendlich mussten wir am 12. März, einen Monat nach dem WordCamp Asia ebenfalls entscheiden, das WordCamp Europe in Porto auf 2021 zu verschieben. Es war eine der schwersten Entscheidungen, die wohl jeder WordCamp Europe Organizer jemals treffen mustte. Aber die Unterstützung der WordPress Community für unsere Entscheidung war überwältigend.

Alles zurück auf Anfang

Als wir die Entscheidung für die Verschiebung des „vor-Ort-Events“ beschlossen haben, wurde auch gleich die Entscheidung getroffen, das Event stattdessen online stattfinden zu lassen. Bis zu diesem Tag wurde noch kein WordCamp, das abgesagt wurde, direkt auf ein Online-Event verschoben. Es gab also eine Erfahrungen in der Community, wie man ein Event einer solchen Größe am besten online umsetzt. Wir mussten im Grunde die Arbeit am lokalen WordCamp stoppen und ganz von vorne beginnen, ein völlig anderes Event zu veranstalten.

Obwohl die Entscheidung durch das gesamte Organisationsteam getroffen wurde, konnten einige aus verschiedenen Gründen nicht dabei helfen, das Online-Event zu veranstalten. Da leider sowohl Tess, als auch Jonas nicht als Global Lead weitermachen konnten, wurde ich von Rocío Valdivia unterstützt, die zuvor unser Mentor war und nun zusammen mit mir das Global Lead Team stellte. Wir wurden von 31 weiteren Organizern unterstützt, die sich in neuen Team zusammenfanden.

Group photo of the WCEU 2020 Online organising team
Das WordCamp Europe 2020 Online Organizsationsteam

Dies war der Start des ersten WordCamp Europe Online und ein neuer Meilenstein für die Community und viele von uns.

Drei Monate Leidenschaft und harte Arbeit

Ein WordCamp Europe in neun Monaten zu organisieren ist verdammt viel Arbeit. Ein Online-Event dieser Größe in weniger als drei Monaten zu organisieren, ist sehr viel schwieriger. Mit der Leidenschaft, Hingabe und harten Arbeit eines tollen Teams haben wir es geschafft ein Event zu organisieren, das hoffentlich eine Inspiration für nachfolgende Online-WordCamps sein wird.

Wir haben sehr viel Hilfe von anderen WordCamp-Organisationsteams bekommen. Das Team des WordCamp Asia hat uns gezeigt, wie man mit der Verschiebung eines Events umgeht, das Team des WordCamp Spain hat ein echtes Community-Event organisiert und uns gezeigt, welche Dinge, die wir geplant hatten, noch einmal überdenken sollten, da wir einige der tollen Ideen übernehmen wollten. Und auch andere WordCamps auf der ganzen Welt hatten einige einmalige Dinge, von denen wir uns haben inspirieren lassen.

Das größte Wor(l)dCamp allerzeiten

Alle, die schon einmal ein WordCamp organisiert haben werden die Erfahrung gemacht haben, dass es von externen Dienstleistern oft als „WorldCamp“ falsch geschrieben wird. Dieses Mal traf diese Bezeichnung absolut zu. Auch wenn der Fokus auf der europäischen Community liegt, wollten wir so vielen Teilnehmenden wie möglich die Teilnahme ermöglichen. Daher habe wir die Zeiten auf 15:00 bis 20:00 Uhr mitteleuropäische Sommerzeit für alle drei Tage gelegt. So konnten Teilnehmende aus Europe an einem Nachmittag teilnehmen, ohne unbedingt Urlaub nehmen zu müssen. Aber auch Teilnehmenden auf beiden Seiten des Pazifiks war hierdurch eine Teilnahme am frühen morgen oder späten Abend möglich.

Für das WordCamp in Porto hätten wir mit 3500 verkauften Tickets und mehr als 3000 Personen vor Ort gerechnet. Letztes Jahr hatten wir mehr als 3000 Tickets verkauft und konnten mehr als 2700 Teilnehmende begrüßen, die aus über 90 Ländern kamen. Dieses Jahr haben wir mehr als 8600 Tickets für den Live-Stream verkauft und in den ersten 24 Stunden gab es mehr als 9000 Aufrufe für Track 1 der Vorträge vom Freitag – einige davon im Live-Stream und andere zeitversetzt in der Aufzeichnung. Aber die Zahl, die am meisten beeindruckte, war die Anzahl von unterschiedlichen Ländern der Anmeldungen. Wir hatten Teilnehmende aus 140 Ländern, also wirklich ein „WorldCamp“:

Weltkarte der Teilnehmenden des WordCamp Europe 2020 Online

Eine Erfahrung, die ich niemals erwartet hätte

Ich habe bisher an jedem WordCamp Europe teilgenommen und bin seit 2017 im Organisationsteam aktiv. Als wir letztes Jahr das Event in Berlin hatten, fühlte es sich für mich ganz anders an. Dieses Jahr war der Unterschied noch sehr viel größer. Normalerweise reise ich ein paar Tage vorher in ein fremdes Land und verbringe Zeit mit alten und neuen Freunden. Dieses Jahr mussten wir alle von unseren eigenen vier Wänden aus teilnehmen und organisieren. Alle haben den persönlichen Kontakt mit anderen vermisst. Aber die Rückmeldungen aus der Community waren überwältigend!

Ein riesengroßer Dank an die Commmunity!

Ich kann noch nicht in Worte fassen, wie ich mich fühle. Auch eine Woche nach dem Event noch nicht. Die Erfahrung ist noch immer sehr frisch und schwer zu beschreiben. Aber mehr als alles andere fühle ich tiefe Dankbarkeit. Für meine Co-Organizer, für die COmmunity, die an den Vorträgen und am Contributor Day teilgenommen haben, für die Speaker, die „Emcees“ und die anderen Freiwilligen, für die Sponsoren, die geholfen haben, das Event zu finanzieren und auch für alle anderen Personen und Organisationen, die dabei geholfen haben, all dies zu ermöglichen. Auch wenn wir nicht die Möglichkeit hatten und mit Freunden zu treffen, haben wir so vielen Menschen mehr ermöglich, daran teilzunehmen.

Wir sehen uns 2021 in Porto!

Ich hoffe, dass viele von euch letzte Woche beim WCEU 2020 Online dabei waren. Nächstes Jahr werden wir dann hoffentlich die Gelegenheit haben, uns endlich in Porto zu treffen. Ich werde erneut Teil des Organisationsteams als Global Lead sein. Ich werde hierbei mit Lesley, Taeke und Moncho zusammenarbeiten. Falls auch ihr nun Lust bekommen habt dabei zu helfen, ein solches Event zu veranstalten, dann antwortet auf den Call for Organizers. Und falls ihr nur teilnehmen wollt, dann sichert euch schon heute euer Ticket.

Bis nächstes Jahr beim WordCamp Europe im June 2021 in Porto!

Schnellere lokale Entwicklung durch die Blockierung externen Requests

Ich entwickle Seiten immer lokal. Bei der Entwicklung verwende ich dabei Docker was ich in einer zukünftigen Blogreihe vorstellen möchte. Manchmal erlebe ich bei der lokalen Entwicklung sehr lange Request-Zeiten, vor allem im Backend. Da ich normalerweise während der Entwicklung immer das Query Monitor Plugin einsetze, konnte ich schnell feststellen, dass es an einigen HTTP Requests lag, die fehlschlugen. Dieser wurden entweder vom Core oder Premium Plugins/Themes ausgelöst, die nach Updates gesucht haben.

Externe Requests blockieren

Um diese Fehler zu beheben habe ich zuerst einzeln Filters oder Actions deaktiviert, die diese Requests auslösen. Dann bin ich aber auf einen globalen Filter gestoßen, der das noch vereinfacht:

add_filter( 'pre_http_request', '__return_true', 100 );

Das ist nicht der einfachste oder beste Weg, denn er blockiert sämtliche Requests, egal auf welchen Host sie zugreifen. Um nur externe Requests zu blockieren, kann man stattdessen einfach folgende Konstante setzen:

define( 'WP_HTTP_BLOCK_EXTERNAL', true );

Das blockiert keine lokalen Requests, die eventuell für Cronjobs oder ähnliche Funktionalitäten gebraucht werden.

Bestimme externe Hosts erlauben

Manchmal kann man aber nicht einfach alle externen Requests blockieren, da einige Plugins/Themes, die man gerade entwickelt, externe APIs verwenden. Daher kann man mit einer anderen Konstante über eine kommagetrennte Liste diese Hosts definieren:

define( 'WP_ACCESSIBLE_HOSTS', 'example.com, *.example.com' );

Wie ihr in meinem Beispiel sehen könnt, sind auch Wildcard-Subdomains möglich. Hierbei wird über einen regulären Ausdruck das Suchmuster auf eine beliebige Tiefe an Subdomains geprüft.

Mehr als nur HTTP Requests blockieren

Die beiden Konstanten helfen dabei HTTP Requests zu blockieren, die durch WordPRess ausgelöst werden. Dies funktioniert aber nur, wenn diese die WordPreSS API Funktionen für HTTP Requests verwenden. Wenn ein Plugin/Theme allerdings mit file_get_contents, curl oder ähnlichem arbeitet, werden solche Requests nicht blockiert.

Weiterhin werden auch keine Requests blockiert, die vom Browser aus gemacht werden. Wenn man auch solche Requests blockieren will, dann kann man das Plugin „Offline Mode“ von Frank Bültge einsetzen, das man direkt von GitHub aus runterladen und installieren kann. Es versucht so viele externe Requests wie möglich zu blockieren.

Fazit

Lokal zu entwickeln ist immer der beste Weg, wenn man an einem Projekt arbeitet. Sollte man aber eine instabile Internetverbindung haben (oder gar keine, wie z.B. im Flugzeug), dann kann das die lokale Entwicklung extrem verlangsamen. Mit Hilfe der beiden vorgestellten Konstanten mann man die gewohnte Geschwindigkeit wieder zurückholen.

Wiederverwendbare Blöcke verwalten

Ich liebe wiederverwendbare Blöcke! OK, aktuell sprechen eher alle über „(Block) Patterns“ und die werden sicher großartig. Aber viele kennen noch immer die wiederverwendbare Blöcke nicht oder wissen einfach nicht, wie praktisch sie sind.

Was ist ein wiederverwendbarer Blöcke

Nun, wie der Name es schon andeutet ist es ein Block, der wiederverwendet werden kann. Irgendwo. Da ein solches Block auch ein Gruppen-Block sein kann, könnte ein wiederverwendbarer Block also eine Sammlung von Blöcken wiederverwendbar machen. Sobald man einen solchen Block erstelle hat, kann man den gleichen „Inhalt“ in mehreren Beiträgen, Seiten oder anderen Inhaltstypen verwenden. In der Zukunft wird das dann auch in Widgets oder anderen „blockbasierten Bereichen“ möglich sein.

Aber wie findet man einen solchen wiederverwendbaren Block? Der einfachste Weg ist es, auf einen der vielen „Block hinzufügen“ Buttons (der quadratische Button mit dem Plus-Zeichen) zu klicken und dort nach dem Namen zu suchen oder ganz nach unten zu scrollen:

Man kann natürlich auch die „Suche nach einem Block“ verwenden und dort den Namen des Blocks (in diesem Beispiel „Kontakt“) eintippen oder aber indem man die Suche per „Slash Suche“ (Vorwärtsschrägstrich) verwendet um schneller nach danach zu suchen. Neu in dieser Ansicht ist auch der Link „Alle wiederverwendbaren Blöcke“ verwalten am Ende der Liste. Dieser war zuvor unter „Mehr Werkzeuge & Optionen“ zu finden:

Wenn man auf einen der beiden Links klickt, wird man auf die „Blöcke“ Übersicht weitergeleitet.

Die Blöcke verwalten

Die Liste der Blöcke die ziemlich genau so aus wie alle anderen Übersichten von Inhaltstypen. Das ist auch keine große Überraschung, denn auch wiederverwendbare Blöcke werden als Inhaltstyp wp_block in der Datenbank gespeichert.

Auf der Verwaltungsübersicht kann man einen existierenden Block über „Bearbeiten“ im Block-Editor öffnen, dort bearbeiten und die Änderungen speichern. Man kann ebenfalls über „Block hinuzufügen“ einen neuen Block erstellen, ohne dabei erst eine Seite oder einen Beitrag verwenden zu müssen, um dann einen vorhandenen normalen Block in einen wiederverwendbaren zu konvertieren.

Aber vermutlich eine der nützlichsten Funktionen, die man hier findet ist das „Als JSON exportieren“ eines individuellen Blocks bzw. der „Import von JSON“. Damit kann man sehr einfach wiedererwendbare Blöcke zwischen verschiedenen WordPress-Installationen migrieren.

Bonus

Wenn ihr genau aufgepasst habt, dann ist euch vielleicht aufgefallen, dass am Ende des letzten Screenshots ein Link „Blöcke“ unter dem Menüpunkt „Wekrzeuge“ zu sehen ist. Dieser Link wäre normalerweise nicht hier. Wenn man zur Verwaltung der Blöcke navigiert, dann ist man „nirgends“. Die Übersicht ist versteckt und man erreicht sie nicht über die linke Navigation. Bevor es die zwei erwähnten Links gab, hat man diese Übersicht noch viel schwieriger gefunden. Daher hatte ich damals ein kleines Hilfsplugin geschrieben, um diesen Menüpunkt „Blöcke“ zu „Werkzeuge“ hinzuzufügen. Das hat es in einem Projekt sehr viel einfacher gemacht, zu dieser Übersicht zu gelangen. Wenn ihr das auch bei euch haben wollt, dann ladet euch das Plugin einfach von GIST runter und installiert es.

Fazit

Selbst wenn wiederverwendbare Blöcke nicht mehr so viel Verwendung finden, wenn die „Pattern“ da sind, so gibt es dennoch Anwendungsfälle, in denen man „synchronisierte Inhalte“ auf einer Seite haben möchte. Zu wissen, wie man diese Blöcke findet, kann einem dabei die Arbeit sehr erleichert.

Suchmaschinen daran hindern eine Staging-Seite zu indizieren

Wenn man an einer Webseite arbeitet, egal ob diese bereits live gegangen ist, oder es sich um ein neues Projekt handelt, man sollte dabei immer eine Kopie der Seite in einer Staging-Umgebung haben. Aber man möchte ganz sicher nicht, dass diese Seite von einer Suchmaschine indiziert wird. In diesem Beitrag möchte ich euch ein paar Wege vorstellen, wie man eine solche Indizierung verhindern kann.

Methode 1: Die Standard-Einstellung nutzen

Im Dashboard der Seite navigiert ihr zum Punkt „Einstellungen | Lesen“. Dort findet ihr die Option „Sichtbarkeit für Suchmaschinen“ in könnt hier die Checkbox „Suchmaschinen davon abhalten, diese Website zu indexieren“ aktivieren. Dies erstellt dynamisch eine sogenannte „robots.txt“ Datei, die Suchmaschinen mitteilt, dass eure Seite nicht indiziert werden soll. Wie der Hinweis „Es ist Sache der Suchmaschinen, dieser Bitte nachzukommen“ allerdings ausdrückt ist dies nur eine Anweisung an Suchmaschinen dies nicht zu tun, manche werden die Seite vielleicht dennoch indizieren.

Methode 2: Verhindern der Indizierung durch die Serverkonfiguration

Die erste Methode funktioniert eigentlich ziemlich gut. Es gibt nur ein großes Problem damit. Diese Einstellung wird in der Datenbank gespeichert und kann einfach überschrieben werden? Wie? Nun, es kommt oft vor, dass man sich bei der Arbeit an einer Staging-Seite mal einen aktuellen Stand der Live-Datenbank importiert. In dieser ist die Einstellungen natürlich nicht aktiviert. Denkt ihr immer daran, das dann sofort nachzuholen? Vielleicht vergesst ihr es mal.

Daher kann man die Indizierung auch über die Serverkonfiguration verhindern und gefahrlos eine Live-Datebank importieren. Hierzu fügt ihr einfach folgende Zeilen in die Konfiguration ein:

Header set X-Robots-Tag "noindex"
Header merge X-Robots-Tag "noarchive"

Das könnt ihr in der .htaccess Datei der Staging Seite machen. Das ist auch der beste Weg, wenn man die globale Konfiguration der Servers nicht bearbeiten kann. Aber auch hier besteht die Gefahr, dass man vielleicht versehentlich die .htaccess Datei mit der Version der Live-Seite überschreibt.

Falls ihr einen eigenen Staging-Server habt und nicht möchtet, dass irgendeine Seite dieses Severs indiziert wird, dann fügt die beiden Zeilen z.B. in eine globale Konfiguratoinsdatei wie /etc/apache2/apache2.conf oder eine ähnliche Datei ein.

Methode 3: Verwendet ein Wartungsplugin

Durch den Einsatz eines Wartung (oder englisch „Maintenance“) Plugins kann man auch verhindern, dass die Staging-Seite indiziert wird. Damit wird oft ein Passwort vor die gesamte Seite geschaltet oder man muss sich einloggen, um die eigentliche Seite zu sehen. Damit kann man auch anderen Zugriff auf die Seite geben, aber eben nicht jedem. Diese Methode hat leider ebenfalls das zuvor beschriebene Problem, denn der Zustand der gerade aktiven Plugins wird auch in der Datenbank gespeichert und importiert man eine Live-Datenbank, muss man daran denken, das Plugin danach wieder zu aktivieren.

Methode 4: Verwendet eine „Basic Authentication“

Mit der „Basic Authentication“, oder auch „htaccess Schutz“ genannt, könnt ihr die gesamte Seite ohne ein zusätzliches Plugin schützen. Bei einem Apache-Webserver fügt man hierbei ein paar Zeilen in die .htaccess Datei und alle, die die Seite aufrufen, müssen zuerst einen Benutzernamen und ein Passwort eingeben. Diese Methode ist also sicher, wenn man die Live-Datenbank importiert, aber wenn die .htaccess Datei mit der Version der Live-Seite überschreibt, muss man den Schutz erneut einrichten. Daher bietet es sich auch hier an, die Einstellung global (pro Seite) in der Serverkonfiguration zu hinterlegen.

Fazit

Es gibt viele verschiedene Wege um zu verhindern, dass eine Staging-Website durch Suchmaschinen indiziert wird. Welche Methode auch immer ihr verwendet, ihr solltet immer prüfen, ob dieser Schutz noch funktioniert, wenn ihr etwas von einer Live-Seite importiert habt. Man kann zwar eine indizierte Seite aus einer Suchmaschine löschen lassen, ihr müsst dann aber jeder Seite über deren URL in jeder einzelnen Suchmaschinen über die individuellen Werkzeuge manuell löschen lassen.

WordPress-Domain und Dateipfade in der Datenbank aktualisieren

Im letzten Blogbeitrag habe ich euch gezeigt, wie ich WordPres Websites auf einen andern Server migriere. In Schritt 7 bin ich auf die Übersetzung der Domain in der Datenbank eingegangen. Dies ist aber nicht die einzige Ersetzung, die man eventuell machen muss. Daher soll es im heutigen Beitrage darum gehen, welche anderen Ersetzungen eventuell noch notwendig sind.

Schauen wir uns also noch einmal die grundlegendste Ersetzung an. Mit diesem Befehl wird die Domain in allen Tabellen ersetzt, die den Präfix der aktuellen WordPress Installation haben:

wp search-replace "https://staging.example.com" "https://example.com" --all-tables-with-prefix

Dieser Befehl ersetzt die Domain in allen Spalten in allen Tabellen einer WordPress-Datenbank, auch wenn diese als serialisiertes PHP-Objekt gespeichert sind.

Zusätzlich sollte auch der Dateipfad auf dem Server ersetzt werden, da dieser von einigen Plugins verwendet wird:

wp search-replace "/home/staging.example.com" "/home/example.com" --all-tables-with-prefix

Weitere alte Domains suchen

Nach der Durchführung dieses Befehls sollten die meisten Domains bereits ersetzt sein. Man kann aber auch sehr einfach prüfen, ob es den alten Wert noch gibt. Auch hierbei hilft uns die WP-CLI:

wp db search "https://staging.example.com"

Weitere Ersetzungen

Leider gibt es sehr viele Plugins, die komplexe Daten in anderen Formaten speichern. Daher ist es empfehlenswert, auch folgende Ersetzungen durchzuführen, sofern die Suche zuvor noch Ergebnisse geliefert hat.

SuchmusterErsetzungBemerkung
http://example.comhttps://example.comNeue Domains ohne SSL
http://staging.example.comhttps://example.comAlte Domains ohne SSL
//staging.example.com//example.comprotokol-relative Pfade
https:\/\/staging.example.comhttps:\/\/example.comJSON-Objekte (ausführen für alle vorherigen Muster)
@staging.example.com@example.comE-Mail-Domains (optional, da nicht immer gewünscht)
staging.example.comexample.comGefährlich!
Ersetzungsmuster bei Domainumstellung

Es sind einige Varianten zu beachten. Für die ersten vier Ersetzungen sollte man zusätzlich alle Slashes „escapen“, falls Objekte als JSON-String gespeichert wurden. Die E-Mail-Adressen sind optional, da auf dem neuen System eventuell keine E-Mails versendet werden sollten (z.B. bei Übertrag von Live zu Staging) oder falls diese im Frontend ausgegeben werden und man nicht möchte, dass hier eine andere Domain zu sehen ist.

Die letzte Ersetzung scheint die beste zu sein, da sie alle vorherigen umfasst. Aber sie kann potentiell auch zu schwierig zu findenden Problemen führen, da der Domainname bespielsweise in Bildnamen vorhanden sein könnte, die dann auf einmal nicht mehr angezeigt werden. Man sollte also am besten niemals nur den Domainnamen ersetzen.

Weitere Maßnahmen

Oft werden in Themes, Plugins oder auf dem Server Caches eingesetzt. Oft haben diese eigene Mechanismen, um diese zu leeren.

Fusion Builder (z.B. Avada Theme)

Unter „Avada/Themename | Theme Options | Performane | Reset Fusion Caches“ über den gleichnamigen Button „Reset Fusion Caches“ alle Dateien im Cache löschen.

Autoptimize

In der Adminbar findet man einen Eintrag „Autoptimize“ und am Ende einen Link „Delete Cache“.

PageSpeed

Den PageSpeed-Cache kann man nur über den Server leeren. Nachdem man sich zu diesem verbunden hat, muss man folgenden Befehl ausführen:

touch /var/cache/mod_pagespeed/cache.flush

Es kann ein paar Sekunden dauern, bis der Cache vollständig geleert ist. Nachdem er leer ist, entfernt man die Datei einfach wieder:

rm /var/cache/mod_pagespeed/cache.flush

Weitere Infrormationen zum partiellen Leeren des Caches findet ihr in der PageSpeed Dokumentation.

Eine WordPress-Installation in weniger als 5 Minuten migrieren

Ich arbeiten an WordPress Projekten immer lokal. Bei vielen Projekten gibt es zusätzlich einen Staging-Server. Die Migration einer WordPress-Installation ist also eine sehr häufig vorkommende Aufgabe für mich. Daher ist ein guter Prozess hier sehr wichtig.

Einfache Migration ohne Plugins

Wenn ich eine Seite migriere, dann verwende ich immer die WP-CLI. Die einzige Voraussetzung hierfür ist ein SSH-Zugang zum Zielserver. Mein Migrationsprozess unterteilt sich in wenige Schritte:

1. Dump der Quelldatenbank

Eine WordPress-Installation besteht aus zwei Teilen, der Datenbank und dem Dateisystem. Um einen Dump der Datenbank zu erstellen, muss nur der folgende Befehl im Hauptverzeichnis von WordPress (dem „document root“) ausgeführt werden:

wp db export
Success: Exported to 'wp_project-staging-2020-04-05-a2aa75c.sql'.

Der Dateiname startet mit dem Namen der Datenbank, gefolgt vom aktuellen Datum und einem zufälligen hexadezimalen Hash. Das ist sehr praktisch für den zweiten Schritt.

2. Packen aller Dateien auf der Quelle

Jetzt sind wir soweit, alle Dateien auf dem Quellserver zu packen. Das erledigen wir einfach mit zip, gzip oder einem anderen Tool:

zip -r wp_project-staging-2020-04-05-a2aa75c.zip .

Als Dateinamen verwenden wir einfach den gleich Namen wie beim Datenbank-Dump und ändern hierbei lediglich die Dateiendung von .sql zu .zip im Befehl. Das „schützt“ den Dateinamen davor, einfach erraten werden zu können. Wenn man die Datei einfach nur dump.zip nennen würde, könnte sonst jeder einfach die Datei runterladen.

3. Übertragung der Datei auf den neuen Server

Jetzt ist es an der Zeit, die Datei auf den neuen Server zu übertragen. Das kann man über verschiedene Wege tun. Ein sehr einfacher ist die Verwendung von curl, wget oder ähnlichem:

wget https://staging.example.com/wp_project-staging-2020-04-05-a2aa75c.zip

Wenn man die Dateien von einem lokalen System überträgt, wird man vermutlich FTP verwenden, da man die Datei ja nicht per curl/wget von einer lokalen Domain laden kann.

4. Entpacken der Datei im Ziel

Der nächste Schritt ist sehr nahe liegend. Wir müssen die Datei im Ziel entpacken. Hat man eine ZIP-Datei verwendet, führt man einfach folgenden Befehl aus:

unzip wp_project-staging-2020-04-05-a2aa75c.zip

Wenn man die Dateien in Schritt 2 im Hautpverzeichnis gepackt hat, dann sollten die Dateien auch wieder im Hauptverzeichnis auf dem neuen Server einpackt werden und nicht in einem Unterordner.

5. Aktualisierung der Konfiguration

Bevor wir das Projekt auf dem neuen Server nutzen können, müssen wir die wp-config.php aktualisieren. Vermutlich nur alle Werte, die mit DB_ anfangen.

6. Import der Datenbank

Nun können wir die Datenbank importieren. Wenn die Datenbank auf dem neuen Server noch nicht existiert, kann sie entweder über das Verwaltungsprogramm der Hosters angelegt werden, oder ebenfalls mit einem einfachen WP-CLI Befehl (sofern der Datenbank-User dazu die Berechtigungen hat):

wp db create

Sobald die Datenkbank erstellt ist, können wir den Dump ähnlich zu Schritt 1 importieren:

wp db import wp_project-staging-2020-04-05-a2aa75c.sql

7. Aktualisierung der Domain in der Datenbank

Wie ihr vermutlich wisst, speichert WordPress alle Domainpfade als absolute Pfade in der Datenbank. Daher müssen diese ersetzt werden. Das funktioniert mit einem Plugin, aber noch einfacher über die WP-CLI:

wp search-replace "https://staging.example.com" "https://example.com"

Dies ist die einfachste Ersetzung. In manchen Fällen müssen aber noch andere Ersetzungen durchgeführt werden. Das werde ich in einem zukünftigen Beitrag behandeln.

Fazit

Die Migration eines WordPress-Projekts sollte so einfach und schnell wie möglich sein, gerade dann, wenn man diese Aufgabe sehr regelmäßig erledigt. Mein Ansatz benötigt nur 2 Befehle auf dem Quellserver und 4-5 auf dem Zielserver. Der Teil, der in der Regel die meiste Zeit benötigt, ist das Packen, Übertragen und Entpacken, welches länger dauert, je größer das Projekt ist. Für ein kleines Projekt mit nur wenigen Inhalten dauert es aber jeweils oft weniger als 10 Sekunden.

Ich hoffe, diese kleine Anleitung konnte euch helfen, damit eure nächste Migration genau so schnell und einfach geschieht wie bei mir. Falls ihr einen anderen Ansatz habt, der auch sehr praktisch ist, hinterlasst gerne einen Kommentar hierzu und stellt ihn vor.

Vielen Dank an die WordPress-Community!

Die letzte Woche war hart. Ich meine so richtig hart. Erst vor zwei Wochen habe ich an dieser Stelle allen Organisationsteam gedankt, die Konferenzen absagen mussten. Nun befinde ich mich in genau der gleichen Situation.

Die Absage des WordCamp Europe 2020

Am Donnestagabend vorletzte Woche hatte ich ein Telefonat mit Tess und Jonas, den anderen beiden Global-Leads des WCEU 2020 und mit Rocío, unserer Mentorin, sowie mit Andrea, die das globale WordPress-Community-Team leitet.

Wir haben über einen Zeitplan für die nächsten Wochen und Monate gesprochen und uns einen Plan gemacht, um das WordCamo Europe in Porto im Juni diesem Jahres durchführen zu können. Am 5. März sahen die Dinge noch ganz gut aus. Es gab nur wenige Fälle in Portugal und nur Italien hatte in Europe mit sehr vielen Fällen zu kämpfen. Wir beschlossen also, mit der Planung des Events im Juni weiterzufahren und waren optimistisch, dass es noch stattfinden könne. Wir haben uns bis Anfang April für eine Entscheidung Zeit lassen wollen.

Die letzten Tage

Nach diesem Meeting wurden die Dinge mit jedem Tag schlechter. Konferenzen in Europa wurden abgesagt. Am 9. Märze traf es eine große Joomla Konferenz in Lissabon, die nur eine Woche vor dem WordCamp Europe 2020 in Porto stattfinden sollte.

Am 11. März hat das globale Community-Team Empfehlungen herausgegeben, dass alle Veranstaltungen bis einschließlich 1. Juni abgesagt oder verschoben werden sollten. Da das WCEU 2020 vom 4. – 6. Juni geplant war, also nur bis ein paar Tage zuvor.

Schließlich hatten wir letzten Donnerstag, nur eine Woche nach unsere „Krisensitzung“ eine Videokonferenz mit allen Organisatoren, in der wir beschlossen haben, dass wir das WordCamp Europe 2020 absagen und auf das Jahr 2021, ebenfalls in Porto, verschieben werden.

Danke an unserer Communtiy

Die Reaktionen, die auf unserer Ankündigung folgten, waren überwältigend. Wir haben viele empathische Nachichten auf Twitter und anderen Kanälen erhalten. Viele liebe Menschen aus der WordPress-Community haben mich direkt angeschrieben und gefragt, wie es mir geht und Hilfe angeboten.

Darum liebe ich diese Communtiy. In guten und in harten Zeiten unterstützen und helfen wird uns gegenseitig. Das ist auch der Grund, wieso das Organisationsteam positiv in die Zukunft schaut und noch intersiver am WordCamp Europe 2021 in Porto arbeiten wird.

Vielen Dank WordPress-Community ❤

Vielen Dank die Organisationsteams!

Ich hatte für diese Woche einen anderes Thema für den #projekt26 Beitrag geplant, aber die Ereignisse der letzten Wochen haben mich dazu veranlasst über etwas anderes zu schreiben.

WordCamp Asia 2020

Der Februar ist vorüber und es war ein sehr ereignisreicher Monat für mich. Oder sollte ich eher sagen, er war es nicht? Ich habe mich sehr auf keine erst Asienreise gefreut, meine Teilnahme am WordCamp Asia in Bangkok in Thailand. Es war vom 21. – 23. Feburar geplant und ich hatte Flug und Hotel schon vor Wochen geplant sowie Urlaub eingereicht (da Teilnahmen an WordCamps nicht Teil meines Jobs sind). Ich habe mich auch auf ein paar schöne warme Tage mit vielen alten und neuen Freunden gefreut. Aber am 12. Februar bekam ich dann überraschend die traurige Nachricht, dass das WordCamp Asia abgesagt werden musste.

Ich hatte großes Glück und konnte mein Hotel und meinem Flug kostenfrei stornieren. Daher habe ich meine gesamte erste Asienreise für dieses Jahr abgesagt.

CloudFest 2020 Hackathon

Diesen Monat vom 14. – 16. März werde ich meinen ersten echten Hackathon besuchen. Dieser wird nicht nur für Mitglieder der WordPress-Community, sondern für viele andere tolle Menschen aus anderen OpenSource-Communities veranstaltet, sowie Firmen, die sich auf das Thema Hosting spezialisiert haben. Aber auch an dieser Konferenz werde ich nicht teilnehmen, dann das CloudFest musste ebenfalls abgesagt werden.

WordCamp Retreat Soltau 2020

Vor zwei Jahren habe ich eines der besten WordCamps besucht, auf denen ich je als Teilnehmer dabei sein konnte. Es war keine normale Veranstaltung, auf der man sich für einen „Arbeitstag“ zu Vorträgen und Workshop traf. Stattdessen verbrachte man 24 Stunden für über mehrere Tage mit allen anderen Teilnehmenden im selben Hotel und konnte neben Vorträgen auch an anderen Aktivitäten teilnehmen. Dieses Jahr war es vom 30. April bis zum 3. Mai geplant. Es war geplant, da auch diese Veranstaltung vor einer Woche abgesagt und auf das nächste Jahr verschoben wurde.

Danke Organisationsteams!

Falls ihr euch nun wundert, wieso ich mich dafür bedankte, dass diese Veranstaltungen abgesagt wurden, dann ist der Grund ganz einfach. Selbstverständlich bin ich sehr traurig darüber, dass ich an an diesen Events nicht teilnehmen kann … zumindest nicht dieses Jahr. Alle Organisationsteams haben aber angekündigt im nächsten Jahr die Veranstaltung erneut zu organisieren. Viele davon am gleichen Ort und ungefähr zur gleichen Zeit.

Ich habe bereits vier WordPress Konferenzen in Berlin organisiert und stecke gerade zum vierten Mal mitten in der Organisation des WordCamp Europe. Ich weiß, wie viel Zeit, Energie und Leidenschaft in die Organisation eines solchen Community-Events fließt. Ich kann mir nur vorstellen, wie schwer es für alle Beteiligten gewesen sein muss, diese Veranstaltungen abzusagen (es gab auch noch weitere).

Mit der Absage einer Veranstaltung ist die Arbeit aber nicht getan und man kann nicht einfach aufhören zu arbeiten. Man muss sich mit den ganzen Nachwehen einer solchen Absage beschäftigen, sämtliche Verträge kündigen und so vielen Menschen wie möglich eine Rückerstattung ermöglichen. Man wird außerdem mit vielen negativen Rückmeldungen zu kämpfen haben, denn nicht alle werden verstehen, wieso die Absage unausweichlich war (wie z.B. „es gab doch gar keine Corona-Infektionen in dem Gebiet“). Allen Personen, die an der Organisation und harten Entscheidung zur Absage beteiligten waren, gilt unsere Unterstützung.

Wenn es euch also wie mir geht und eine Veranstaltung, an der ihr teilnehmen wolltet, wurde abgesagt, dann nehmt euch bitte einen Moment und sendet ein Vielen Dank an das Organisationsteam, denn sie haben es sich mit ihrer Entscheidung sicher nicht einfach gemacht und diese schwierige Entscheidung im besten Interesse der Gesundheit der Community, sowohl der pysischen, als auch der psychischen, gemacht. Und bitte unterstützt sie dadurch, dass ihr auch im nächsten Jahr wieder teilnehmen werdet. Vielleicht ja sogar durch freiwillige Mithilfe auf der Veranstaltung als Volunteer. Damit erhalten ihr den besten Einblick darin, mit wie viel Leidenschaft alle daran arbeiten für uns allen ein tolles Event zu veranstalten!

Danke Ogranisationsteams ❤

Bildkonvertierung mit ImageMagick reparieren

Seit Version 4.7 erstellt WordPress von einer hochgeladenen PDF-Datei einen Screenshot der ersten Seite. Hierzu muss ImageMagick sowie die zugehörige PHP-Extension installiert sein.

Auf einem Server mit Ubuntu 18 funktionierte es aber trotzdem noch nicht, obwohl beide Komponenten installiert waren. Daher habe ich zum Test versucht, eine Konvertierung direkt auf der Kommandozeile durchzuführen:

convert test-pdf.pdf test-pdf.png

Dabei bekam ich dann folgende Fehlermeldung angezeigt:

convert: not authorized `test-pdf.pdf' @ error/constitute.c/ReadImage/412.
convert: no images defined `test-pdf.png' @ error/convert.c/ConvertImageCommand/3210.

Nach etwas Recherche bin ich dann auf die Lösung für das Problem gestoßen. ImageMagick hat seit einigen Versionen eine Security-Policy umgesetzt, in der man einschränken kann, welche Dateiformat umgewandelt werden dürfen. Leider gehört PDF zu den Erweiterungen, die nicht standardmäßig unter Ubuntu 18 konvertiert werden können. Die Policies kann man aber in der Datei /etc/ImageMagick-6/policy.xml anpassen:

<policymap>
  <!-- ... -->
  <policy domain="path" rights="none" pattern="@*" />
  <!-- disable ghostscript format types -->
  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="EPS" />
  <policy domain="coder" rights="none" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="XPS" />
</policymap>

Hier kann man entweder die Zeile für das PDF-Format mit einem XML-Kommentar auskommentieren oder aber die rights auf read einstellen:

<policymap>
  <!-- ... -->
  <policy domain="path" rights="none" pattern="@*" />
  <!-- disable ghostscript format types -->
  <policy domain="coder" rights="none" pattern="PS" />
  <policy domain="coder" rights="none" pattern="EPS" />
  <policy domain="coder" rights="read" pattern="PDF" />
  <policy domain="coder" rights="none" pattern="XPS" />
</policymap>

Nun kann man auf der Kommandozeile noch einmal testen, ob die Einstellung angenommen wurde (in diesem Fall gibt das convert Kommando keine Rückmeldung). Anschließend sollte die automatische Konvertierung beim Upload von PDF Dateien in die WordPress-Mediathek auch funktionieren.

Fehlende Bilder von Live-Server im Entwicklungs-System anzeigen

Wenn man an einem bestehenden Projekt arbeite, das bereits live gegangen ist, dann ist es manchmal notwendig, dass man sich den aktuellen Stand einer Datenbank vom Live-System holt, um lokal Dinge zu testen. Aber wie sieht es mit den Mediendateien aus, die in der Zwischenzeit dazu gekommen sind und die schnell mehrere Gigabyte an Größe umfassen? Nun, oft wird man auch diese benötigen, vor allem, wenn man am Design arbeitet. Aber wie hält man diese auf dem aktuellen Stand mit der Live-Seite? Die gute Nachricht: das ist gar nicht notwendig und in diesem Blogbeitrag möchte ich euch zeigen, wie man es anders lösen kann.

Nehmen wir also an, dass ich euch gerade eine aktuelle Kopie der Live-Datenbank in euer lokalen Entwicklungs-System gespielt habt. Dann werden wahrscheinliche einige Bilder nicht angezeigt, da ihr ja die URL in der Datenbank auf die lokale Domain geändert habt und diese Bilder lokal nicht gefunden werden können. Ihr könntet auch nun natürlich mit dem Live-System verbinden und alle Bilder synchronisieren, was aber schnell viele Megabyte oder Gigabyte benötigt. Wenn ihr gleichzeitig an mehreren Projekten arbeitet, habt ihr sehr schnell denn Platz auf eurer Festplatte verbraucht. Ihr könnt aber auch einfach den gesamten Uploads-Ordner inklusive aller Unterordner (oder zumindest alle mit den hochgeladenen Mediendateien) löschen und sie stattdessen von der Live-Seite laden lassen.

Fehlende Dateien vom Live-Server laden

Falls ihr in eurer lokalen Entwicklungsumgebungen einen Apache Webserver einsetzt, müsst ihr hierzu lediglich folgende Zeilen in eure .htaccess eintragen:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wp-content/uploads/(.*) https://xyz.com/wp-content/uploads/$1 [R=302,L]
</IfModule>

Diese Zeilen fügt man ganz oben in der .htaccess Datei vor allen anderen Angaben ein.

Wie es funktioniert

Der Apache Server prüft über die beiden RewriteCond, ob die Datei oder der Ordner, der angefragt wird, nicht existiert. Sollte dies der Fall sein greift die RewriteRule, die alle Aufrufe von Dateien im Ordner wp-content/uploads auf die Live-Seite umleitet.

Es werden also alle Bilder, die nicht lokal vorhanden sind, vom Live-Server abgerufen. Ist bei diesem das Caching richtig eingestellt, passiert dies in der Regel auch nur einmal pro individueller URL.

Somit kann man nun alle Bilder auch auf der lokalen Umgebung sehen, ohne diese vorher runterladen zu müssen. Man kann die Bilder sogar lokal über die Medienübersicht bearbeiten. Sobald man die Datei speichert, wird die Originaldatei sowie die anderen Bildgrößen im lokalen System abspeichert. Diese Änderungen werden aber natürlich nicht wieder ins Live-System zurückgespielt. Man kann hiermit aber schnell und gefahrlos lokale testen.

Einige Einschränkungen

Diese Technik funktioniert in den allermeisten Fällen. Falls der Webserver nicht bei der Generierung des HTML-Codes allerdings prüft, ob die Datei auch wirklich lokal vorhanden ist, dann scheitert es, denn in der Regel passieren solche Prüfungen auf die Existenz von Dateien über eine PHP-Funktion, die dann die Datei nicht finden kann, da unser Trick über den Webserver umgesetzt wird.

Da aber oft eher nur Dateien auf Existenz geprüft werden, die nicht im Uploads-Ordner, sondern in den Ordnern der Themes und Plugins gespeichert sind, sollte das kein allzu großes Problem darstellen. Im Zweifel müsstet ihr dann solche Dateien doch runterladen. Diese zu finden könnte aber etwas knifflig sein.

Eine weitere Einschränkung ist die Notwendigkeit einer Verbindung zum Webserver. Wenn man lokal entwickelt hat man ja in der Regel den Vorteil, dass dies auch ohne Internetverbindung möglich ist. Ich schreibe auch oft meine Blogbeiträge, wenn ich etwas im Zug unterwegs bin, wo die Internetverbindung häufiger abbricht. Falls ihr also Dateien unbedingt für die lokale Entwicklung benötigt, müsste ihr sie wohl doch synchronisieren.

Funktioniert es auch mit anderen Entwicklungsumgebungen?

Das Gleiche ist auch bei der Verwendung des nginx-Servers in der lokalen Entwicklung möglich. Da man aber beim nginx nicht einfach eine Datei im Verzeichnis der WordPress-Installation verwenden kann, müsste ihr folgende Zeilen in die nginx-Konfiguration hinzufügen:

location ~ ^/wp-content/uploads/(.*)$ {
	try_files $uri @missing;
}
location @missing {
	return https://xyz.com$uri;
}

Fazit

Man sollte immer mit einer lokalen Kopie einer Website ändern, wenn man daran entwickelt. Diese auf dem aktuellen Stand zu halten ist allerdings sehr zeitintensiv. Durch den Wegfall der Synchronisation von Mediendateien kann aber sehr viel Zeit und vor allem Speicherplatz eingespart werden.