WordPress-Multisite – Eine komplette Übersicht + Meinungen dazu

Multisite-Umgebungen in WordPress eignen sich für viele Anwendungsfälle, zb für

  • Mehrsprachigkeit – wo jede Sprache eine eigene Multisite-Seite bekommt
  • Soziale Netzwerke, wo jede Gruppe oder Benutzer eine eigenen Blog bekommt
  • Kundenverwaltung, wo jeder Kunde eine eigene Multisite-Seite/Blog bekommt

 

Es gibt sehr viele Möglichkeiten, eine Multisite-Umgebung aufzusetzen und zu konfigurieren. Dazu hier ein paar Gedanken:

tl;dr

  • Subdomain-Installation bringt Aufwand mit DNS, Plesk (und eventuell nginx)

Cool Stuff

  • Jede Multisite kann eine eigene Domain haben
  • Bessere Strukturierung von Inhalten und Teilbereichen mit integrierter Rechteverwaltung
    • Wird eine Datenstruktur zb mit Meta-Feldern aufgebaut, bin ich immer im Post-Edit bereich und tu mir da schwer, andere Benutzer mit Rechten zu versehen. Vor allem wenn da Benutzer mit unterschiedlichen Berechtigungen behandelt werden müssen
  • Multisites für zb Kunden können öffentliche und private Bereiche haben – so können die Kunden Ihren Kunden oder Bekannten Zugang zu den öffentlichen Bereichen geben
  • Jeder Multisite für Kunden oder BuddyPress-Freunden kann von denen selbst verwaltet werden. Themes können gewechselt und weitere Benutzer verwaltet werden
  • Trennung von sensiblen und öffentlichen Daten
  • Medienverwaltung ist einfacher und getrennt!  Werden soziale Netzwerke ohne Multisite aufgezogen, so sehen alle User alle Medien

Ordnerstruktur oder Subdomains – SSL, Permalink und Verzeichnisprobleme aufgelöst

Vorab: nginx kann in beiden Fällen Probleme machen!

Soll die Multisite-Umgebung unter

  • zweiteseite.hauptdomain.com oder
  • hauptdomain.com/zweiteseite

erreichbar sein?

Eine Entscheidungshilfe soll nachfolgende Gegenüberstellung geben.

Multisite mit Ordnerstruktur

Bei der Ordnerstruktur sind die Multisites unter hauptdomain.com/zweiteseite oder hauptdomain.com/dritteseite erreichbar.

Vorteile

  • Kein Problem mit SSL-Zertifikaten wie let’s encrypt.
    • Weil auf die Hauptdomain eh ein SSL-Zertifikat ausgestellt wurde, gilt das für alle Teile einer URL, die darauf folgen.
    • hauptdomain.com/zweiteseite oder hauptdomain/blogs/dritteseite sind alle vom Zertifikat erfasst.
  • Kein Problem mit DNS & Domainkonfiguration am Server (zb Plesk)
    • Da für jeden weiteren Multisite-Blog keine Domain angelegt wird, muss ich am Server nichts konfigurieren. Ich brauch mich auch nicht um die DNS-Verwaltung kümmern.
    • Gerade DNS macht bei Hostern gerne Probleme.
  • URLS der Multisites können mit Permalinks leicht beeinflusst werden.
  • Schnellerer und besserer Workflow beim Erstellen einer weiteren Seite. Zb durch Kunden oder User. Ich muss mich dadurch nicht um Domain- oder DNS-Handling kümmern.
  • Weniger nginx-Probleme – da jede Unterseite nur über weiteres URL-Rewriting/Permalinks gelöst werden.

 

Nachteile

  • Permalinks könnten Probleme machen. Gleichlautende Seiten oder CPT-Posts könnten mit dem Slug/Namen der Multisite-Seite kollidieren.
    • Ein Beitrag mit dem Titel Essen und der URL meineseite.com/essen macht Probleme, wenn ich einen Multisite-Blog mit der URL meineseite.com/essen habe!
    • Lösung: Posts sollten sowieso immer einen nummerischen Permalink-Prefix haben, zb: /%post_id%/%postname%/

 

Multisite mit Subdomains

Vor und Nachteile der Ordnerstruktur-Konfiguration sind hier meist vice versa zu sehen. Zusätzlich:

  • Subdomains könnten als saubere Trennung gesehen werden
  • Domain könnte sehr lang werden!
    • Wird eine Multisite unter einer übergeordneten Subdomain betrieben, wird die URL sehr lange, komplex oder unschön.
    • Hauptseite ist unter subdomain.meinedomain.at erreichbar. Wird nun eine Multisite darunter eingerichtet, kommt es zu solchen URLS: multisiteblog.subdomain.meinedomain.at.
  • Wildcard-DNS-Eintrag wird benötigt.

 

Plesk

 

„/blog/“-Slug in URL entfernen

