Der folgende Text ist ein Gastbeitrag von Jason Witt. Ich weiß schon seit einiger Zeit, dass ich viele Dinge aus meiner `functions.php`-Datei in meinem WordPress-Theme in ein Funktionalitäts-Plugin auslagern sollte. Aber Sie wissen ja, Stunden am Tag und so weiter. Kürzlich habe ich Jason beauftragt, dieses Projekt für mich zu übernehmen, und er hat großartige Arbeit geleistet. Wenn Sie keine Ahnung haben, wovon ich spreche, lesen Sie weiter.
Das Hinzufügen neuer Funktionalitäten zu einer WordPress-Website kann so einfach sein, wie das Suchen eines Plugins im WordPress Plugin Repository und das Installieren dieses Plugins. Aber es gibt einige benutzerdefinierte Funktionalitäten, die Sie benötigen könnten, die entweder zu grundlegend oder zu benutzerdefiniert sind, als dass es dafür ein Plugin gäbe. Hier kommt die `functions.php`-Datei ins Spiel. Sie ist im Wesentlichen eine Sammelstelle für die Funktionalität eines Themes.
Aber einige des Codes, den wir dort tendenziell ablegen, wäre woanders besser aufgehoben.
Die `functions.php`-Datei ist ein einfacher Ort, um Dinge wie Theme-Support-Optionen, benutzerdefinierte Inhaltstypen, das Einbinden von JavaScript und (wirklich) alles andere hinzuzufügen, was Ihnen einfällt. Jahrelang war dies die De-facto-Methode, um benutzerdefinierte Funktionalitäten zu Ihrem WordPress-Theme hinzuzufügen. In den letzten Jahren gab es eine Bewegung, die Funktionalität, die normalerweise in die `functions.php`-Datei gehört, **in ein "Funktionalitäts-Plugin" zu verlagern.**
Was ist ein Funktionalitäts-Plugin?
Ein Funktionalitäts-Plugin ist einfach ein Plugin wie jedes andere, das Sie im WordPress Plugin Repository finden. Der Hauptunterschied besteht darin, dass es nicht öffentlich verbreitet würde, da es spezifisch für Ihre Website ist. Es ist ein benutzerdefiniertes Plugin, das die gesamte benutzerdefinierte Funktionalität *Ihrer* Website umfasst.

