Nutzen Sie die Leistungsfähigkeit von WordPress-Hooks: Aktionen und Filter erklärt

Veröffentlicht: 2022-07-22

Wie jedes CMS wird WordPress nicht immer alle Anforderungen sofort erfüllen. Da es sich um Open Source handelt, könnten Sie es hacken, um es an Ihre geschäftlichen Anforderungen anzupassen – aber stattdessen können Sie die Hooks von WordPress verwenden, um Ihre Ziele zu erreichen. Das Bauen mit Hooks ist eine erfolgreiche Strategie, die es WordPress-Entwicklern ermöglicht, nahezu jede erdenkliche Website-Funktion zu erstellen.

WordPress-Hooks: Aktionen und Filter

WordPress-Hooks sind nicht nur leistungsstarke Anpassungswerkzeuge, sondern auch die Art und Weise, wie WordPress-Komponenten miteinander interagieren. Eingehakte Funktionen verwalten viele der Routineaufgaben, die wir als wesentlichen Bestandteil von WordPress betrachten, wie z. B. das Hinzufügen von Stilen oder Skripten zu einer Seite oder das Umgeben von Fußzeilentext mit HTML-Elementen. Eine Suche in der Codebasis von WordPress Core zeigt Tausende von Hooks an mehr als 700 Stellen. WordPress-Themes und Plugins enthalten noch mehr Hooks.

Bevor wir uns mit Hooks befassen und den Unterschied zwischen Aktions-Hooks und Filter-Hooks untersuchen, wollen wir verstehen, wo sie in die WordPress-Architektur passen.

WordPress-Infrastruktur

Die modularen Elemente von WordPress lassen sich leicht ineinander integrieren, sodass wir sie einfach mischen, anpassen und kombinieren können:

  1. WordPress Core: Dies sind die Dateien, die für das Funktionieren von WordPress erforderlich sind. WordPress Core bietet eine generalisierte Architektur, das WP Admin-Dashboard, Datenbankabfragen, Sicherheit und mehr. WordPress Core ist in PHP geschrieben und verwendet eine MySQL-Datenbank.
  2. Thema (oder übergeordnetes Thema): Ein Thema definiert das grundlegende Layout und Design einer Website. Angetrieben von PHP-, HTML-, JavaScript- und CSS-Dateien funktioniert ein Design, indem es die WordPress-MySQL-Datenbank liest, um den HTML-Code zu generieren, der in einem Browser gerendert wird. Hooks in einem Design können beispielsweise Stylesheets, Skripte, Schriftarten oder benutzerdefinierte Beitragstypen hinzufügen.
  3. Untergeordnetes Thema: Wir erstellen selbst untergeordnete Themen, um das grundlegende Layout und Design der übergeordneten Themen zu optimieren. Untergeordnete Themen können Stylesheets und Skripte definieren, um geerbte Funktionen zu ändern oder Beitragstypen hinzuzufügen oder zu entfernen. Die Anweisungen des Child-Themes ersetzen immer die des Parent-Themes.
  4. Plugin(s): Um die Backend-Funktionalität von WordPress zu erweitern, können wir aus Tausenden von Plugins von Drittanbietern wählen. Hooks in einem Plugin könnten uns beispielsweise per E-Mail benachrichtigen, wenn ein Beitrag veröffentlicht wird, oder von Benutzern eingereichte Kommentare verbergen, die verbotene Sprache enthalten.
  5. Benutzerdefinierte Plugin(s): Wenn ein Drittanbieter-Plugin die Geschäftsanforderungen nicht vollständig erfüllt, können wir es beschleunigen, indem wir ein benutzerdefiniertes Plugin in PHP schreiben. Oder wir können ein neues Plugin von Grund auf neu schreiben. In beiden Fällen würden wir Hooks hinzufügen, um die vorhandene Funktionalität zu erweitern.

Die Pyramide zeigt von unten nach oben fünf Ebenen: (1) WordPress Core, (2) Theme, (3) Child Theme, (4) Plugins, (5) Custom Plugins.
Hierarchie der WordPress-Infrastruktur

