WordPress Hooks: Actions & Filters einfach erklärt

Hooks sind super wichtig, wenn du WordPress, als Entwicklerin, wirklich beherrschen willst. Falls du noch nie was davon gehört hast, wird sich das jetzt schnell auflösen.

Mit Actions und Filter kannst du u.a. Code ausführen und Daten manipulieren ohne Original Template-/Plugin-Dateien verändern zu müssen. Dadurch bleibt dein Code auch nach Plugin/Themes Updates funktional und zerhaut deine Website nicht.

Es gibt da zwei Arten von Hooks:

Actions (Aktionen)

  • Werden zu bestimmten Zeitpunkten ausgeführt
  • Du machst etwas, gibst aber nichts zurück
  • 1. Beispiel: Kritisches CSS im <head> ausgeben
  • 2. Beispiel: E-Mail senden, wenn ein Post veröffentlicht wird

Filters (Filter)

  • Verändern Daten, bevor sie angezeigt werden
  • Du bekommst etwas, veränderst es und gibst es zurück
  • 3. Beispiel: Standard Thumbnail setzen
  • 4. Beispiel: Versionsparameter aus Skripten entfernen

Easy Setup: So funktioniert’s

Die Grundsyntax von Action und Filter Hooks sehen wie folgt aus:

add_action( $hook_name, $funktionsname, $prioritaet, $anzahl_parameter );
add_filter( $filter_name, $funktionsname, $prioritaet, $anzahl_parameter );Code-Sprache: PHP (php)

Action Hook einbauen

function meine_super_funktion() {
    // Dieser Code wird einfach an dieser Stelle ausgeführt
}
add_action('hook_name', 'meine_super_funktion');Code-Sprache: PHP (php)

Filter Hook einbauen:

function meine_filter_funktion($data) {
    // Hier können wir $data verändern
    return $data;
}
add_filter('hook_name', 'meine_filter_funktion');Code-Sprache: PHP (php)

4 Praxis-Beispiele, die du sofort nutzen kannst

1. Action: Kritisches CSS (Above the fold) im <head> Bereich ausgeben (wp_head action)

Das mache ich gerne in meinen WordPress Templates um FOUC (Flash of unstyled content) zu vermeiden, denn das CSS wird SOFORT vom Browser gerendert, noch bevor andere CSS Dateien geladen werden.

function prpz_critical_css() {
	echo '<style>' . file_get_contents( get_template_directory() . '/styles/critical.css' ) . '</style>';
}
add_action( 'wp_head', 'prpz_critical_css', 100 );Code-Sprache: PHP (php)

Zur Erklärung nochmal: Bei actions wird dein Code einfach 1 zu 1 an der entsprechenden Stelle ausgegeben/ausgeführt.

2. Action: Automatische E-Mail bei neuen Posts

Möchtest du vielleicht dein Autorinnen benachrichtigen wenn ein entsprechender Artikel veröffentlicht wird? Da kannst du dich auch einfach „einhaken“, Daten aufbereiten und per E-Mail senden.

function prpz_notify_author_after_post_publish($post_id) { 
	$post = get_post($post_id);
	$author = get_userdata($post->post_author);
	$subject = "Dein Post wurde veröffentlicht";
	$headers = 'From: '.get_bloginfo( 'name' ).' <info@propz.de>' . "\r\n";
	$message = "
		Moin ".$author->display_name.",

		Dein post \"".$post->post_title."\" wurde gerade veröffentlicht.
		Post ansehen: ".get_permalink( $post_id )."
		
		Danke dir,
		propz";
		
	wp_mail($author->user_email, $subject, $message, $headers);
}
add_action('publish_post', 'prpz_notify_author_after_post_publish');Code-Sprache: PHP (php)

3. Filter: Standard Thumbnail setzen

In diesem Beispiel überprüfen ob bereits ein Thumbnail HTML-Markup existiert. Wenn nicht, erstelle ich ein eigenes als Standard Thumbnail.

function prpz_post_thumbnail_html( string $html, int $post_id, int $post_thumbnail_id, string|array $size, string|array $attr ): string
{
	if ( empty( $html ) )
	{
		$thumbnail_url = '/uploads/propz-blog-default.svg';
		$html = '<img src="' . esc_url( $thumbnail_url ) . '" alt="' . esc_attr( get_the_title( $post_id ) ) . '" />';
	}

	return $html;
}
add_filter( 'post_thumbnail_html', 'prpz_post_thumbnail_html', 10, 5 );Code-Sprache: PHP (php)

