Extensible Plugins mit Aktionen und Filtern schreiben
German (Deutsch) translation by Władysław Łucyszyn (you can also view the original English article)
Eines der vielen Dinge, die Sie finden, wenn Sie den Quellcode eines guten Plugin-Entwicklers untersuchen, sind benutzerdefinierte Hooks und Filter, die der Entwickler im gesamten Plugin platziert hat. Das Vorhandensein dieser Aktionshaken und Filter macht das Plugin "erweiterbar", was bedeutet, dass andere Plugins und Themes das Verhalten des Plugins manipulieren oder hinzufügen können.
Extensible Plugins zu schreiben ist etwas, das ich dir gerne empfehlen würde. Es gibt viele gute Gründe, warum Sie es tun sollten, aber sehr wenige (wenn überhaupt) Gründe, warum Sie diese Praxis vermeiden sollten.
Wir werden uns einige Elemente erweiterbarer Plugins ansehen:
- Eine Erklärung, was erweiterbare Plugins sind
- Gründe, warum Sie erweiterbare Plugins schreiben sollten
- Die grundlegenden Werkzeuge, die Sie brauchen
- Wie Sie Ihre Plugins schreiben müssen, um sie erweiterbar zu machen
- Einfache Beispiele für Hooks und Filter, um zu veranschaulichen, wie Sie sie verwenden können
Ein wichtiger Hinweis: Dieses Tutorial wird rein prozedurbasierte Programmiertechniken verwenden. Alles, worüber ich hier rede, gilt immer noch, wenn man die objektorientierte Programmierung (Object Oriented Programming, OOP) verwendet, aber es ist einfacher, diese Techniken zuerst in einer prozeduralen Einstellung zu lernen.
Was ist ein erweiterbares Plugin?
Ein erweiterbares Plugin ist eines, das über seinen ursprünglichen Zweck hinaus durch ein anderes Plugin oder Theme verändert und erweitert werden kann. Wenn ein Plugin erweiterbar ist, können andere Plugins (oder Designs) das Verhalten oder die Ausgabe des Plugins verändern. Zum Beispiel erlauben E-Commerce-Plugins Add-On-Payment-Gateways, die die Verarbeitung von Käufen über zusätzliche Zahlungssysteme ermöglichen. Diese Zahlungsgateways sind separate Plugins, die sich einfach mit dem Kern-Plugin verbinden und dessen Funktionalität erweitern.
Alle Plugins können erweiterbar sein, obwohl nur eine kleine Minderheit der veröffentlichten Plugins vorhanden ist. Um erweiterbar oder modular zu sein (ein anderer Begriff für die gleiche Sache), muss der Entwickler eines Plugins eine bewusste Entscheidung treffen, indem er die notwendigen Elemente implementiert, die es anderen Plugins und Themes ermöglichen, sich in das Kern-Plugin einzufügen Verhalten.
Warum erweiterbare Plugins schreiben?
Es gibt viele gute Gründe, um erweiterbare Plugins zu schreiben, aber einer der Hauptgründe ist, dass es einfach keinen guten Grund gibt, Ihre Plugins nicht so zu schreiben, besonders nicht, wenn Ihre Plugins in der WordPress Community veröffentlicht werden kostenlose oder kostenpflichtige Plugins.
Wenn Sie erweiterbare Plugins schreiben, ermöglichen Sie anderen Entwicklern, Ihr Plugin zu erweitern und es noch besser zu machen, ohne jedoch den Kern-Quellcode zu ändern. Sie erleichtern es Entwicklern und Anwendern zudem, das Plugin besser an ihre Bedürfnisse anzupassen. Lassen Sie mich ein Beispiel geben: In meinem Easy Digital Downloads Plugin gibt es ein Rabatt-Code-System. Rabattcodes sind auf eine einmalige Verwendung pro Benutzer beschränkt. Wenn ein Nutzer versucht, denselben Rabatt auf zwei verschiedene Käufe anzuwenden, wird ein Fehler angezeigt. Einer meiner Nutzer aus der realen Welt stellte fest, dass sie Rabatte nicht auf eine einzige Nutzung pro Nutzer beschränken wollte. Daher gab ich ihr eine einfache Funktion, die sie in ein neues benutzerdefiniertes Plugin einfügte und die Beschränkung entfernte, ohne einen Kern-Plugin-Code zu berühren.
Erweiterbarer Code macht auch andere Entwickler sehr glücklich, wenn sie ihn finden, weil ihre Aufgabe, Ihren Code anzupassen, viel einfacher geworden ist.
Die grundlegenden Werkzeuge / Funktionen
Es gibt mehrere wichtige Werkzeuge, die Sie benötigen, um erweiterbare Plugins zu schreiben. Wenn Sie vor dem Lesen irgendwelche Plugins oder Themes geschrieben haben, sind Sie wahrscheinlich mit diesen Funktionen zumindest ein bisschen vertraut, auch wenn dies nur deshalb der Fall ist, weil Sie sie gesehen haben.
Bevor ich Ihnen die Funktionen zeige, die Sie verwenden werden, sprechen wir zunächst über zwei Hauptkonzepte: Haken und Filter.
Ein Aktionshook ist ein Platz in Ihrem Plugin, der durch Funktionen (sowohl in Ihrem Plugin als auch in anderen Plugins) "eingehängt" werden kann, damit der Code an diesem Punkt ausgeführt werden kann. Wenn ein Aktions-Hook ausgeführt wird, werden alle Funktionen ausgeführt, die mit ihm verbunden sind.
Ein Filter-Hook ist auch ein Platz in Ihrem Plugin für andere Funktionen, an die Sie sich binden können, aber sie funktionieren etwas anders als Aktionen. Mithilfe von Filtern können Daten vor ihrer Verwendung manipuliert oder geändert werden.
Der Hauptunterschied zwischen Aktionen und Filtern besteht darin, dass normalerweise Aktionen zum Ausführen von Funktionen und Filter zum Manipulieren von Daten verwendet werden.
Wenn Sie mit Aktionen und Filtern nicht vertraut sind, sollten Sie unbedingt den Codex-Eintrag lesen.
Für Aktionen gibt es vier Hauptfunktionen:
-
do_action()- Dies definiert einen hookbaren Ort für Aktionen -
add_action()- Dies hängt eine Funktion an einen mitdo_action()erstellten Hook an -
has_action()- überprüft, ob eine Aktion mitdo_action()registriert wurde -
remove_action()- Entfernt eine Aktion, die mitadd_action()gesetzt wurde
Von diesen vier werden Sie do_action() und add_action() am häufigsten verwenden.
Für Filter gibt es auch vier Hauptfunktionen:
-
apply_filters()- Dies erstellt einen anklickbaren Speicherort für benutzerdefinierte Filter, an die Sie sich binden können -
add_filter()- Dies hängt einen benutzerdefinierten Filter an einen Hook an, der mitapply_filters()erstellt wurde -
has_filter()- überprüft, ob ein Filter beiapply_filters()registriert wurde -
remove_filter()- entfernt einen zuvor mitapply_filters()verbundenen Filter
Wie bei Aktionen sind apply_filters() und add_filter() die beiden, die Sie am häufigsten verwenden.
Wenn Sie an dieser Stelle verwirrt sind, machen Sie sich keine Sorgen, wir werden uns ansehen, wie Sie diese im nächsten Abschnitt verwenden können.
Implementierung in eigenen Plugins
Um Ihr Plugin wirklich erweiterbar zu machen, müssen Sie die oben genannten Schlüsselfunktionen im gesamten Plugin verwenden. Am Anfang mag es schwierig, umständlich, ärgerlich oder viele andere anwendbare Adjektive sein, diese zusätzlichen Funktionen ständig in Ihrem Code zu platzieren, besonders wenn Sie keinen unmittelbaren Nutzen oder Nutzen für sie sehen.
Was Sie jedoch finden werden ist, dass sobald Sie die Gewohnheit haben, Ihre Plugins mit all diesen Funktionen im Hinterkopf zu schreiben, wird es zur zweiten Natur werden, sie einzuschließen.
Es gibt einige Hauptszenarien, in denen Sie Filter in Ihren Plugins verwenden:
- Wenn Arrays eingerichtet sind. Filter werden hier hinzugefügt, damit andere Plugins die Daten vor ihrer Verwendung modifizieren können.
- Wenn Datenobjekte eingerichtet werden. Genau wie bei Arrays verwenden Sie einen Filter für Objekte, damit andere Entwickler das Objekt vor der Verwendung ändern können.
- Wenn Datenzeichenfolgen eingerichtet werden. Wenn ein Filter für eine Zeichenfolge verfügbar ist, können andere Entwickler die gesamte Zeichenfolge ändern, Teile davon ändern oder hinzufügen.
In den oben genannten Szenarien werden Filter am häufigsten verwendet, wenn Daten zurückgegeben werden oder kurz bevor sie verwendet werden. Wenn Sie beispielsweise ein Plug-in haben, das eine Posts-Abfrage durchführt, empfiehlt es sich, das Array der Abfrageargumente über einen Filter zu übergeben, bevor sie an get_posts() oder WP_Query übergeben werden, damit andere die Abfrage manipulieren können.
Wenn es um Aktionen geht, gibt es auch mehrere Hauptinstanzen, in denen Sie sie platzieren:
- Bevor eine Aufgabe ausgeführt wird.
- Nachdem eine Aufgabe ausgeführt wurde.
- In Ihrem Markup können Sie zusätzliche Markups einfügen.
Lassen Sie uns jetzt ein paar Beispiele betrachten.
1. Anzeigen von HTML mit einem Shortcode
Shortcodes, die HTML ausgeben, sind extrem häufig (tatsächlich sind sie wahrscheinlich die gebräuchlichsten aller Shortcodes), und eine Art, wie wir die Shortcodes unseres Plugins freundlicher für andere Entwickler machen können, besteht darin, ihnen eine Möglichkeit zu geben, den Inhalt des Codes zu ändern Shortcode, aber ohne dass es wieder abgemeldet und registriert werden muss.
Alle Shortcodes geben ihren Inhalt zurück, statt sie zu wiederholen, was bedeutet, dass die auf dem Bildschirm ausgegebenen Daten in Form einer Zeichenfolge vorliegen, bevor sie zurückgegeben werden. Da die gesamte HTML-Ausgabe in Form einer Zeichenfolge vorliegt, können Sie die Zeichenfolge vor dem Zurückgeben durch einen Filter übergeben. Dadurch können andere Entwickler den HTML-Code Ihres Shortcodes ändern.
Ein Entwickler möchte möglicherweise zusätzliches Markup vor und nach dem Standard-HTML hinzufügen: Mit dem vorhandenen Filter können sie das tun.
Ihr Shortcode könnte etwa so aussehen:
1 |
|
2 |
function wptp_sample_shortcode( atts, $content = null ) { |
3 |
|
4 |
$html = '<div class="wptp_shortcode">'; |
5 |
$html .= '<p>Contents of the sample shortcode</p>'; |
6 |
$html .= '</div>'; |
7 |
|
8 |
return $html; |
9 |
|
10 |
}
|
Wir können dies verbessern, indem wir der Rückgabe einen Filter hinzufügen:
1 |
|
2 |
function wptp_sample_shortcode( atts, $content = null ) { |
3 |
|
4 |
$html = '<div class="wptp_shortcode">'; |
5 |
$html .= '<p>Contents of the sample shortcode</p>'; |
6 |
$html .= '</div>'; |
7 |
|
8 |
return apply_filters( 'wptp_shortcode_html', $html ); |
9 |
|
10 |
}
|
Der HTML-Code in unserem Shortcode kann nun wie folgt geändert werden:
1 |
|
2 |
function wptp_modify_html( $html ) { |
3 |
return '<div class="extra_div">' . $html . '</div>'; |
4 |
}
|
5 |
add_filter( 'wptp_shortcode_html', 'wptp_modify_html' ); |
Dies führt dazu, dass das ursprüngliche HTML, das im Shortcode erstellt wurde, mit einem anderen div Tag umschlossen wird.
2. Abfragen von Posts
Das Ausführen von benutzerdefinierten Abfragen in Plug-ins ist eine gängige Praxis. Nehmen wir einmal an, Sie hätten ein Plugin geschrieben, das einen benutzerdefinierten Posttyp namens "Bücher" registriert, und in Ihrem Plugin ist eine Funktion, um erstellte Bücher anzuzeigen. Ihre Funktion zum Abfragen der Bücher könnte etwa so aussehen:
1 |
|
2 |
function wptp_show_books() { |
3 |
|
4 |
$query_args = array( |
5 |
'post_type' => 'books', |
6 |
'posts_per_page' => 5 |
7 |
);
|
8 |
|
9 |
$books = new WP_Query( $query_args ); |
10 |
if( $books->have_posts() ) : |
11 |
while( $books->have_posts() ) : $books->the_post() |
12 |
// show info about each book here
|
13 |
endwhile; |
14 |
endif; |
15 |
wp_reset_postdata(); |
16 |
|
17 |
}
|
Was aber, wenn ein Benutzer die Art der zurückgegebenen Bücher ändern wollte und vielleicht nur Bücher aus einer bestimmten Kategorie auswählte? Sie können dies viel einfacher für sie machen, indem Sie dies tun:
1 |
|
2 |
function wptp_show_books() { |
3 |
|
4 |
$query_args = array( |
5 |
'post_type' => 'books', |
6 |
'posts_per_page' => 5, |
7 |
'author' => 3 |
8 |
);
|
9 |
|
10 |
$books = new WP_Query( apply_filters( 'wptp_books_query', $query_args ) ) ; |
11 |
if( $books->have_posts() ) : |
12 |
while( $books->have_posts() ) : $books->the_post() |
13 |
// show info about each book here
|
14 |
endwhile; |
15 |
endif; |
16 |
wp_reset_postdata(); |
17 |
|
18 |
}
|
Die einzige Änderung, die ich vorgenommen habe, war einen Filter um die $query_args hinzuzufügen, was bedeutet, dass andere Entwickler (oder Benutzer) die Abfrageargumente ändern können, bevor sie an WP_Query übergeben werden. Zum Beispiel könnten wir die Abfrage so einstellen, dass nur Bücher von Autor 3 wie folgt angezeigt werden:
1 |
|
2 |
function wptp_alter_books_query( $args ) { |
3 |
$args['author'] = 3; |
4 |
return $args; |
5 |
}
|
6 |
add_filter( 'wptp_books_query', 'wptp_alter_books_query' ); |
3. Markup verlängern
Lassen Sie uns jetzt auf Nummer 2 eingehen und es noch besser machen. Wir haben bereits einen Filter hinzugefügt, mit dem Benutzer die Abfrage ändern können. Nun fügen wir ein paar Hooks hinzu, um den erstellten HTML-Code zu ändern.
Zuerst modifizieren wir unseren ursprünglichen HTML-Code:
1 |
|
2 |
function wptp_show_books() { |
3 |
|
4 |
$query_args = array( |
5 |
'post_type' => 'books', |
6 |
'posts_per_page' => 5, |
7 |
'author' => 3 |
8 |
);
|
9 |
|
10 |
$books = new WP_Query( apply_filters( 'wptp_books_query', $query_args ) ; |
11 |
if( $books->have_posts() ) : |
12 |
|
13 |
echo '<div class="wptp_books">'; |
14 |
|
15 |
while( $books->have_posts() ) : $books->the_post() |
16 |
|
17 |
echo '<div class="wptp_book">'; |
18 |
|
19 |
echo '<h3 class="wptp_book_title">' . get_the_title() . '</h3>'; |
20 |
|
21 |
echo '</div>'; |
22 |
|
23 |
endwhile; |
24 |
|
25 |
echo '</div>'; |
26 |
|
27 |
endif; |
28 |
wp_reset_postdata(); |
29 |
|
30 |
}
|
Wir möchten nun Entwicklern die Möglichkeit bieten, an verschiedenen Stellen zusätzliches Markup hinzuzufügen, beispielsweise:
- Bevor HTML ausgegeben wird
- Nach dem Ende HTML
- Vor dem Titel jedes Buches
- Nach dem Titel jedes Buches
Sie können sich ein Szenario vorstellen, in dem ein Benutzer ein Vorschaubild vor oder nach dem Buchtitel hinzufügen möchte. Um dies zu ermöglichen, verwenden wir do_action(), um hookable locations wie folgt zu erstellen:
1 |
|
2 |
function wptp_show_books() { |
3 |
|
4 |
$query_args = array( |
5 |
'post_type' => 'books', |
6 |
'posts_per_page' => 5, |
7 |
'author' => 3 |
8 |
);
|
9 |
|
10 |
$books = new WP_Query( apply_filters( 'wptp_books_query', $query_args ) ); |
11 |
if( $books->have_posts() ) : |
12 |
|
13 |
do_action( 'wptp_books_before' ); |
14 |
echo '<div class="wptp_books">'; |
15 |
|
16 |
while( $books->have_posts() ) : $books->the_post() |
17 |
|
18 |
echo '<div class="wptp_book">'; |
19 |
|
20 |
do_action( 'wptp_before_book_title', get_the_ID() ); |
21 |
|
22 |
echo '<h3 class="wptp_book_title">' . get_the_title() . '</h3>'; |
23 |
|
24 |
do_action( 'wptp_after_book_title', get_the_ID() ); |
25 |
|
26 |
echo '</div>'; |
27 |
|
28 |
endwhile; |
29 |
|
30 |
echo '</div>'; |
31 |
do_action( 'wptp_books_after' ); |
32 |
|
33 |
endif; |
34 |
wp_reset_postdata(); |
35 |
|
36 |
}
|
Beachten Sie, dass die zwei inneren Hooks (die den Titel umgeben) einen zweiten Parameter von get_the_ID() haben. Diese Variable, bei der es sich um die ID des Buchs handelt, steht als Parameter für jede Hook-Funktion zur Verfügung. Um beispielsweise ein Buch-Thumbnail hinzuzufügen, können wir Folgendes tun:
1 |
|
2 |
function wptp_show_book_image( $book_id ) { |
3 |
echo get_the_post_thumbnail( $book_id, 'thumbnail' ); |
4 |
}
|
5 |
add_action( 'wptp_before_book_title', 'wptp_show_book_image' ); |
Beispiele aus der realen
WeltIch möchte Ihnen jetzt einige reale Beispiele für Plugins zeigen, die erweiterbar sind, einschließlich Beispielen einiger ihrer erweiterbaren Funktionen.
1. Soliloquy
Soliloquy ist ein leistungsstarkes, auf WordPress ansprechendes Bild-Slider-Plugin, das die Erstellung und Verwaltung von reaktionsschnellen, effizienten, sicheren und SEO-freundlichen Bild-Slidern zum Kinderspiel macht.
Fast alles in diesem Plugin ist erweiterbar. Hier ist nur ein Beispiel:
1 |
|
2 |
$labels = apply_filters( 'tgmsp_post_type_labels', array( |
3 |
'name' => __( 'Soliloquy', 'soliloquy' ), |
4 |
'singular_name' => __( 'Soliloquy', 'soliloquy' ), |
5 |
'add_new' => __( 'Add New', 'soliloquy' ), |
6 |
'add_new_item' => __( 'Add New Soliloquy Slider', 'soliloquy' ), |
7 |
'edit_item' => __( 'Edit Soliloquy Slider', 'soliloquy' ), |
8 |
'new_item' => __( 'New Soliloquy Slider', 'soliloquy' ), |
9 |
'view_item' => __( 'View Soliloquy Slider', 'soliloquy' ), |
10 |
'search_items' => __( 'Search Soliloquy Sliders', 'soliloquy' ), |
11 |
'not_found' => __( 'No Soliloquy Sliders found', 'soliloquy' ), |
12 |
'not_found_in_trash' => __( 'No Soliloquy Sliders found in trash', 'soliloquy' ), |
13 |
'parent_item_colon' => '', |
14 |
'menu_name' => __( 'Soliloquy', 'soliloquy' ) |
15 |
) ); |
16 |
|
17 |
$args = apply_filters( 'tgmsp_post_type_args', array( |
18 |
'labels' => $labels, |
19 |
'public' => true, |
20 |
'exclude_from_search' => true, |
21 |
'show_ui' => true, |
22 |
'show_in_admin_bar' => false, |
23 |
'rewrite' => false, |
24 |
'query_var' => false, |
25 |
'menu_position' => 100, |
26 |
'menu_icon' => plugins_url( 'css/images/menu-icon.png', dirname( __FILE__ ) ), |
27 |
'supports' => array( 'title' ) |
28 |
) ); |
Dies ist, wie Thomas Griffin (der Entwickler des Plugins) die Argumente für die benutzerdefinierten Beschriftungen und Attribute des Post-Typs einrichtet. Das Vorhandensein seiner zwei Filter, tgmsp_post_type_labels und tgmsp_post_type_args, macht es anderen Entwicklern sehr einfach, den Slider-Post-Typ umzubenennen oder zu ändern, was der Post-Typ unterstützt.
2. bbPress
Bei weitem eines meiner persönlichen Lieblings-Plugins aller Zeiten, ist bbPress ein voll funktionsfähiges Forum-Plugin für WordPress. Das gesamte Plugin ist ein perfektes Beispiel dafür, wie man Plugins erweiterbar macht, da es buchstäblich überall Aktionen und Filter hat. Es hat einen bestimmten Filter, der angewendet wird, wenn der Inhalt eines Forums abgerufen wird:
1 |
|
2 |
function bbp_get_forum_content( $forum_id = 0 ) { |
3 |
$forum_id = bbp_get_forum_id( $forum_id ); |
4 |
|
5 |
// Check if password is required
|
6 |
if ( post_password_required( $forum_id ) ) |
7 |
return get_the_password_form(); |
8 |
|
9 |
$content = get_post_field( 'post_content', $forum_id ); |
10 |
|
11 |
return apply_filters( 'bbp_get_forum_content', $content, $forum_id ); |
12 |
}
|
Bevor der Inhalt des Forums zurückgegeben wird, wird ein Filter namens bbp_get_forum_content übergeben, der es einem Entwickler ermöglicht, den Inhalt zu ändern, bevor er angezeigt wird.
3. Einfache digitale Downloads
Easy Digital Downloads, oder EDD, ist eines meiner Plugins, das speziell dafür entwickelt wurde, digitale Produkte über WordPress besonders einfach zu verkaufen. Wie bei den meisten E-Commerce-Plugins hat EDD einen Checkout-Prozess, den der Käufer durchläuft, damit er seine persönlichen und Zahlungsdetails eingeben kann. Nachdem alle diese Informationen gesammelt sind, geht alles an ein Zahlungs-Gateway (ein System zur Verarbeitung der Zahlung), aber bevor es zum Gateway gelangt, wird ein Filter angewendet, der es ermöglicht, die Daten zu manipulieren, bevor sie von der Zahlung verwendet werden System:
1 |
|
2 |
$purchase_data = apply_filters( |
3 |
'edd_purchase_data_before_gateway', |
4 |
$purchase_data, |
5 |
$valid_data
|
6 |
);
|
Das Vorhandensein dieses Filters ermöglicht es, Kaufbeträge anzupassen (vielleicht für spezielle Rabatte), Steuern hinzuzufügen, vielleicht Produkte aus dem Kauf hinzuzufügen oder zu entfernen, und vieles, vieles mehr.
Fazit
Erweiterbare Plugins kommen allen zugute: dem ursprünglichen Entwickler, anderen Entwicklern und den Benutzern selbst.
Es gibt so viele Gründe, warum Sie Ihre Plugins mit erweiterbarem Code schreiben sollten. Warum also nicht?
Die hier vorgestellten Werkzeuge sind alles, was Sie benötigen, um zu beginnen. Habe Fragen? Frag 'weg!



