WordPress – Wie man die Attribute von 3rth-Party Shortcodes zur Laufzeit anpasst

Nicht immer genügt es, die Attribute statisch an Shortcodes zu übergeben. Wir zeigen, wie man das zur Laufzeit macht. Für Shortcodes beliebiger 3th-Party Plugins.

Wozu braucht man das?
Nun, konstruieren wir mal ein Beispiel:
Angenommen, wir haben ein 3th-Party Plugin, dass einen Shortcode anbietet, welcher Kategorie-IDs und Tag-IDs entgegennimmt, um dann irgendetwas damit zu machen, zum Beispiel nur die Posts dieser Kategorien oder Tags darzustellen.
Der Shortcode könnte so aussehen:

[third-party-posts categories="5", tags="2,3,7"][/third-party-posts]

Was aber, wenn wir diese Attribute zur Laufzeit setzen könnten? Das wäre ja viel besser.
Im unserem letzten WordPress-Artikel haben wir bereits beschrieben, wie man Kategorien und Tags per POST-Variablen an eine WordPress-Seite oder einen Beitrag senden kann.
Darauf können wir hier nun zurückgreifen.

Wir gehen also davon aus, dass wir die POST-Variablen categories und tags haben und versuchen nun, diese an den Shortcode zu übergeben.

Vorbereitung: Plugin erstellen

Wir beginnen damit, ein Plugin zu erstellen, in dem wir unsere Extension für das 3th-Party Plugin implementieren wollen.
Wir legen also im plugin-Ordner der WordPress-Installation einen Unterordner und eine Datei für das Plugin an.

Dort beginnen wir mit den minimalen Metadaten:

<?php
/**
#_________________________________________________ PLUGIN
Plugin Name: Computerhalbwissen Third-Party-Plugin-Extension
Plugin URI: https://computerhalbwissen.de
Description: Wie man die Attribute von 3rth-Party Shortcodes zur Laufzeit anpasst.
Version: 1.0.0
Author: computerhalbwissen.de
Text Domain: chw-third-party-plugin-extension
#_________________________________________________ CONSTANTS
*
* @package Computerhalbwissen Third-Party-Plugin-Extension
* @since 1.0.0
**/

Nun schreiben wir für den Action Hook ‚do_shortcode_tag‘ eine Funktion oder einen Filter.
Der Hook filtert den Output, der von der Callback-Funktionen der Shortcodes erzeugt wird. Für jeden Shortcode kommt man also hier vorbei.

add_filter( 'do_shortcode_tag','extend_the_shortcode', 10, 4);
function extend_the_shortcode($output, $tag, $attr, $m){
  if('third-party-posts' != $tag){
    return $output;
  }
  // hier folgt die Implementierung
  // ...
  return $output;
}

Im Parameter $output ist der Inhalt des Shortcodes enthalten.
Im Parameter $tag steht der Bezeichner des Shortcodes drin.
Im Parameter $attr stehen alle Attribute des Shortcodes drin. In unserem Fall also categories und tags.
Der Parameter $m enthält: Regular expression match array. Das benötigen wir später.

Im ersten Schritt lassen wir die Funktion abbrechen, wenn es sich nicht um unseren gewünschten Shortcode handelt. Dann geben wir einfach den original Shortcode-Inhalt zurück.

Hinweis:
Es gibt keinen Unterschied im Verhalten von add_action und add_filter. Es dient mehr der Lesbarkeit.
Es gibt wohl folgende Regel:

An “add_action” in WordPress is what you use to create a trigger “hook”. When something happens, then do-something-else.
An “add_filter” is used to “hook” data, i.e. change/replace. For example, where there is [some-code], change it to some-other-expanded-code.

Shortcode-Attribute setzen

Im nächsten Schritt holen wir unsere Werte aus den POST-Variablen und übergeben diese an die Attribute des Shortcodes.
Dafür haben wir das Funktions-Attribut $attr.

// Attribute setzen
if(isset($_POST['categories']) && is_array($_POST['categories'])) {
  $attr['categories'] = $_POST['categories'];
}
if(isset($_POST['tags']) && is_array($_POST['tags'])) {
  $attr['tags'] = $_POST['tags'];
}

Neuen Inhalt des Shortcodes setzen und zurückgeben

Jetzt kommt eine Passage, die ich nicht verstanden habe. Denn hier wird irgendwie das Funktions-Attribut $m verwendet, welches ein Array mit Regex expression matches enthält. Hä?
Das habe ich 1 zu 1 diesem Code-Schnipsel entnommen.

global $shortcode_tags;
$content = isset( $m[5] ) ? $m[5] : null;
$output  = $m[1] . call_user_func( $shortcode_tags[ $tag ], $attr, $content, $tag ) . $m[6];

Hier passiert die Magie. Und es funktioniert.
Ganz schlau werde ich daraus allerdings noch nicht. Selbst, wenn ich mir die $m Variable ausgeben lasse.
Aber der Reihe nach. Wir beginnen in der ersten Zeile.

$shortcode_tags

Schaut man in den Quellcode der shortcodes.php von WordPress, so heißt es dort, dass die Variable $shortcode_tags folgendes ist: „Container for storing shortcode tags and their hook to call for the shortcode“

Lassen wir uns die Variable ausgeben, sehen wir, dass der Shortcode third-party-posts als Key im Array vorhanden ist und als Value die entsprechende Funktion des Shortcodes.

Ok. Verstanden so weit.

Das Funktions-Attribut $m

Jetzt wird es undurchsichtiger.
Starten wir damit, dass wir uns die Variable $m mal ausgeben lassen.

In $m[0] scheint der komplette Shortcode zu stehen, wie man ihn statisch auf der Seite oder im Beitrag eingebunden hat.
In $m[2] scheint der Name des Shortcodes drin zu stehen.
In $m[3] scheinen die im statischen Shortcode angegebenen Attribute drin zu stehen.
Und $m[1]? $m[5]?? $m[6]??? Keine Ahnung.

Es bleibt hier vage.

Zeile 2

In $m[5] soll wohl der Content stehen. Kann ich hier nicht nachvollziehen.
Wenn $m[5] gesetzt ist, wird diese als Content verwendet, sonst bleibt er null.
Na gut.

Zeile 3

Hier wird der Output erzeugt. Als Ergebnis erwarten wir hier das komplette HTML des Shortcodes mit unseren Änderungen.
Dafür wird die PHP-Funktion call_user_func aufgerufen, die als ersten Parameter eine Callback-Funktion erwartet. In unserem Fall ist das die Funktion des Shortcodes.
Als zweiten Parameter werden die Attribute erwartet. In unserem Fall sind das die Attribute für den Shortcode, inklusive unserer Änderungen.
Als dritter Parameter wird der Content erwartet.
Das sind genau die Attribute, die eine typische Funktion zum Erzeugen eines Shortcodes erwartet.
Der vierte Parameter ist dann noch mal der Name des Shortcodes.

So. Vorn dran kommt dann noch $m[1]. Hinten dran kommt dann $m[6].
Keine Ahnung.
Aber es funktioniert.

In $output steht nun der gefilterte Inhalt drin. Also das komplette erzeugte HTML.
Dieses müssen wir nur noch mit return zurückgeben.

Falls das jemand genauer erklären kann – Bitte gern in die Kommentare.

Die gesamte Funktion sieht dann so aus:

add_filter( 'do_shortcode_tag','extend_the_shortcode', 10, 4);
function extend_the_shortcode($output, $tag, $attr, $m){
  if('third-party-posts' != $tag){
    return $output;
  }
  
  // Attribute setzen
  if(isset($_POST['categories']) && is_array($_POST['categories'])) {
    $attr['categories'] = $_POST['categories'];
  }
  if(isset($_POST['tags']) && is_array($_POST['tags'])) {
    $attr['tags'] = $_POST['tags'];
  }
  
  global $shortcode_tags;
  $content = isset( $m[5] ) ? $m[5] : null;
  $output  = $m[1] . call_user_func( $shortcode_tags[ $tag ], $attr, $content, $tag ) . $m[6];
  
  return $output;
}

Fazit

Puh. Ich weiß nicht ganz genau wie, aber wir haben es geschafft.
Eine bessere Erklärung des Attributs $m und wie der Output genau erzeugt wird, muss ich an dieser Stelle schuldig bleiben.
Das ist alles sehr vage.
Sollte ich mehr herausfinden oder weitere Quellen finden, werde ich das hier ergänzen.

Bis dahin hoffe ich wie immer, diese erstbeste Lösung ist hilfreich.


Quellen:
https://wordpress.stackexchange.com/questions/279931/how-to-modify-shortcode-attributes-with-data-from-current-post
https://developer.wordpress.org/reference/hooks/do_shortcode_tag/
https://github.com/WordPress/WordPress/blob/master/wp-includes/shortcodes.php
https://www.quora.com/What-is-the-difference-between-add_action-and-add_filter-in-WordPress
https://wpwebsitetools.com/wordpress-add_filter-vs-add_action-functions-the-basics/
https://developer.wordpress.org/reference/functions/add_action/
https://developer.wordpress.org/reference/functions/add_filter/

Ähnliche Beiträge

Schreibe einen Kommentar

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