Was ist so toll an einem Funktionalitäts-Plugin?
Warum sollten Sie Zeit damit verbringen, ein Plugin zu entwickeln, wenn das Einbringen Ihrer Funktionalität in Ihre `functions.php`-Datei so einfach ist? Der große Vorteil ist, dass **Sie Ihre Funktionalität von Theme zu Theme wiederverwenden können.** Beim Aktualisieren/Ändern Ihres Themes bleibt ein Teil des Codes in der `functions.php` gleich und ein Teil ändert sich. Die Idee hinter einem Funktionalitäts-Plugin ist, die Funktionalität, die sich von Theme zu Theme nicht ändert, zu nehmen und in ein Plugin zu packen. So müssen Sie nicht mehr in Ihrer `functions.php`-Datei nach dem suchen, was Sie behalten möchten, sondern können sich direkt in das Design Ihres neuen Themes stürzen.
Was kommt in das Plugin?
Das ist die Million-Dollar-Frage. Was genau kommt in ein Funktionalitäts-Plugin? Der beste Ansatz ist zu entscheiden, was spezifisch für das *Theme* und was spezifisch für die *Website* ist. Zum Beispiel wäre ein benutzerdefinierter Inhaltstyp **spezifisch für eine Website**, und die Unterstützung für Beitragsbilder ist **spezifisch für ein Theme**.
Lassen Sie uns das einen Moment lang unterbrechen, damit es super klar wird.
Stellen Sie sich vor, Ihre Website hat einen Abschnitt für Meetups. Sie haben einen benutzerdefinierten Inhaltstyp dafür erstellt, damit sie eine besondere Art von Inhalt sein können. Auf der Frontend der Website stellen Sie sie auf besondere Weise dar. Auf der Backend der Website sammeln Sie spezielle Informationen, die spezifisch für Meetups sind. Wie in diesem CSS-Tricks Video. Wir nennen das **Theme A**.
Wenn Sie das Theme Ihrer Website ändern ( **Theme B**), werden Ihre Meetups wahrscheinlich nicht verschwinden? Wahrscheinlich nicht. Das sind Website-Inhalte, die Sie wahrscheinlich über jedes bestimmte Theme hinaus beibehalten möchten.
Wenn Sie all diese benutzerdefinierten Inhaltstyp-Sachen (z. B. `register_post_type()`) in Ihrer `functions.php`-Datei von **Theme A** deklariert hätten und dann zu **Theme B** wechseln – *könnten Sie einen leichten Herzinfarkt erleiden*, wenn Sie bemerken, dass all Ihre Meetup-Informationen verschwunden sind. Die `functions.php`-Datei von Theme A ist nicht mehr aktiv, daher wird der gesamte Code, der den benutzerdefinierten Inhaltstyp deklariert, nicht mehr ausgeführt. Die Menüs werden nicht zum Admin-Bereich hinzugefügt, die Inhalte scheinen verschwunden zu sein.
Seien Sie versichert, die Daten sind noch da, Sie müssen nur sicherstellen, dass der Code für die benutzerdefinierten Inhaltstypen wieder ausgeführt wird.
Warum sich das alles antun? Verschieben Sie diesen Code einfach in ein Funktionalitäts-Plugin, und er bleibt auch beim Wechseln der Themes aktiv.
Stellen Sie sich nun etwas ganz anderes vor: Code in Ihrer `functions.php`-Datei, der eine JavaScript-Bibliothek lädt. Sie verwenden diese Bibliothek wahrscheinlich, um Dinge auf dem Frontend Ihrer Website zu tun. Das ist ziemlich spezifisch für das Theme. Ein anderes Theme könnte ganz andere Bibliotheken verwenden oder gar keine. Diese Art von Dingen gehört in die `functions.php`-Datei, da sie *spezifisch für das Theme* und nicht für den Inhalt ist.
Beispiele für Dinge, die in `functions.php` sinnvoll sind
- Die Theme-Support-Funktionen, z. B. `add_theme_support('post-thumbnails');`
- JavaScript, das sich auf das Frontend bezieht
- Hinzufügen eines benutzerdefinierten Inhaltstyps zur Beitragsliste Ihrer Startseite
- Registrieren von Sidebars und Navigationsmenüs
- Hinzufügen einer externen CSS-Datei, zum Beispiel einer benutzerdefinierten Schriftart
Beispiele für Dinge, die in einem Funktionalitäts-Plugin sinnvoll sind
- Benutzerdefinierte Inhaltstypen
- Benutzerdefinierte Taxonomien
- Benutzerdefinierte Funktionalität für andere Plugins
- Benutzerdefinierte Meta-Felder
- Meist benutzerdefinierte Dinge
Erste Schritte
Wenn Sie noch nie ein WordPress-Plugin erstellt haben, ist dies eine großartige Möglichkeit, etwas Erfahrung zu sammeln.
Zuerst erstellen Sie ein Verzeichnis in Ihrem Plugin-Verzeichnis. Benennen Sie es, wie Sie möchten. Vermeiden Sie die Verwendung von Zahlen und Sonderzeichen; Bindestriche und Unterstriche sind in Ordnung. Ich gehe meist mit etwas wie `mysitename-functionality`.
Erstellen Sie in Ihrem neuen Plugin-Ordner eine Datei mit einem ähnlichen Namen wie der Ordner, `mysitename-functionality.php`.
Ganz oben in dieser Datei möchten Sie die Kopfzeileninformationen des Plugins hinzufügen. Hier ist ein Beispiel, um Ihnen den Einstieg zu erleichtern.
/**
* Plugin Name: Your Functionality Plugin Name
* Plugin URI: http://example.com/plugin-name-uri/
* Description: This is a short description of what the plugin does. It's displayed in the WordPress admin area.
* Version: 1.0.0
* Author: Your Name or Your Company
* Author URI: http://example.com/
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: plugin-name
* Domain Path: /languages
*/
Danach können Sie loslegen und Ihre Funktionalität darunter hinzufügen.
Sie können den Code buchstäblich einfach aus `functions.php` in diese Datei kopieren und einfügen, und solange dieses Plugin aktiviert ist, sollte es funktionieren.
Modulares Design
Wenn Sie wie ich sind und Dinge ordentlich und sauber halten möchten, ist dies eine großartige Zeit, um einen modularen Ansatz für den Code zu verwenden, den Sie in Ihr Plugin einfügen.
Ein Ansatz, um die Dinge einfach zu halten, ist die Organisation Ihrer Funktionalität in ähnliche Gruppen und die Zuweisung jeder Gruppe zu einer eigenen Datei. Inkludieren Sie dann diese Dateien mit PHP-Includes in die Hauptdatei des Plugins. Achten Sie darauf, Ihre Funktionen zu kommentieren, damit Sie, wenn Sie später darauf zurückkommen, wissen, was vor sich geht.
include 'mysitename-functionality-post-types.php';
include 'mysitename-functionality-extra-rss-feeds.php';
include 'mysitename-functionality-remove-unwanted-assets.php';
Ein anderer Ansatz ist die Verwendung von objektorientierter Programmierung (OOP). Dies beinhaltet die Erstellung von PHP-Klassen und -Methoden. Wenn Sie mit objektorientierter Programmierung nicht vertraut sind, gibt es ein großartiges Tutorial von Tom McFarlin namens Object-Oriented Programming in WordPress. Sie sollten es sich ansehen, wenn Sie daran interessiert sind, Ihre WordPress-Programmierkenntnisse zu erweitern. OOP ist eine großartige Möglichkeit, Ihren Code zu organisieren, die es Ihnen ermöglicht, ihn entsprechend Ihren sich ändernden Funktionalitätsanforderungen zu erweitern.
Reales Beispiel
Wenn Sie sich das CSS-Tricks Funktionalitäts-Plugin ansehen möchten, hier ist ein Repository auf GitHub, das Sie sich ansehen können.
Nach diesem Übergang hier ist das Einzige, was noch in der `functions.php`-Datei verbleibt, das Laden von jQuery und ein Hook, der die Standard-HTML-Kommentarausgabe überschreibt – beides sind Dinge, die sehr spezifisch für das aktuelle Theme sind.
Ja. Gute Sache.
Nur so am Rande: Ich setze auf DRY (Don't Repeat Yourself) und lagere so viel Funktionalität wie möglich in ein Framework / eine Bibliothek aus. Infolgedessen sind die spezifischen Plugins / Sub-Plugins eines bestimmten Projekts (lesen Sie: die inkludierten Teile) nur die "Todo"-Argumente, die notwendig sind, um einen bestimmten Zauber zu wirken. Jeglicher redundante WP-Überschuss bleibt der Elternklasse überlassen.
https://github.com/WPezClasses
FYI – irgendwo in all diesen Repositories gibt es eine Anleitung für den Einstieg :) Und ja, ich arbeite daran, die Dokumentation zu erweitern und eine korrekte PHP-Namensraumung zu verwenden.
Kommentare. Fragen. Und Pull-Requests sind willkommen.
Zumindest für Websites, die an einen weniger technisch versierten Kunden übergeben werden, denke ich, dass das Platzieren des Funktionalitäts-Plugins im Ordner `/mu-plugins/` der richtige Weg ist!
Für diejenigen, die es nicht wissen: `/mu-plugins/` sind das Beste! "mu" steht für "must use" (verwirrenderweise nicht "multi-user", obwohl es aus dem alten "WPMU"-Zweig stammt, bevor es Multisite gab). Dateien im `/mu-plugins/`-Ordner werden automatisch ausgeführt (soweit ich mich erinnere, vor anderen Plugins) und können nicht über die Plugin-Seite deaktiviert werden (obwohl Sie sie über einen kleinen Link oben auf der Plugin-Seite anzeigen können).
Für Inhaltstypen, Taxonomien und dergleichen, die einzigen Male, in denen Sie ein Funktionalitäts-Plugin deaktivieren möchten, sind wahrscheinlich Zeiten, in denen Sie es sowieso bearbeiten möchten.
Danke, dass Sie darauf hingewiesen haben, @Mark. Ich habe bereits modulares Design innerhalb von functions.php verwendet, aber die Erstellung von Funktionalitäts-Plugins ist sehr sinnvoll.
Ich stimme vollkommen zu! Ich versuche jetzt, Websites so zu erstellen, dass jedes Plugin (außer mu-plugins) sicher entfernt werden kann. So dass der Website-Inhalt oder das Theme keine Abhängigkeit von einem Plugin haben. Das ist schwer durchzusetzen, aber es lässt mich zweimal überlegen, bevor ich Plugins installiere, die mit Shortcodes und benutzerdefinierten Inhaltstypen integriert sind. Das Deinstallieren dieser Plugins kann entweder das Website-Design beeinträchtigen oder dazu führen, dass vom Benutzer eingegebene Daten einfach verschwinden. Zumindest ist es wichtig, sich dieser Plugin-Abhängigkeiten bewusst zu sein.
Es gibt also drei Orte, an denen Sie benutzerdefinierten Code platzieren können
`/mu-plugins/` – kann sich auf Website-Daten oder vitale Backend-Funktionalität auswirken
`/plugins/` – keine Auswirkung auf Website-Daten oder Website-Theme bei Deinstallation
`/functions.php` – wirkt sich nur auf das Website-Theme aus
@cornelius, mir gefällt diese "Kaskade" von Plugin-/Funktionsspeicherorten sehr gut. Ich werde anfangen, so darüber nachzudenken.
Benutzerdefinierte Inhaltstypen sind knifflig, da sie fast immer mit ihnen verbundene spezifische Vorlagencodes haben. Daher sind sie zwar websitespezifisch, aber auch themenspezifisch.
Das stimmt, @sean, aber ich denke trotzdem, dass es eine bessere Erfahrung bietet, aus zwei Gründen
1) Die Alternative besteht darin, dass ein Entwickler den relevanten Code extrahiert und in die `functions.php`-Datei eines neuen Themes portiert. Das ist fehleranfälliger und zeitaufwendiger. Dies so zu tun, wie in diesem Artikel vorgeschlagen, ist sauberer, spart Zeit und verlängert den ersten Entwicklungsschritt nicht.
2) Während Sie zu 100 % Recht haben, dass beim Wechseln der Themes ein Teil der Erfahrung verloren geht, stellt ein Funktionalitäts-Plugin zumindest sicher, dass die grundlegenden Beitraginformationen (Titel, Inhalt, Beitragsbild, Auszug usw.) vom neuen Theme übernommen werden. Zusätzlich gibt es den Website-Benutzern die Gewissheit, dass die Daten nicht verloren gegangen sind. Sie gehen so oder so nicht verloren, aber diese Art von Dingen ist wichtig, wenn man eine Website für jemand anderen erstellt.
Ich habe meine Funktionalität früher in Plugins modularisiert, aber jetzt habe ich einfach ein `lib`-Verzeichnis in meinem Theme, dann enthält meine `functions.php`-Datei eine Schleife, die durch die Dateien in diesem Verzeichnis iteriert und sie einbindet. Ich lagere nur dann in ein Plugin aus, wenn ich wirklich das Gefühl habe, diesen Code universell und wartbar für mehrere Anwendungen zu machen.
Mein vorheriger Kommentar liefert ein paar Gründe, warum es trotzdem vorteilhaft ist, es andersherum zu machen.
Lange Zeit habe ich alles in Funktionalitäts-Plugins gesteckt, aus einigen der von Ihnen genannten Gründe und mehr, aber am Ende entschied ich, dass es für die meisten Theme-Funktionalitäten ein unnötiger Schritt war. Ich fand das Gegenteil: Das Einbinden in Plugins war zeitaufwendiger und eine geringfügige Frustration. Ich finde es weniger zeitaufwendig, meine Code-Bibliotheken in separate Dateien unter `theme/lib` zu packen und dann die Dateien zu iterieren und einzubinden.
Ich mag es, wenn die Bereitstellung darin besteht, rsync zu verwenden, um ein einzelnes Verzeichnis und seine Unterverzeichnisse spärlich zu kopieren.
Meine Funktionalität im Theme zu belassen, spart mir Zeit, wenn ich diese Funktionalität in Templates verwende. Nehmen wir an, ich schreibe eine Funktion, die ich überall in meinem Theme verwenden werde. Wenn sie sich in einem Funktionalitäts-Plugin befindet, muss ich sie mit einer Funktion absichern, die prüft, ob meine Funktionalität definiert ist. Wenn dieses Funktionalitäts-Plugin deaktiviert ist, bricht das Theme zusammen. Jedes Mal, wenn ich die Funktion verwende, zu prüfen, ob sie definiert ist, ist nervig. Und um ehrlich zu sein, werde ich wahrscheinlich vergessen, alles in diese Prüfung einzuschließen.
Ein weiteres Beispiel. Manchmal kehre ich zu einem Theme zurück, an dem ich seit ein paar Jahren nicht mehr gearbeitet habe. Wenn sich die Funktionalitätsbibliotheken in einem Plugin befinden, muss ich woanders in der Verzeichnisstruktur danach suchen. Es klingt geringfügig, aber diese kleinen zusätzlichen Schritte summieren sich schnell.
Die Aktivierungs-/Deaktivierungsfunktion klang cool, aber ich muss zu den Plugins gehen und überprüfen, ob meine Plugins aktiviert sind. Dafür bin ich zu faul. Es klang auch nützlich für die Fehlersuche, aber ich kann alles, was ich brauche, durch das Tailen des PHP-Logs beheben.
Vielleicht bin ich nur eine Pessimistin, aber ich habe diese Art des Aufbaus ausprobiert und festgestellt, dass sie für meine Art der Entwicklung nur dann nützlich war, wenn ich ein Code-Fragment hatte, das ich zu einem echten "Plugin" machen und an anderer Stelle verwenden wollte. Jetzt erstelle ich einfach eine Datei im `lib`-Verzeichnis meines Themes und bin sicher, dass sie beim Aktivieren des Themes automatisch geladen wird. Halten Sie es einfach.
Jetzt ist alles, was ich in meiner `functions.php`-Datei habe, dies. Und alles ist super organisiert, bis hin zu Dateien wie `post_types.php`, wo ich die Inhaltstypen definiere, und `header.php`, wo ich Code einfüge, der den Header bereinigt.
Jetzt bin ich mit dem schwarzen Hut für heute fertig. ;)
Soweit ich mich erinnere, gibt es einen Unterschied in der Reihenfolge, in der mu-plugins und Plugins ausgeführt werden, und nicht alle Plugins sind für den mu-plugins-Ordner geeignet.
Das ist nur etwas zu berücksichtigen, wenn Sie planen, den mu-plugin-Ordner zu verwenden.
Sehr guter Punkt. Die relevante WP Codex-Seite hat einen Abschnitt mit Vorbehalten, der auf die Einschränkungen eingeht. Dennoch habe ich ihn für genau die Art von Dingen verwendet, die in diesem Beitrag aufgeführt sind, ohne Probleme.
Wenn jemand interessiert ist, habe ich ein WordPress-Plugin, das die Erstellung eines Funktionalitäts-Plugins automatisieren kann, sodass kein Dateisystemzugriff erforderlich ist. http://wordpress.org/plugins/functionality/
@Shea Bunge, ich werde Ihr Plugin überprüfen und es ausprobieren. Inspiriert von diesem Beitrag habe ich beschlossen, meine nächste Meetup-Präsentation über die `functions.php`-Datei, Funktionalitäts-Plugins und alternative Möglichkeiten zur Speicherung benutzerdefinierter Funktionen zu halten.
Danke, @govertz. Vielleicht interessiert Sie auch ein weiteres meiner Plugins, das es Ihnen ermöglicht, benutzerdefinierte Funktionen über das WordPress-Admin-Interface hinzuzufügen und zu verwalten, die dann auf der Website ausgeführt werden, als ob sie sich in einer Plugin- oder Theme-`functions.php`-Datei befänden. http://wordpress.org/plugins/code-snippets