Angesichts der Tatsache, dass wir Zugriff auf die Quelle aller fünf Schichten haben, warum werden Hooks in WordPress benötigt?

Code-Sicherheit

Um mit sich entwickelnden Technologien Schritt zu halten, veröffentlichen Mitwirkende an WordPress Core, übergeordneten Themen und Plugins häufig Updates, um Sicherheitslücken zu schließen, Fehler zu beheben, Inkompatibilitäten zu beheben oder neue Funktionen anzubieten. Wie jeder Berater mit Notfallerfahrung aus erster Hand weiß, kann das Versäumnis, WordPress-Komponenten auf dem neuesten Stand zu halten, eine Website gefährden oder sogar deaktivieren.

Wenn wir lokale Kopien von Upstream-WordPress-Komponenten direkt modifizieren, stoßen wir auf ein Problem: Updates überschreiben unsere Anpassungen. Wie können wir dies beim Anpassen von WordPress umgehen? Über Hooks, im Child-Theme und benutzerdefinierte(n) Plugin(s).

Codierung in unserem Child-Theme

Ein untergeordnetes Thema ist ein sicherer Bereich, in dem wir das Aussehen und Verhalten unseres installierten Themas anpassen können. Jeder hier hinzugefügte Code überschreibt vergleichbaren Code im übergeordneten Code, ohne dass das Risiko besteht, dass er durch ein Update überschrieben wird.

Wenn ein untergeordnetes Thema aktiviert wird, wird es mit einem deaktivierten übergeordneten Thema verknüpft, das die Eigenschaften des übergeordneten Elements erbt und zeigt, während es von den Aktualisierungen des übergeordneten Elements unbeeinflusst bleibt. Um nicht der Versuchung zum Opfer zu fallen, ein Theme zu ändern, empfehlen Best Practices, dass ein untergeordnetes Theme als Teil unseres Setups aktiviert wird.

Schreiben von benutzerdefinierten Plugins

Wenn ein Plugin aktiviert ist, wird seine Datei functions.php bei jedem Aufruf auf dem Server ausgeführt. WordPress wiederum lädt und sortiert Hooks aller aktiven Plugins nach ihrer Priorität und führt diese sequentiell aus. Um die Funktionalität eines Drittanbieter-Plugins zu erweitern, können wir unser eigenes benutzerdefiniertes WordPress-Plugin schreiben.

Wo platzieren wir unsere Hooks in WordPress

Tor Beispiel Wo?
Child-Theme PHP Benutzerdefiniertes Plugin PHP
Um die Struktur einer Webseite zu ändern Hinzufügen eines benutzerdefinierten Stylesheets zum Ändern der Farben und Schriftarten von Website-Elementen
Um die Funktionalität eines anderen Plugins zu ändern (d. h. ein Plugin zu erstellen, um die Funktionalität eines Plugins eines Drittanbieters zu verbessern) Hinzufügen einer Unterüberschrift (z. B. „Neuigkeiten“) zu benutzerdefinierten Beitragstypen
Um eine neue Funktion hinzuzufügen, die über WordPress Core hinausgeht Ändern des Arbeitsablaufs, der stattfindet, wenn ein Beitrag besucht wird, um das Aktualisieren eines Zählers in der Datenbank einzuschließen

Vorbereitung vor dem Tauchen: Definitionen

Um eine Vermischung von Begriffen zu vermeiden, halten wir uns an diese Terminologie:

  • Ein Hook ist ein Sweetspot in WordPress, an dem Funktionen zur Ausführung registriert werden. Wir können unsere Funktionen mit einem der vielen Hooks in WordPress und seinen Komponenten verbinden oder unsere eigenen erstellen.
    • Ein Action-Hook führt Aktionen aus.
    • Ein Filter-Hook führt Filter aus.
  • Eine Hook-Funktion ist eine benutzerdefinierte PHP -Callback- Funktion, die wir in einen WordPress-Hook-Speicherort „eingehakt“ haben. Welcher Typ zu verwenden ist, hängt davon ab, ob der Hook Änderungen außerhalb der Funktion zulassen soll – z. B. direktes Hinzufügen zur Ausgabe einer Webseite, Ändern einer Datenbank oder Senden einer E-Mail. Diese sind als Nebenwirkungen bekannt.
    • Ein Filter (oder eine Filterfunktion ) sollte Nebeneffekte vermeiden, indem er nur an den ihm übergebenen Daten arbeitet und dann eine modifizierte Kopie davon zurückgibt.
    • Eine Aktion (oder Aktionsfunktion ) hingegen soll Nebenwirkungen hervorrufen. Es hat keinen Rückgabewert.

Diagramm mit Funktionen gepaart mit kompatiblen Haken. An Filter-Hooks sind Filterfunktionen angehängt, und an Aktions-Hooks sind Aktionsfunktionen angehängt.
WordPress-Hooks können mehrere Callback-Funktionen haben, aber alle Callback-Funktionen müssen mit dem Hook-Typ übereinstimmen, bei dem sie registriert sind.

Mit diesen Unterscheidungen im Hinterkopf können wir mit der Erforschung von Hooks beginnen.

Abstraktion und sauberer Code

Wenn eine Aktion oder ein Filter bei Bedarf in einen Hook integriert wird, erfüllen wir die Ziele, nur eine Funktion pro Aufgabe zu schreiben und die Duplizierung von Code innerhalb eines Projekts zu vermeiden. Angenommen, wir möchten das gleiche Stylesheet zu drei Seitenvorlagen (Archiv, einzelne Seite und benutzerdefinierter Beitrag) in unserem Design hinzufügen. Anstatt jede Vorlage im Parent zu überschreiben, dann jede in unserem Child-Theme neu zu erstellen und dann Stylesheets zu einzelnen Head-Abschnitten hinzuzufügen, können wir Code in einer einzigen Funktion schreiben und ihn mit dem wp_head Hook anhängen.

Durchdachte Nomenklatur

Vermeiden Sie Konflikte proaktiv, indem Sie ein untergeordnetes Thema oder benutzerdefinierte Plugin-Hooks eindeutig benennen. Gleichnamige Hooks auf einer einzelnen Site zu haben, ist ein Rezept für unbeabsichtigtes Codeverhalten. Best Practices schreiben vor, dass wir den Namen unseres Hooks mit einem eindeutigen, kurzen Präfix beginnen (z. B. die Initialen des Autors, Projekts oder Unternehmens), gefolgt von einem beschreibenden Hook-Namen. Wenn wir beispielsweise das Muster „Projektinitialen plus Hook-Name“ für das Projekt Tahir's Fabulous Plugin verwenden, könnten wir unsere Hooks tfp-upload-document oder tfp-create-post-news .

Parallele Entwicklung und Debugging

Ein einzelner Hook kann mehr als nur eine Aktion oder einen Filter auslösen. Zum Beispiel könnten wir eine Webseite schreiben, die mehrere Skripte enthält, die alle den Action-Hook wp_head verwenden, um HTML (z. B. einen <style> - oder <script> -Abschnitt) innerhalb des <head> -Abschnitts auf dem Frontend der Seite zu drucken.

Somit können mehrere Plugin-Entwickler mehrere Ziele parallel auf einem einzigen Plugin vorantreiben oder das Plugin in mehrere, einfachere einzelne Plugins aufteilen. Wenn ein Feature nicht richtig funktioniert, können wir seine Hook-Funktion direkt untersuchen und debuggen, ohne das gesamte Projekt durchsuchen zu müssen.

Aktionen

Eine Aktion führt Code aus, wenn ein Ereignis in WordPress auftritt. Aktionen können Vorgänge ausführen wie:

  • Daten erstellen.
  • Lesen von Daten.
  • Ändern von Daten.
  • Löschen von Daten.
  • Erfassen der Berechtigungen von eingeloggten Benutzern.
  • Standorte verfolgen und in der Datenbank speichern.

Beispiele für Ereignisse, bei denen Aktionen ausgelöst werden können, sind:

  • init , nach dem Laden von WordPress, aber vor dem Senden von Headern an den Ausgabestream.
  • save_post , wenn ein Beitrag gespeichert wurde.
  • wp_create_nav_menu , direkt nachdem ein Navigationsmenü erfolgreich erstellt wurde.

Eine Aktion kann mit einer API interagieren, um Daten zu übertragen (z. B. einen Link zu einem Beitrag in sozialen Medien), aber sie gibt keine Daten an den aufrufenden Hook zurück.

Angenommen, wir möchten das Teilen aller neuen Beiträge auf unserer Website über soziale Medien automatisieren. Beginnen Sie, indem Sie in der WordPress-Dokumentation nach einem Hook suchen, der ausgelöst werden kann, wenn ein Beitrag veröffentlicht wird.

Es gibt keine Abkürzungen, um unseren Haken zu finden: Wir würden durch Erfahrung lernen oder die aufgelisteten Aktionen durchforsten, um wahrscheinliche Kandidaten zu finden. Wir könnten save_post als Kandidaten in Betracht ziehen, schließen es aber schnell aus, da es während einer einzigen Bearbeitungssitzung mehrmals ausgelöst werden würde. Eine bessere Wahl ist transition_post_status , das nur ausgelöst wird, wenn ein Beitragsstatus geändert wird (z. B. von draft zu publish , von publish zu trash ).

Wir werden mit transition_post_status fortfahren, aber auch unsere Aktion so verfeinern, dass sie nur dann ausgeführt wird, wenn der Status unseres Beitrags auf publish . Darüber hinaus können wir, indem wir der offiziellen Dokumentation und den APIs der verschiedenen Social-Media-Plattformen folgen, den Inhalt unseres Beitrags zusammen mit einem vorgestellten Bild integrieren und veröffentlichen:

 <?php function publish_post_on_social_media ( $new_status = NULL, $old_status = NULL, $post_ID = NULL ) { if ( 'publish' == $new_status && 'publish' != $old_status ) { // build the logic to share on social media } } add_action( 'transition_post_status', 'publish_post_on_social_media', 10, 3 ); ?>

Jetzt, da wir wissen, wie man Action-Hooks verwendet, gibt es einen, der besonders hilfreich ist, besonders wenn es um CSS geht.

Prioritäten festlegen mit wp_enqueue_scripts

Angenommen, wir möchten das Stylesheet unseres untergeordneten Themas zuletzt hinzufügen, nachdem alle anderen geladen wurden, um sicherzustellen, dass alle gleichnamigen Klassen, die von anderen stammen, von den Klassen unseres untergeordneten Themas überschrieben werden.

WordPress lädt Stylesheets in einer Standardreihenfolge:

  1. Übergeordnete Themen
  2. Untergeordnete Themen
  3. Alle Plugins

In diesem Konstrukt:

 add_action( string $hook_name, callable $callback, int $priority = 10, int $accepted_args = 1)

…der priority der hinzugefügten Aktion bestimmt ihre Ausführungsreihenfolge:

  • Der wp_enqueue_scripts priority oder jede Aktion) ist „10“.
  • Eine Funktion wird früher ausgeführt, wenn wir ihre priority auf eine niedrigere Zahl zurücksetzen.
  • Eine Funktion läuft später, wenn wir ihre priority auf eine höhere Zahl zurücksetzen.

Um das Stylesheet unseres untergeordneten Designs zuletzt zu laden, verwenden wp_enqueue_scripts , eine Aktion, die häufig von WordPress-Designs und -Plugins verwendet wird. Wir müssen nur die Priorität der Aktion wp_enqueue_scripts unseres untergeordneten Themas auf eine Zahl ändern, die höher ist als der Standardwert von „10“, sagen wir „99“:

 add_action( 'wp_enqueue_scripts', 'child_theme_styles', 99 );



Im Allgemeinen verwenden wir Aktionen, wenn wir nicht nach Rückgabewerten suchen. Um Daten an den aufrufenden Hook zurückzugeben, müssen wir uns Filter ansehen.

Filter

Ein Filter ermöglicht es uns, Daten zu ändern, bevor sie für die Anzeige in einem Browser verarbeitet werden. Zu diesem Zweck akzeptiert ein Filter Variable(n), modifiziert den/die übergebenen Wert(e) und gibt Daten zur weiteren Verarbeitung zurück.

WordPress prüft und führt alle registrierten Filter aus, bevor Inhalte für Browser vorbereitet werden. Auf diese Weise können wir Daten manipulieren, bevor wir sie gegebenenfalls an den Browser oder die Datenbank senden.

Einer meiner Kunden personalisiert die Produkte, die er verkauft, indem er sie mit Bildern bedruckt, die Kunden bereitstellen. Dieser Client verwendet das WooCommerce-Plug-in, um E-Commerce zu verwalten. WooCommerce unterstützt diese Funktionalität nicht standardmäßig. Daher habe ich der functions.php meines Clients zwei Code-Bits hinzugefügt:

  1. woocommerce_checkout_cart_item_quantity , aufgeführt in der WooCommerce-Dokumentation, ist ein Filter-Hook, mit dem Kunden vor dem Bezahlvorgang externe Elemente zu ihren Einkaufswagen hinzufügen können.
  2. my_customer_image_data_in_cart ist ein Filter, den wir selbst schreiben und verwenden, um woocommerce_checkout_cart_item_quantity auszulösen, wenn WooCommerce einen Warenkorb für die Anzeige vorbereitet.

Mit der folgenden Vorlage können wir unseren Filter hinzufügen und das Standardverhalten des Einkaufswagens ändern:

 add_filter( 'woocommerce_checkout_cart_item_quantity', 'my_customer_image_data_in_cart', 1, 3 ); function my_customer_image_data_in_cart( $html, $cart_item, $cart_item_key ) { if ( !empty( $cart_item['images_data'] ) ) { // Store image // Get image URL // Modify $html } return $html; }

Wir fügen Filter genauso hinzu, wie wir Aktionen hinzufügen. Filter funktionieren ähnlich wie Aktionen, einschließlich der Verarbeitung von Prioritäten. Der Hauptunterschied zwischen Filtern und Aktionen besteht darin, dass eine Aktion keine Daten an den aufrufenden Hook zurückgibt, ein Filter jedoch schon.

Kundenspezifische Aktionshaken und Filterhaken

Das Schreiben benutzerdefinierter Action-Hooks erweitert Wordpress Core nicht, sondern erstellt lediglich neue Triggerpunkte in unserem eigenen Code.

Erstellen von benutzerdefinierten Action-Hooks

Durch das Hinzufügen eines benutzerdefinierten Hooks in unserem Design oder Plugin können andere Entwickler die Funktionalität erweitern, ohne unsere Codebasis zu ändern. Um einen benutzerdefinierten Hook hinzuzufügen, verwenden Sie dieselbe Technik, die die WordPress Core-Codebasis selbst verwendet: An unserem gewünschten Triggerpunkt rufen wir einfach do_action mit dem Namen unseres neuen Hooks auf und fügen optional so viele Argumente hinzu, wie unsere Callbacks nützlich finden könnten:

 do_action( 'myorg_hello_action', $arg1, $arg2 );

Dieser Code führt einfach alle Callback-Funktionen aus, die an unseren benutzerdefinierten Hook angeschlossen wurden. Beachten Sie, dass der Namensraum global ist, daher wäre es, wie bereits vorgeschlagen, eine gute Idee, unseren benutzerdefinierten Hook-Namen eine verkürzte Form des Namens unserer Organisation (und möglicherweise auch unseres Projekts) voranzustellen, daher hier myorg_ .

Nachdem wir myorg_hello_action definiert haben, steht es Entwicklern zur Verfügung, sich genau auf dieselbe Weise einzuklinken, die wir zuvor für integrierte Hooks behandelt haben: Definieren Sie eine Funktion und rufen Sie dann add_action() .

Sofern wir einen neuen Hook nicht rein intern verwenden wollen – es ist schließlich eine hilfreiche Möglichkeit, unseren Code zu strukturieren – müssen wir seine Verfügbarkeit nachgelagert, anderen Mitgliedern unseres Teams oder externen Benutzern unseres Plugins durch eine klare Dokumentation mitteilen .

Erstellen von benutzerdefinierten Filter-Hooks

Das WordPress-Muster für benutzerdefinierte Filter-Hooks ist das gleiche wie das für Aktions-Hooks, außer dass wir apply_filters() anstelle von do_action() .

Lassen Sie uns diesmal ein konkreteres Beispiel durchgehen. Angenommen, unser Plugin erstellt ein Seitenleistenmenü, das normalerweise aus vier Elementen besteht. Wir fügen einen benutzerdefinierten Filter-Hook hinzu, damit wir (und nachgeschaltete Entwickler) diese Liste von Elementen an anderer Stelle ändern können:

 // Text labels of sidebar menu $sidebar_menu = array( "Page One", "Page Two", "Page Three", "Page Four" ); $sidebar_menu = apply_filters( 'myorg_sidebar_menu', $sidebar_menu );

Das war's – unser benutzerdefinierter Filter-Hook myorg_sidebar_menu kann jetzt in einem Plugin verwendet werden, das später oder an anderer Stelle in diesem geladen werden kann. Dadurch kann jeder, der nachgelagerten Code schreibt, unsere Seitenleiste anpassen.

Wir oder andere Entwickler werden dem gleichen Muster folgen, wenn sie einen eingebauten WordPress-Hook verwenden. Mit anderen Worten, wir beginnen mit der Definition einiger Callback-Funktionen, die eine modifizierte Version der Daten zurückgeben, die ihnen übergeben werden:

 function lowercase_sidebar_menu( $menu ) { $menu = array_map( 'strtolower', $menu ); return $menu; } function add_donate_item( $menu ) { $menu = array_push( $menu, 'Donate' ); return $menu; }

Wie bei unseren früheren Beispielen sind wir jetzt bereit, unsere Filter-Callback-Funktionen mit unserem benutzerdefinierten Hook zu verknüpfen:

 add_filter( 'myorg_sidebar_menu', 'add_donate_item', 100 ); add_filter( 'myorg_sidebar_menu', 'lowercase_sidebar_menu' );

Damit haben wir unsere beiden Beispiel-Callback-Funktionen mit unserem benutzerdefinierten Filter-Hook verbunden. Beide modifizieren nun den ursprünglichen Inhalt von $the_sidebar_menu . Da wir add_donate_item einen höheren priority gegeben haben, wird es später ausgeführt, nachdem lowercase_sidebar_menu ausgeführt wurde.

Drei Felder, die die Ergebnisse der in diesem Abschnitt beschriebenen Filterfunktionen darstellen. Panel 1 zeigt die Seitenleiste, wie sie wäre, wenn kein Callback in den Filter eingehakt wäre. Panel 2 zeigt die Seitenleiste so, wie sie aussehen würde, wenn der Callback „lowercase_sidebar_menu“ in den Filter eingebunden wäre, mit allen vier Elementnamen in Kleinbuchstaben. Panel 3 zeigt die Seitenleiste so, wie sie wäre, wenn der donate_button-Callback auch in den Filter eingebunden wäre – die gleichen Kleinbuchstaben wie in Panel 2 plus ein fünftes Element, „Donate“, links im Titel.

Downstream-Entwicklern steht es immer frei, weitere Callback-Funktionen mit myorg_sidebar_menu zu verbinden. Dabei können sie den priority verwenden, um ihre Hooks vor, nach oder zwischen unseren beiden Beispiel-Callback-Funktionen laufen zu lassen.

Der Himmel ist die Grenze mit Aktionen und Filtern

Mit Aktionen, Filtern und Hooks kann die WordPress-Funktionalität sprunghaft wachsen. Wir können benutzerdefinierte Funktionen für unsere Website entwickeln, sodass unsere eigenen Beiträge genauso erweiterbar sind wie WordPress. Mit Hooks können wir uns an Sicherheit und Best Practices halten, während wir unsere WordPress-Seite auf die nächste Stufe bringen.

Der Toptal Engineering Blog dankt Fahad Murtaza für sein Fachwissen, seine Beta-Tests und seine technische Überprüfung dieses Artikels.