Woher weiß ich welche Parameter da genau übergeben werden und was da drin ist? Google (In diesem Fall: „wordpress post thumbnail hooks“)! Dann kommt man schnell zu der offiziellen WordPress Dokumentation für entsprechende Hooks. Hier der Link zur Dokumentation des oberen Beispiels.

4. Filter: Versionsparameter aus Skripten und Styles entfernen

Hier kann ich sogar die gleiche Funktion für zwei unterschiedliche Filter nutzen weil beide Filter gleich funktionieren.

function prpz_remove_version( string $src ): string {
	if( strpos( $src, '?ver=' ) )
		$src = remove_query_arg( 'ver', $src );
	return $src;
}
add_filter( 'style_loader_src', 'prpz_remove_version', 10, 2 );
add_filter( 'script_loader_src', 'prpz_remove_version', 10, 2 );Code-Sprache: PHP (php)

Wichtige Tipps

1. Hooks können wieder entfernt und verschoben werden

Es ist auch möglich bereits vorhandene Hooks von anderen Plugins oder Themes wieder zu entfernen. Ich nutze das gerne bei WooCommerce um z.B. Daten auszublenden die für mich irrelevant oder auch an einer andere Stelle besser aufgehoben wären.

Wie bereits erwähnt kann ich dadurch direkt Einfluss auf das Aussehen der Website nehmen ohne irgendeine Template-Datei anzufassen = Keine Gefahr beim nächsten Update.

// Entferne Produktbewertungen aus der Originalposition...
remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating', 5 );

// ... und füge es vor dem Produkttitel ein.
add_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_rating', 5 );Code-Sprache: PHP (php)

Woher ich weiß die die Hooks heißen? Stehen in den WooCommerce Template Dateien drin.

2. Setze die Prioritäten richtig

Du kannst bestimmen wann deine action genau ausgeführt wird. Beachte auch das vorherige Beispiel: wenn ich ein Hook entfernen möchte, muss ich ebenfalls die Original-Priorität kennen, sonst funktioniert das nicht.

add_action('hook_name', 'meine_funktion', 10); // Standard-Priorität
add_action('hook_name', 'wichtige_funktion', 1); // Läuft früher
add_action('hook_name', 'spaete_funktion', 99); // Läuft späterCode-Sprache: PHP (php)

3. Setze die Anzahl der übergeben Parameter richtig

Auch bei der Parametern muss du gut aufpassen. Wenn du die Anzahl der übergebenen/erwarteten Parameter falsch einträgst wird WordPress einen „fatal error“ schmeißen. Woher weißt du wie viele Parameter übergeben werden? Die Dokumentation wird es dir verraten.

Du kannst es auch direkt an der Stelle erkennen wo der entsprechende Hook ausgeführt wird.

4. Hooks werden nur ausgeführt wenn sie wirklich existieren

Wenn du einen Hook aufrufst der nicht existiert, passiert auch nichts. Es gibt keinen Fehler o.ä. D.h. du kannst auch ohne Probleme Plugins deaktivieren, Updates installieren und es wird alles wie gewohnt funktionieren.

Der Nachteil: wenn du dich verschreibst, wirst du keine Fehlermeldung bekomme, überprüfe den Hook Namen also immer doppelt.

5. Gib bei Filtern mindestens den Original-Wert zurück

Falls du mit einem Filter Daten manipulieren möchtest, vergiss nicht den Original-Wert zurückzugeben, wenn du keine Änderung vorgenommen hast.

function prpz_maybe_hide_quantity_on_checkout( string $quantity_markup, array $cart_item, string $cart_item_key): string {
	// Verstecke "Menge" Feld, wenn das Produkt nur einzelnt verkauft wird
	if ( $cart_item['data']->is_sold_individually() )
		return '';

	// Wichtig:
	// Gib den Original-Wert zurück: $quantity_markup
	// Sonst wird das Feld nie angezeigt und das wollen wir ja nicht.
	return $quantity_markup;
}
add_filter( 'woocommerce_checkout_cart_item_quantity', 'prpz_maybe_hide_quantity_on_checkout', 10, 3);Code-Sprache: PHP (php)