Man könnte sich an /blog/ in der Url stören. Das lässt sich aber ganz einfach beseitigen!

  • Im Netzwerkbereich (domain.at/wp-admin/network/site-settings.php?id=1) die Permalinkstruktur anpassen und das /blog/ wegnehmen:
    • Alt:
    • Neu:

 

Dafür gibt es natürlich auch ein Plugin:

https://wordpress.org/plugins/r3df-multisite-blog-slug-remover/

 

Erzwungene Subdomain-Installation doch noch als Unterverzeichnis-Installation durchführen

Da deine Installation nicht neu ist, müssen die Websites in deinem WordPress-Netzwerk Subdomains verwenden. Die Haupt-Website einer Installation in Unterverzeichnissen benötigt eine modifizierte Permalink-Struktur, die möglicherweise bestehende Links beeinträchtigt.

Das kennt man und ärgert sich darüber, oder?

Trotz komplett neuer Installation kommt also der Zwang, die Multisite nur als Subdomain-Installation durchzuführen!

Das Ziel wär aber folgendes:

 

Die Lösung?

  • Alle Artikel und Seiten löschen.
  • Eventuell auch: Permalinkstruktur auf schöne Urls ändern

Was mache ich mit WP_ALLOW_MULTISITE?

Bei der Installation bekommt man folgende Anweisungen:

 

In der Datei wp-config.php steht bereits der Eintrag

define( 'WP_ALLOW_MULTISITE', true );

und daher würde das dann so aussehen:

WP_ALLOW_MULTISITE brauche ich nur, um die Multisite-Installation überhaupt zu ermöglichen.

Wenn ich den vorgegebenen Block aus dem ersten Screenshot in die wp-config.php kopieren muss, kann ich WP_ALLOW_MULTISITE löschen oder überschreiben!

Siehe:

 

Domainmapping – Domains für die einzelnen Blogs aufschalten

Früher brauchte man ein Plugin, um extra Domains für die „Unterseiten“ zu verwenden.

Seit einiger Zeit ist diese Funktionalität aber im WordPress-Core enthalten:

https://codex.wordpress.org/WordPress_Multisite_Domain_Mapping

https://twitter.com/Rarst/status/897804897743253505

Gutenberg – Der neue WordPress Editor. Letztes Update vom 25.10.

Das hier wird ein Sammelartikel zu all den Neuigkeiten rund um Gutenberg.

Daher gibt’s hier laufend Erweiterungen und Updats.

Neue Artikel und Meinungen werden am Ende eingefügt!

  • Update vom 09. Oktober – Linkschleuder erweitert
  • Update vom 04. Oktober – Joost über Gutenberg
  • Update vom 23. + 25. Oktober: Metaboxen in Gutenberg angekommen

Was ist Gutenberg?

Gutenberg soll den derzeitigen Artikel-Bearbeiten-Bereich ersetzen.

Von der Idee her geht man weg von einem Contenbereich hin zu mehreren.

So kann man Content übereinanderstapeln oder untereinanderreihen. Inhalte werden dann in Zeilen, ähnlich Tabellenreihen, organisiert.

Man kann dann Inhalte verschieben – also ein Bild zwischen andere Bilderzeilen oder Textzeilen schieben.

Ziel

Der Editor von WordPress ist veraltet und fühlt sich auch nicht so hilfreich an.

WordPress wird von ähnlichen Apps wie wiix oder medium o.ä.  mächtig Feuer unter dem Arsch gemacht.

Warum?

Weil die bearbeitungsfreundlicher sind.

Außerdem möchte WodPress die ganzen Sitebuilderplugins mit Gutenberg ersetzen.

Generelle Infos

  • https://wordpress.org/plugins/gutenberg/
  • https://wordpress.github.io/gutenberg/

     

Diverse Infos

Gutenberg bekommt Metaboxen!

 

Ein großer Kritikpunkt an Gutenberg war die fehlende Unterstützung von Custom Fields/Metaboxen.

Mit nachfolgendem Commit sollte die Kritik nun langsam verstummen:

 

 

 

https://github.com/WordPress/gutenberg/commit/02d4734e667cbd423d78636bda5d34ec580bb3f9

Mehr Infos hier:

Gutenberg und WordPress lassen React fallen. Daraufhin ändert Facebook die Lizenz auf MIT ohne Anhang.

Matt Mullenweg beantwortet exzessiv Fragen zu Gutenberg:

Matt klärt ein paar offene Punkte zu Gutenberg und verteidigt einige Entscheidungen:

 

Die React-Problematik

Dazu möcht ich mich nicht lange auslassen, weil es hier um Patente und Lizenzrecht geht – und da amerikanisches Recht involviert ist..

React „gehört“ Facebook.

React steht nicht unter der GPL oder der MIT.

Wer React benutzt stimmt zu, dass man nicht mit Facebook wirtschaftlich konkurriert. Verkürzt gesagt.

Ein sehr provokativer Artikel dazu ist folgender:

https://medium.com/@raulk/if-youre-a-startup-you-should-not-use-react-reflecting-on-the-bsd-patents-license-b049d4a67dd2 – Wenn du ein Startup bist, verwende nicht React. (Wenn du darauf hoffst, von einer großen Firma aufgekauft zu werden)

Die Hauptaussage ist, dass es Probleme gibt, wenn man React benutzt und an eine andere Firma verkauft. Weil sich andere Firmen die Lizenzproblematik nicht einhandeln wollen.

GRAVIERENDES UPDATE

Das galt bis Anfang Oktober 2017. Facebook hat die Lizenz nun auf die MIT-Lizenz ohne Anpassungen geändert.

 

Meinungsspiegel

Joost de Valk von Yoast SEO über Gutenberg

  • https://yoast.com/gutenberg-alternative-approach/
  • Joost findet es gut, dass WordPress mit Gutenberg benutzerfreundlicher wird.
  • Gutenberg ist eine moderne Kopie des Medium-Editors.
  • Joost hat bedenken wegen JavaScript, der Geschwindigkeit/des Zeitplans der Entwicklungen
  • Es fehlen Schnittstellen zum Reinhängen in die Blocks – Yoast SEO kann noch nicht in die Gutenberg-Blocks integriert werden.
  • Es fehlen die Metaboxen und Joost kritisiert, dass die Gutenberg-Entwickler Metaboxen eventuell weglassen wollen.
  • Accessibility ist eine große Baustelle
  • Es gibt einen Vorschlag für ein mögliches Aussehen von Gutenberg – hier werden die Metaboxen ganz normal angezeigt:

 

 

Linkschleuder

Das verwünschte HTTP Error Problem beim Medienuploader

Es ist einer der ärgerlichsten Probleme mit WordPress die man kennt.

Ein Fehler beim Upload von Bildern.

Man sucht alle Logdaten durch, schaut sich die Firewall und Jails an und kommt nicht dahinter, woher das Problem kommt.

Es gibt für das Problem mehrere Ursachen und einige Lösungen.

Gesperrte IP-Adresse?

Es kann zb bei Plesk passieren, dass die eigenen IP-Adresse gesperrt ist.

Das kann man einfach begutachten und beheben, indem man bei den Tools & Einstellungen die eigenen Adresse wieder freischaltet:

 

ModSecurity/WebAppFirewall überprüfen

ModSecurity kannn oft die Ursache für ein Problem beim Medienupload sein.

In den Einstellungen von Plesk wird sogar darauf hingewiesen, dass manche ModSecurity Regelsätze Probleme mit zb WordPress bereiten.

Sicherheitsplugins überprüfen

Plugins wie iThemes Security, Wordfence o.ä. können auch dafür zuständig sein, dass gewisse Anfrangen an WordPress nicht weitergeleitet oder geblockt werden.

 

PHP-Version ändern

Oft hilft es auch einfach die PHP-Backend-Version auf zb FastCGI zu ändern.

So geht das beispielhaft:

Apache oder Server neu starten

Die Holzhammer-Methode wäre es, den Apache oder den Server neu zu starten.

feuer photo

Das hilft aber manchmal!

Wenn Updaten nicht funktioniert und WordPress FTP Verbindungsdaten verlangt…

…stehen bald Schweißperlen auf der Stirn.

Dabei gibt es ein paar relativ einfache Möglichkeiten um WordPress dazu zu bringen, seiner Arbeit ganz normal nachzugehen.

Einstellen der FTP Zugangsdaten in wp-config.php

Oft reicht es einfach, die FTP Zugangsdaten einzugeben und von FTP auf FTPS umzustellen.

Wenn das nicht funktioniert oder das dauernde Eingeben nervt, kann man die Zugangsdaten in der wp-config.php hinterlegen:

define('FS_METHOD', 'direct');
define('FTP_BASE', '/var/pfad/zum/richtigen/wordpress/verzeichnis');
define('FTP_USER', 'meinftpusername');
define('FTP_PASS', 'dasftppasswort');
define('FTP_HOST', 'ftp.meinedomain.com');
define('FTP_SSL', true);

Es kann sein, dass diese Einstellungen nicht gleich funktionieren. In dem Fall muss man sich mit den einzelnen Parametern ein bisschen spielen, und zb FS_METHOD auf auf ftpext, ssh2 o.ä umstellen.
Natürlich kann es sein, dass man SSL nicht verwenden kann. Dann muss man einfach die letzte Zeile weglassen.

Die einzelnen Möglichkeiten sind im WordPress Codex nachzulesen:

 http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants

http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants

Änderung der Berechtigung am Server mittels SSH

Wenn sich WP oder Plugins nicht updaten lassen kann auch ein Rechteproblem vorliegen. Der erste Schritt ist mal zu schauen, ob die Dateien/Ordner schreibgeschützt sind und dann den User zu überprüfen. Oft ist der FTP-Benutzer ein anderer als der Webserver und wenn da die Gruppe nicht passt, geht das Update nicht weil die Berechtigungen fehlen.

Wenn man SSH-Zugang (SFTP mit Shell) hat, dann kann man die Eigentümer evtl. direkt am Server auf den Webserver-Benutzer ändern (sofern der SSH/SFTP-Benutzer dazu das Recht hat). Der Webserver Benutzer heißt meistens www-data (lässt sich rausfinden indem man ein php-Script hochlädt und dann ausführt, welches eine Datei anlegt).

Mit folgendem Einzeiler kann man den Eigentümer recht zügig ändern:

find . -user <alterBenutzer> -exec chown www-data:www-data {} \;

Der Befehl macht folgendes:

Finde alle Dateien im aktuellen Verzeichnis oder darunter (.) die dem Benutzer <alterBenutzer> gehören und übereigne sie an Benutzer www-data und Gruppe www-data.

UPDATE: Wie ist das mit den Rechten gemeint?

Kurz: Es fehlt die Schreibberechtigung. Die aktuelle WP-Instanz darf eventuell nicht auf die Festplatte schreiben. Also der Benutzer, der für das Ausliefern der Seiten zuständig ist. Auf einem Webserver laufen viele Dienste. Diese werden oft direkt einem Benutzer zugewiesen. Der Webserver auf Linuxgeräten ist oft dem Benutzer „www-data“ zugewiesen.

Wenn der Benutzer “ www-data“ jetzt keine Schreibberechtigung hat, können auch keine Updates durchgeführt werden. Updates lösen ja einen Schreibvorgang auf der Festplatte des Servers aus.

Wenn das Problem bei einer bisher funktionierenden WordPress-Instanz auftritt, kann auch der Host/Server/vServer daran Schuld haben.

UPDATE: Ich kann mich per FTP verbinden, aber diese Daten funktionieren in der wp-config.php nicht!

Das Problem lässt sich oft lösen, indem man mit dem FS_METHOD-Parameter herumspielt.

Es gibt da vier Auswahlmöglichkeiten, die man durchprobieren kann:

Näheres befindet sich im Bereits verlinkten Artikel im Codex zum Thema wp-config.php.

Eine andere Möglichkeit ist, dass der Hoster auf eine sichere Verbindung umgestellt hat, dann muss man FTP_SSL auf true setzen:

define( 'FTP_SSL', true );

Es kann auch sein, dass man den Port explizit angeben muss, wobei 666 nur als (unrealistisches!) Beispiel für den Port herhalten muss. Ein Standard wäre zb der Port 21.

define( 'FTP_HOST', 'ftp.meinedomain.com:666' );

Dont’s

Natürlich könnte man per FTP zb die Verzeichnisrechte auf 777 setzen. Das ist eine ganz ganz schlechte Idee, denn dann hat jeder alle Berechtigungen.

Neue Tabellen-Spalte per Code mit wpdb oder dbDelta hinzufügen

Grundsätzlich bietet WordPress als Basis für Webapps ja eine einfache Möglichkeit, um Daten in die von WP mitgebrachten Tabellen einzugeben.

Siehe:

https://www.wp-entwickler.at/was-ist-dbdelta-und-wofuer-brauch-ich-das/
https://www.wp-entwickler.at/was-ist-dbdelta-und-wofuer-brauch-ich-das/

https://www.wp-entwickler.at/ueberpruefen-ob-tabelle-tabellenspalte-oder-tabellenzeile-existiert-mit-wpdb/
https://www.wp-entwickler.at/ueberpruefen-ob-tabelle-tabellenspalte-oder-tabellenzeile-existiert-mit-wpdb/

Eigene Tabellen sind in vielen Fällen aber besser.
Will ich nun zu einer Tabelle eine neue Spalte per PHP-Code hinzufügen, gibt es mehrere Möglichkeiten:

 

ALTER TABLE

$wpdb->query( "ALTER TABLE {$table_name} ADD {$column_name} LONGTEXT" );

Die einfachste und durchschaubarste Lösung ist wahrscheinlich ALTER TABLE.
Hier erstelle ich in einer Tabelle, notiert mit {$table_name}, eine Spalte mit dem Type LONGTEXT, notiert mit {$column_name}.

dbDelta

DbDelta ist eigentlich dafür da, um Tabellen in der Datenbank zu erstellen. Siehe auch den vorherigen Blogeintrag zu dbDelta.

Man kann dbDelta aber auch dazu verwenden, um Spalten anzufügen.

Aber nur um Spalten hinzuzufügen – dbDelta löscht keine Spalten. Daher funktionieren folgende Beispiele gleich, ohne Fehler zu werfen. Für euch getestet.

 

		
$sql =
	"CREATE TABLE {$table_name} (
          ID mediumint(9) NOT NULL AUTO_INCREMENT,
          post_ID mediumint(9) NOT NULL,
          term_ID mediumint(9) NOT NULL,
          {$column_name} LONGTEXT,
          PRIMARY KEY  (id)
        ) ENGINE = InnoDB {$charset_collate};";

dbDelta( $sql );

 

$sql =
	"CREATE TABLE {$table_name} (
          {$column_name} LONGTEXT,
        ) ENGINE = InnoDB {$charset_collate};";

dbDelta( $sql );

 

In beiden Fällen füge ich der Tabelle {$table_name} die Spalte {$column_name} hinzu.
Im ersten Fall verwende ich den gleichen Code wie zum erzeugen der Tabelle.
Im zweiten Fall Fall fehlen die meisten Zeilen aus dem ersten Beispiel. Dennoch funktioniert beides gleich.

Kleiner Hinweis: Will ich dbDelta verwenden, muss ich die wp-admin/includes/upgrade.php Datei einbinden:

require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );

 

https://developer.wordpress.org/reference/functions/dbdelta/
https://developer.wordpress.org/reference/functions/dbdelta/

http://wordpress.stackexchange.com/questions/78667/dbdelta-alter-table-syntax
http://wordpress.stackexchange.com/questions/78667/dbdelta-alter-table-syntax

https://codex.wordpress.org/Creating_Tables_with_Plugins#Adding_an_Upgrade_Function
https://codex.wordpress.org/Creating_Tables_with_Plugins#Adding_an_Upgrade_Function

 

http://stackoverflow.com/questions/21330932/add-new-column-to-wordpress-database/21331762#21331762
http://stackoverflow.com/questions/21330932/add-new-column-to-wordpress-database/21331762#21331762

Überprüfen ob Tabelle, Tabellenspalte oder Tabellenzeile existiert mit WPDB

WordPress bietet viele und einfache Möglichkeiten, um Daten zu speichern, ohne eigenen SQL-Code schreiben zu müssen.

Custom Fields (oder Post Metas) werden oft für allerhand Daten verwendet.
Man muss sich nicht selbst um Userinterfaces oder Update- und Löschmechanismen kümmern.

Doch die Tabellenstruktur von WordPress reicht oft nicht, oder ergibt bei größeren Projekten keinen Sinn.

Wenn es dann darum geht, kurze Checks und Überprüfungen an eigenen Tabellen durchzuführen, gehen mir die WordPress eigenen Mittel aus.

Daher nachfolgend ein paar Snippets als Hilfestellung:

Überprüfen ob Tabelle existiert

$table_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" );

Das ist eine recht einfache Übung – {$table_name} ist dabei der Tabellennamen, auf den man überprüfen möchte.

Überprüfen ob Zeile existiert

$wpdb->get_row( "SELECT * FROM {$table_name} WHERE post_ID = {$post_id}" );
$wpdb->get_row( "SELECT post_ID FROM {$table_name} WHERE post_ID = {$post_id}" );

Dazu gibt es mehrere Möglichkeiten – siehe die Doku zu wpdb.
Hier wird aus einer Tabelle, hier dargestellt mit {$table_name}, eine Zeile mit einer bestimmen post_ID geholt.
Im ersten Fall werden alle Datenfelder der Zeile geholt. Für das Überprüfen ob eine Zeile vorhanden ist, könnte das zu viel an Information und Speicherbelegung sein.
Es reicht vollkommen, wenn ich mir nur ein Datenfeld oder eine Spalte aus der Zeile hole.

Überprüfen ob Spalte existiert

$columns = $wpdb->get_results(
"DESC {$table_name}"
);

{$table_name} ist wieder der Tabellenname.
DESC ist shorthand für DESCRIPTION. Mit obigem Befehl hole ich mir alle Informationen zu einer speziellen Tabelle. Ich bekomme nicht nur die Spaltennamen sondern eine Fülle an Infos..
In dem obigen Fall kommt ein Objekt an Arrays zurück. Jedes Array stellt eine Spalte dar. Ich kann diese Arrays mit einer Schleife durchlaufen, oder zb. auch das Objekt serialisieren und nach Text (= die spezielle Spalte) durchsuchen.

 

Dort wo es nötig ist, bitte nicht auf das Absichern der Abfragen vergessen. WordPress bietet dazu eine Hilfestellung mit $wpdb->prepare an.
Hineiws: Dabei handelt es sich nicht um prepared statements auf DB-Ebene sondern um WordPress-Funktionalität.

 

https://codex.wordpress.org/Class_Reference/wpdb
https://codex.wordpress.org/Class_Reference/wpdb

Javascript-Dateien für alten Internet Explorer richtig mit WordPress laden

Worum geht’s?

Microsofts Internetexplorer ist für Webentwickler immer noch ein schwarzes Tuch. Zu stark kochte Microsoft ein eigenes Süppchen, hielt sich nicht an Standards und hinkte mit der Entwicklung hinterher.

Daher muss auch noch im Jahr 2016 auf alte Internet-Explorer-Versionen Rücksicht genommen werden.

Wer ein eigenes Theme entwickelt, wird daher auch folgende Codepassage aus der header.php kennen:

<!--[if lt IE 9]>
    <script src="<?php echo get_stylesheet_directory_uri() ?>/js/html5shiv.min.js"></script>
 <![endif]-->

Damit wird alten Internetexplorern HTML5 beigebracht. (Nebenbei erwähnt:  html5shiv ist eine fantastische Arbeit von Alexander Farkas)
Dieses Schnippsel findet sich in den meisten WordPress-Themes wieder.

Problem – Conditional Comments und wp_enqueue_script()

So richtig schön und richtig ist dieser Code aber nicht – WordPress bietet dazu eh eine Hilfestellung:
Grundsätzlich sollte man JavaScript-Dateien mit wp_register_script() und/oder  wp_enqueue_script() zb in der functions.php  laden, und nicht in der eigentliche Theme-Datei wie header.php.

Leider gab es bis WordPress 4.2 keine Möglichkeit, die JavaScript-Dateien nur für bestimmte Browserversionen zu laden. Conditional Comments und wp_enqueue_script() verstanden sich nicht miteinander.

(Kleiner Hinweis: Man sollte das auch mit respond.js uÄ machen)

Lösung

Das änderte sich in der WordPress Version 4.2 mit der Einführung der Funktion wp_script_add_data().

Damit war es möglich, mit wp_enqueue_script() JavaScript-Dateien zu notieren und WordPress darauf hinzuweisen, diese Datei nur unter bestimmten Umständen zu laden.
Das funktioniert so:

  wp_enqueue_script( 'html5shiv', get_template_directory_uri() . '/js/html5shiv.min.js' );
 wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );

Hier sehen wir

  • laden der html5shiv Datei mit wp_enqueue_script()
  • Hinzufügen von Metadaten für dieses Skript mit wp_script_add_data()
  • Anleitung, das Skript nur für Internetexplorer-Versionen kleiner 9 zu laden.

Jetzt können wir alle Javascript-Dateien gebündelt zb in der functions.php laden.
Damit gibt es nur mehr einen Punkt im Theme, wo dies passiert und wird haben dadurch die header.php bereinigt.

 

Links

 

https://core.trac.wordpress.org/ticket/16024#no0
https://core.trac.wordpress.org/ticket/16024#no0

 

https://developer.wordpress.org/reference/functions/wp_script_add_data/
https://developer.wordpress.org/reference/functions/wp_script_add_data/

 

http://hookr.io/functions/wp_script_add_data/
http://hookr.io/functions/wp_script_add_data/

 

https://msdn.microsoft.com/en-us/library/ms537512(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/ms537512(v=vs.85).aspx

https://codex.wordpress.org/Using_Javascript
https://codex.wordpress.org/Using_Javascript

https://developer.wordpress.org/reference/functions/wp_enqueue_script/
https://developer.wordpress.org/reference/functions/wp_enqueue_script/

https://github.com/aFarkas/html5shiv
https://github.com/aFarkas/html5shiv

https://github.com/aFarkas/
https://github.com/aFarkas/

https://github.com/scottjehl/Respond
https://github.com/scottjehl/Respond

Was ist dbDelta() und wofür brauch ich das?

dbDelta() ist so eine WordPress-Funktion, die einem immer ein bisserl Kopfzerbrechen bereitet aber extremst hilfreich ist.

Worum geht’s bei dbDelta()?

Die Developer-Seite sagt:

Modifies the database based on specified SQL statements.

Also:
Ändert die Datenbank aufgrund von angegebenen SQL-Anweisungen.
Die Funktion ist sehr hilfreich wenn’s darum geht, eine neue, eigene Tabelle anzulegen. Wenn mir die WP eigene Tabellenstruktur nicht ausreicht und ich mit WP-Bordmitteln (Funktionen) also eine Tabelle erzeugen will.

Doch nicht nur erzeugen ist möglich, auch das Abändern.

Genau da wird’s praktisch! Ich kann meine eigenen Tabellen ohne großen Aufwand, ohne große Überlegungen ändern.
Also Spalten einfügen, Datentypen anpassen o.ä.
Was dbDelta() in dem Zusammenhang nicht kann, ist löschen.

Die Probleme?

Man muss sehr genau sein, was die Anweisungen für dbDelta() betrifft.
Genau heißt in dem Fall, dass es sogar auf ein Leerzeichen zu viel ankommt oder auf die komplette Großschreibung einzelner Wörter.
Die genaue Liste der einzelnen Problemfelder von dbDelta() ist bei folgenden Links ersichtlich:

https://codex.wordpress.org/Creating_Tables_with_Plugins#Creating_or_Updating_the_Table
https://codex.wordpress.org/Creating_Tables_with_Plugins#Creating_or_Updating_the_Table

 

http://wordpress.stackexchange.com/questions/78667/dbdelta-alter-table-syntax/78670#78670
http://wordpress.stackexchange.com/questions/78667/dbdelta-alter-table-syntax/78670#78670

Hilfe in Sicht?

Ja! Es tut sich natürlich immer irgendwo etwas im WordPres-Universum.

Dominik Schilling, ein Core-Entwickler hat Verbesserungen angekündigt, die zb. die oben angesprochenen Probleme beheben.

 

https://twitter.com/ocean90/status/753244345629827072
https://twitter.com/ocean90/status/753244345629827072

https://make.wordpress.org/core/2016/07/13/dbdelta-updates-in-4-6/

dbDelta() updates in 4.6


https://make.wordpress.org/core/2016/07/13/dbdelta-updates-in-4-6/

 

Wer sich für die noch offenen Baustellen interessiert wird hier fündig:

https://core.trac.wordpress.org/query?status=!closed&summary=~dbDelta
https://core.trac.wordpress.org/query?status=!closed&summary=~dbDelta

 

https://developer.wordpress.org/reference/functions/dbdelta/
https://developer.wordpress.org/reference/functions/dbdelta/

https://codex.wordpress.org/Creating_Tables_with_Plugins
https://codex.wordpress.org/Creating_Tables_with_Plugins

 

ACF – Felder vor dem Anzeigen und Speichern ändern

ACF ist ein wunderbares Tool, um strukturierter Daten in WordPress Posts speichern zu können.

Bevor das einzelne Felder im Backend angezeigt wird, kann es mit einem Hook verändert werden.
Das ist dann interessant, wenn ich mit diesen Metadaten vor dem Anzeigen etwas machen will. ZB Texte dranhängen, Berechnungen durchführen o.ä.

Nicht nur für’s Anzeigen gibts einen Hook sondern auch für den Fall, dass ich vor dem Speichern in die Datenbank etwas mit dem Feldinhalt anstellen will.

Warum können die Hooks so interessant sein?

Weil ich zb Daten in eine externe Tabelle speichern will – wie das zb hier besprochen wird:

 

https://support.advancedcustomfields.com/forums/topic/custom-database-table/
https://support.advancedcustomfields.com/forums/topic/custom-database-table/

https://support.advancedcustomfields.com/forums/topic/dynamic-select-from-other-plugin-table/
https://support.advancedcustomfields.com/forums/topic/dynamic-select-from-other-plugin-table/

Hook vor dem Anzeigen – acf/load_value

https://www.advancedcustomfields.com/resources/acf-load_value/
https://www.advancedcustomfields.com/resources/acf-load_value/

Für das Ändern des Feldinhaltes vor der Ausgabe gibt es den acf/load_value Hook.
Es gibt vier Möglichkeiten, um sich in das Feld vor dem Anzeigen reinzuhängen.

Genereller Hook

Dieser Filter greift für jedes Feld – schlägt also bei jedem Feld an.
Das ist dann sinnvoll, wenn ich jedes Feld ändern will oder ich einen Feldtyp nicht ausschließen kann. Oder wenn ich den Namen oder die ID des Feldes nicht kenne.
Da der Hook immer greift, kann es zu Performance-Problemen kommen.

// acf/load_value
add_filter('acf/load_value', 'funktion_fuer_load_value_hook', 10, 3);

Hook für einen bestimmten Feldtyp

Wenn ich nur einen bestimmten Feldtypen behandeln will, ist das hier der richtige Hook.
Hier eine Übersicht der möglichen Feldtypen

Auswahlmöglichkeit der Feldtypen in ACF
Auswahlmöglichkeit der Feldtypen in ACF
// acf/load_value/type={$Feldtyp}
add_filter('acf/load_value/type=select', 'funktion_fuer_load_value_hook', 10, 3);

Hook für den vergebenen Namen eines Feldes

Wenn ich den Namen eines Feldes kenne und gezielt dieses Feld ansprechen will, bin ich hier richtig.
Der Name ist im Backend bei den Feld-Gruppen ersichtlich:

Feldname in ACF
Feldname in ACF
// acf/load_value/name={$Feldname}
add_filter('acf/load_value/name=e_mail_adresse_1', 'funktion_fuer_load_value_hook', 10, 3);

Hook für eine eindeutigen ID

Jedes Feld in ACF bekommt eine eindeutige ID, zb wie in folgendem Screenshot „field_56ac02513c8de“.
Diesen kann ich gezielt ansprechen. Dadurch wird der Code wenig dynamisch – da ich ja irgendwie den Key im PHP-Code hinterlegen muss. Unproblematischer ist das, wenn ich die ACF-Struktur sowieso per PHP bereitstelle.

Eindeutige ID - Key
Eindeutige ID – Key
// acf/load_value/key={$Feld-ID}
add_filter('acf/load_value/key=field_56ac02513c8de', 'funktion_fuer_load_value_hook', 10, 3);

 

Hook vor dem Speichern – acf/update_value

Gleich wie beim Filter load_value gibt es für den Schritt vor dem Speichern der Feldinhalte einen Hook.
Dieser nennt sich acf/update_value.
Dieser kann wieder die gleichen vier Szenarien wie oben abgreifen.
Daher gibt es je einen Hook für

  • alle Felder –  ‚acf/update_value‘
  • für einen bestimmten Feldtypen –  ‚acf/update_value/type=select‘
  • für einen vergebenen Feldnamen  – ‚acf/update_value/name=e_mail_adresse_1‘
  • für eine eindeutige ID –  ‚acf/update_value/key=field_56ac02513c8de‘

https://www.advancedcustomfields.com/resources/acf-update_value/
https://www.advancedcustomfields.com/resources/acf-update_value/

 

ACF Quelltext

Im Quelltext von ACF werden die Hooks so bereitgestellt:

ACF-Quelltext load_value Hooks
ACF-Quelltext load_value Hooks

 

https://github.com/elliotcondon/acf/search?utf8=%E2%9C%93&q=load_value
https://github.com/elliotcondon/acf/search?utf8=%E2%9C%93&q=load_value

 

Problem: Speichern leerer Inhalte in der Postmeta-Tabelle

Wenn ich zb manche ACF-Felder exklusiv in einer eigenen Tabelle speichern will, dann sollen die Daten ja nur dort auftauchen.
Das funktioniert, wenn ich mich in den acf/update_value Hook reinhänge und einen leeren Wert zurückgebe.
Das kann aber zu einem Problem werden, weil ACF dennoch Daten in der Postmeta-Tabelle speichert. Eben einen leeren Wert:

Leere Werte in Postmeta-Tabelle
Leere Werte in Postmeta-Tabelle

Beheben könnte ich das zb, indem ich mich in der WordPress eigenen Funktion update_metadata in den Hook „update_{$meta_type}_metadata“ reinhänge und bestimmte meta_keys behandle:

https://github.com/WordPress/WordPress/blob/e6267dcf19f1309954e04b65a7fa8e9e2df5d0a4/wp-includes/meta.php#L143

https://github.com/WordPress/WordPress/blob/e6267dcf19f1309954e04b65a7fa8e9e2df5d0a4/wp-includes/meta.php#L187

Update Metadata Hook
Update Metadata Hook

Links

https://www.advancedcustomfields.com/resources/acf-update_value/

https://www.advancedcustomfields.com/resources/acf-update_value/

https://www.advancedcustomfields.com/resources/acf-load_value/

 

https://www.advancedcustomfields.com/resources/#field-types
https://www.advancedcustomfields.com/resources/#field-types

Dynamic Select from other plugin table?


https://support.advancedcustomfields.com/forums/topic/dynamic-select-from-other-plugin-table/

Aktueller Status 2016

Wir bekommen die letzten Monate über öfters die Frage gestellt, warum wir keine neuen Blogartikel veröffentlichen.

Derzeit sind wir bis in den Herbst hinein mit einem großen und langfristigen Projekt betreut. Das freut uns auf der einen Seite sehr, weil es eine reizvolle Herausforderung ist. Auf der anderen Seite müssen wir die meisten Anfragen potentieller Kunden leider abweisen. Ab Herbst 2016 wird das aber besser.

Intern passiert bei uns im Moment aber einiges:

Fixer Mitarbeiter

In unserem Umkreis bewegen sich zwar einige Freelancer und Partner, bis dato haben wir aber noch keinen fixen Mitarbeiter. Das ändert sich gerade und es schaut gut aus mit einem zukünftigen Kollegen. Wenns dann soweit ist, werden wir auch eine Blogartikelserie starten, die das Thema „Wie werde ich WordPress-Entwickler/Webentwickler“ behandelt.

GmbH

Wir sind gerade dabei unsere GesbR in eine GmbH umzugründen. Das ist ein logischer Schritt ab einer gewissen Größe, einem gewissen Umsatz und aufgrund der angedachten Zielen.
Für unsere Kunden ändert sich nix in der Geschäftsbeziehung. Wir haben dann einfach eine andere UID und eine Firmenbuchnummer.

Zukäufe/Übernahmen

Derzeit stehen wir in Verhandlungen, eine andere bekannte WordPress-Marke aus Österreich zu übernehmen. Wir werden diese Marke weiterführen und mit neuem Leben füllen. Dadurch wird ein Firmenbereich geschaffen, der nichts mit Agenturzusammenarbeit zu tun hat. Mehr dazu dann gegen Jahresende.

 

WordCamp Europe in Wien

Natürlich lassen wir uns das erste WordCamp Europe auf österreichischem Boden nicht entgehen! Wir werden mit drei Mann von 24. bis 26. Juni vor Ort sein und freuen uns auf andere interessante WordPress Geister.

https://2016.europe.wordcamp.org/

Pro bono

Wie jedes Jahr bieten wir zu Weihnachten ein Projekt im Wert von ca 1.000 € pro bono an. Da unser Zeitbudget heuer knapp wird bitten wir darum, eventuell uns schon jetzt die Ideen zukommen zu lassen. Wie gehabt setzen wir ein Projekt gratis um, wenn es einem guten Zweck dienen soll.