Funktionsweise von Hooks richtig verstehen

Nicht alle Plugins/Themes sind gut dokumentiert. Manchmal muss man sich den Code des Plugins zur Gemüte führen. Wie kannst du dann verstehen was der Hook genau macht? Ich werde hier zwei komplexere Beispiel genauer erläutern.

1. So findest du Hooks

Actions werden vom Code-Autor festgelegt.

Diese erkennst du wenn „do_action“ ausgeführt wird. D.h. überall wo do_action erscheint, kannst du dich mit add_action einhaken.

Bei Filter heißt es „apply_filters“. D.h. überall wo apply_filters ausgeführt wird, kannst dich mit add_filter einhaken und die Daten manipulieren.

2. Filter verstehen

Für meinem Webshop nutze ich „WooCommerce Germanized“ als extra Plugin. Das Plugin bietet auch die Option um Produktbilder im Checkout anzuzeigen. Das ist ne coole Funktion, aber für bestimmte Produkte möchte ich das nicht. Also habe ich in den Plugin Template Dateien gesucht ob ich das beeinflussen kann und folgendes gefunden:

...
if ( apply_filters( 'woocommerce_gzd_checkout_table_needs_thumbnail', ( ! strstr( $cart_item_name, $thumbnail ) ), $cart_item, $cart_item_key ) ) {
...Code-Sprache: PHP (php)

Genau da wird überprüft ob das Thumbnail dargestellt werden soll. Da der Plugin Entwickler mitgedacht hat, hat er dort ein Filter eingebaut, damit ich mich bei Bedarf einklinken kann.

Zur Erklärung:
Der erste Parameter ist immer der, der auch zurückgegeben wird: strstr Funktion gibt string oder false zurück.

Zusätzlich dazu bekommen wir weitere Parameter die für den Kontext relevant sind: $cart_item und $cart_item_key (in dem Kontext werden alle Warenkorb Produkte geloopt).

So sieht dann mein Code aus:

function prpz_maybe_hide_thumbnail_on_checkout( bool|string $needs_thumbnail, array $cart_item, string $cart_item_key ): bool|string {
	if ( $cart_item['data']->is_downloadable() || $cart_item['data']->is_virtual() )
	{
		return false;
	}
	return $needs_thumbnail;
}
add_filter( 'woocommerce_gzd_checkout_table_needs_thumbnail', 'prpz_maybe_hide_thumbnail_on_checkout', 100, 3 );Code-Sprache: PHP (php)

So kann ich selber überprüfen ob ich das Thumbnail für das jeweilige Produkt anzeigen lassen möchte oder nicht.

3. Action verstehen

Bei actions verhält sich das ganz ähnlich, mit dem Unterschied, dass kein Rückgabewert erwartet wird. Sehen wir uns dazu das 2. Beispiel an. Die do_action Dokumentation sagt folgendes:

do_action( “{$new_status}_{$post->post_type}”, int $post_id, WP_Post $post, string $old_status );Code-Sprache: PHP (php)

Hier wirds noch abgefahrener, denn der Hook Name wird dynamisch erstellt. Long story short: als Paramenter bekommen wir die wichtigsten Daten um an der entsprechenden Stelle benötigte Aktionen auszuführen.

Im besten Fall gibt es eine Dokumentation dazu aber wir können auch ohne Probleme auch aus dem Code rauslesen was wir genau brauchen und wie wir es nutzen können.

Wo findest du alle verfügbaren Hooks?

WordPress hat unzählige Hooks! Die findest du im WordPress Codex oder in der Code Reference. Einfach nach „wordpress [dein Thema] hook“ googeln und du findest schon was passendes.

Dein nächster Schritt

Jetzt ans Eingemachte! Schnapp dir ein Beispiel von oben und probier’s aus. Am besten in einem Child-Theme oder einem Test-Plugin, dann machst du auch nix kaputt.

Mit diesem Wissen kannst du WordPress nach deinen Vorstellungen anpassen, ohne Plugin-/Template-Dateien zu zerstören. Das ist professionelle WordPress-Entwicklung at its finest!

WordPress hat zu dem Thema auch noch einige ausführlichere Artikel erstellt. Schaut mal bei denen vorbei falls ihr noch Fragen habt:

Gib deinen Senf dazu

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert