Der folgende Beitrag ist ein Gastbeitrag von Jason Witt. Ich weiß schon seit geraumer Zeit, dass ich viele der Dinge aus meiner `functions.php` in meinem WordPress-Theme in ein Funktions-Plugin auslagern sollte. Aber Sie wissen ja, Stunden am Tag und so weiter. Ich habe Jason kürzlich mit diesem Projekt beauftragt und er hat großartige Arbeit geleistet. Wenn Sie keine Ahnung haben, wovon ich spreche, lesen Sie weiter.
Das Hinzufügen neuer Funktionen zu einer WordPress-Website kann so einfach sein, wie im WordPress Plugin Repository nach einem Plugin zu suchen und dieses zu installieren. Aber es gibt einige benutzerdefinierte Funktionen, die Sie möglicherweise benötigen und für die es entweder zu grundlegend oder zu benutzerdefiniert ist, um dafür ein Plugin zu finden. Hier kommt die Datei `functions.php` ins Spiel. Sie ist im Wesentlichen eine Sammelstelle für Funktionen eines Themes.
Aber einige des Codes, den wir dort tendenziell ablegen, wäre woanders besser aufgehoben.
Die Datei `functions.php` ist ein einfacher Ort, um Dinge wie Theme-Support-Optionen, benutzerdefinierte Inhaltstypen (Custom Post Types), das Einbinden von JavaScript und (wirklich) alles andere, was Ihnen einfällt, hinzuzufügen. Seit Jahren ist dies der De-facto-Weg, um benutzerdefinierte Funktionen zu Ihrem WordPress-Theme hinzuzufügen. In den letzten Jahren gab es eine Bewegung, die Funktionen, die normalerweise in die Datei `functions.php` gehören, in ein „Funktions-Plugin“ auszulagern.
Was ist ein Funktions-Plugin?
Ein Funktions-Plugin ist ein Plugin wie jedes andere Plugin, das Sie im WordPress Plugin Repository finden. Der Hauptunterschied besteht darin, dass es nicht öffentlich vertrieben würde, da es spezifisch für Ihre Website ist. Es ist ein benutzerdefiniertes Plugin, das all Ihre benutzerdefinierten Funktionen der Website umfasst.

Was ist so toll an einem Funktions-Plugin?
Warum sollten Sie Zeit mit der Erstellung eines Plugins verbringen, wenn das Ablegen Ihrer Funktionen in Ihrer `functions.php`-Datei so einfach ist? Der große Vorteil ist, dass Sie Ihre Funktionen von Theme zu Theme wiederverwenden können. Beim Aktualisieren/Ändern Ihres Themes bleiben einige Codes in der `functions.php` gleich und einige ändern sich. Die Idee hinter einem Funktions-Plugin ist, die Funktionen, die sich nicht von Theme zu Theme ändern, zu nehmen und in ein Plugin zu verschieben. Auf diese Weise müssen Sie nicht mehr Ihre `functions.php`-Datei nach dem durchsuchen, was Sie behalten möchten, sondern können sich direkt in das Design Ihres neuen Themes stürzen.
Was gehört in das Plugin?
Das ist die Millionen-Dollar-Frage. Was gehört tatsächlich in ein Funktions-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 (Custom Post Type) spezifisch für eine Website, und das Hinzufügen der Unterstützung für Vorschaubilder (Thumbnails) ist spezifisch für ein Theme.
Lassen Sie uns das einen Moment lang pausieren, damit es super klar wird.
Stellen Sie sich vor, Ihre Website hat einen Bereich für Meetups. Sie haben dafür einen benutzerdefinierten Inhaltstyp erstellt, damit sie eine spezielle Art von Inhalt sein können. Auf der Frontend-Seite der Website stellen Sie sie auf eine besondere Weise dar. Im 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), ist es wahrscheinlich, dass Sie möchten, dass Ihre Meetups verschwinden? Wahrscheinlich nicht. Das sind Website-Inhalte, die Sie wahrscheinlich über jedes einzelne Theme hinaus erhalten 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, dann zu Theme B gewechselt wären – Sie könnten einen leichten Herzinfarkt erleiden, wenn Sie feststellen, dass alle Ihre Meetup-Informationen verschwunden sind. Die `functions.php`-Datei von Theme A ist nicht mehr aktiv, daher läuft all dieser Code, der den benutzerdefinierten Inhaltstyp deklariert, nicht mehr. Die Menüs werden nicht zum Admin 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 erneut ausgeführt wird.
Warum sich das alles antun? Verschieben Sie diesen Code einfach in ein Funktions-Plugin und er bleibt auch beim Wechseln von Themes aktiv.
Stellen Sie sich nun etwas ganz anderes vor: Code in Ihrer `functions.php`-Datei, der eine JavaScript-Bibliothek einbindet (enqueues). Wahrscheinlich verwenden Sie diese Bibliothek, um Dinge auf der Frontend-Seite Ihrer Website zu tun. Das ist ziemlich spezifisch für das Theme. Ein anderes Theme könnte völlig andere Bibliotheken verwenden oder gar keine. Diese Art von Dingen macht Sinn, in der `functions.php`-Datei zu sein, da es 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
- Registrierung von Sidebars und Navigationsmenüs
- Hinzufügen einer externen CSS-Datei, zum Beispiel einer benutzerdefinierten Schriftart
Beispiele für Dinge, die in einem Funktions-Plugin sinnvoll sind
- Benutzerdefinierte Inhaltstypen
- Benutzerdefinierte Taxonomien
- Benutzerdefinierte Funktionen für andere Plugins
- Benutzerdefinierte Metadatenfelder
- Hauptsächlich 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 Plugins-Verzeichnis. Benennen Sie es, wie Sie möchten. Vermeiden Sie die Verwendung von Zahlen und Sonderzeichen; Bindestriche und Unterstriche sind in Ordnung. Ich verwende normalerweise 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 Header-Informationen der Plugin-Datei 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 Code buchstäblich einfach aus der `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, Ihre Funktionen in ähnliche Gruppen zu organisieren und jeder von ihnen eine eigene Datei zu geben. Fügen Sie dann diese Dateien mit PHP-Includes in die Hauptdatei des Plugins ein. Stellen Sie sicher, dass Sie Ihre Funktionen kommentieren, damit Sie wissen, was los ist, wenn Sie später darauf zurückkommen.
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 entwickeln. OOP ist eine großartige Möglichkeit, Ihren Code zu organisieren, der mit den sich ändernden Funktionsanforderungen mitwachsen kann.
Echtes Beispiel
Wenn Sie sich das CSS-Tricks Funktions-Plugin ansehen möchten, hier ist ein Repository auf GitHub, das Sie sich ansehen können.
Nach diesem Übergang ist das Einzige, was in der Datei `functions.php` übrig bleibt, das Einbinden von jQuery und ein Hook, der die Standardausgabe von HTML-Kommentaren überschreibt – beides sehr spezifisch für das aktuelle Theme.
Yep. Gute Sache.
Nur so am Rande, ich setze auf DRY (Don't Repeat Yourself) und abstrahiere so viel Funktionalität wie möglich in ein Framework / eine Bibliothek. Infolgedessen sind die maßgeschneiderten Plugins / Sub-Plugins eines bestimmten Projekts (lesen: die eingebundenen Teile) nur die „Todo“-Argumente, die notwendig sind, um einen bestimmten Zauber zu wirken. Jeglicher redundanter WP-Überschuss bleibt der Elternklasse überlassen.
https://github.com/WPezClasses
Nur zur Info – irgendwo in all diesen Repositories gibt es eine Anleitung zum Einstieg :). Und ja, ich arbeite daran, die Dokumentation auszubauen und die 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 Funktions-Plugins in den Ordner
/mu-plugins/der richtige Weg ist!Für diejenigen, die es nicht wissen:
/mu-plugins/sind die besten! „mu“ steht für „must use“ (verwirrenderweise nicht „multi-user“, obwohl es aus dem alten „WPMU“-Zweig stammt, bevor es Multisite gab). Dateien im Ordner/mu-plugins/werden automatisch ausgeführt (vor anderen Plugins, wenn ich mich richtig erinnere) und können nicht über die Plugin-Seite deaktiviert werden (obwohl Sie sie über einen kleinen Link am oberen Rand der Plugin-Seite anzeigen können).Bei Inhaltstypen, Taxonomien und ähnlichem sind die einzigen Zeiten, in denen Sie ein Funktions-Plugin deaktivieren möchten, wahrscheinlich Zeiten, in denen Sie es sowieso bearbeiten möchten.
Danke für den Hinweis @Mark. Ich verwendete bereits modulares Design innerhalb von functions.php, aber die Erstellung von Funktions-Plugins macht viel Sinn.
Ich stimme vollkommen zu! Ich versuche jetzt, Websites so zu bauen, dass jedes Plugin (außer mu-plugins) immer sicher entfernt werden kann. Damit die Website-Inhalte 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 geliefert werden. Das Deinstallieren dieser Plugins kann entweder ein Website-Design zerstören oder dazu führen, dass vom Benutzer eingegebene Daten einfach verschwinden. Zumindest ist es ziemlich wichtig, sich dieser Plugin-Abhängigkeiten bewusst zu sein.
Es gibt also drei Orte, an denen man benutzerdefinierten Code platzieren kann
/mu-plugins/– kann Website-Daten oder wichtige Backend-Funktionen beeinflussen/plugins/– keine Auswirkungen auf Website-Daten oder Website-Theme, wenn deinstalliert/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 spezifischen Vorlagencode dafür haben. Sie sind also zwar websitespezifisch, aber auch themenspezifisch.
Das stimmt, @sean, aber ich glaube immer noch, dass es eine bessere Erfahrung bietet, aus zwei Gründen
1) Die Alternative ist, einen Entwickler zu veranlassen, den relevanten Code zu extrahieren und in die `functions.php`-Datei eines neuen Themes zu portieren. Das ist fehleranfälliger und zeitaufwändiger. Dies so zu tun, wie in diesem Artikel vorgeschlagen, ist sauberer, spart Zeit im Nachhinein und fügt dem ersten Entwicklungsschritt keine Zeit hinzu.
2) Während Sie zu 100 % Recht haben, dass der Wechsel des Themes einige der Erfahrungen verlieren würde, stellt ein Funktions-Plugin zumindest sicher, dass die grundlegenden Beitragsinformationen (Titel, Text, Vorschaubild, Auszug usw.) vom neuen Theme übernommen werden. Darüber hinaus gibt es den Website-Benutzern die Gewissheit, dass die Daten nicht verloren gegangen sind. Sie gehen auf keine Weise verloren, aber so etwas ist wichtig, wenn man eine Website für jemand anderen baut.
Ich habe früher meine Funktionalität in Plugins modularisiert, aber jetzt habe ich nur noch ein `lib`-Verzeichnis in meinem Theme, dann enthält meine `functions.php`-Datei eine Schleife, die die Dateien in diesem Verzeichnis durchläuft und sie einbindet. Ich extrahiere nur in ein Plugin, 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 immer noch vorteilhaft ist, es anders zu machen.
Eine Zeit lang habe ich alles in Funktions-Plugins gesteckt, aus einigen der von Ihnen genannten Gründe und mehr, aber ich habe schließlich beschlossen, dass es für die meisten Theme-Funktionen ein unnötiger Schritt war. Ich fand das Gegenteil, dass das Platzieren von Dingen in Plugins zeitaufwändiger und eine geringfügige Frustration war. Ich finde es weniger zeitaufwändig, meine Bibliothek-Code-Schnipsel in separaten Dateien unter
theme/libzu platzieren, anstatt die Dateien zu durchlaufen und sie einzubinden.Ich mag es, wenn die Bereitstellung aus einem Sparse-Copy eines einzelnen Verzeichnisses und seiner Unterverzeichnisse mittels rsync besteht.
Das Beibehalten meiner Funktionalität im Theme spart mir Zeit, wenn ich diese Funktionalität in Vorlagen verwende. Nehmen wir an, ich schreibe eine Funktion, die ich in meinem Theme verwenden werde. Wenn sie sich in einem Funktions-Plugin befindet, muss ich sie absichern, indem ich alles in eine Funktion einwickle, die prüft, ob meine Funktionalität definiert ist. Wenn dieses Funktions-Plugin deaktiviert ist, bricht das Theme zusammen. Jedes Mal, wenn ich die Funktion verwende, zu prüfen, ob sie definiert ist, ist ärgerlich. Und ehrlich gesagt, ich werde es wahrscheinlich sowieso vergessen, alles in diese Prüfung einzubinden.
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 Funktionsbibliotheken in einem Plugin befinden, muss ich an einer anderen Stelle in der Verzeichnisstruktur danach suchen. Das klingt geringfügig, aber diese kleinen zusätzlichen Schritte summieren sich schnell.
Die Aktivierungs-/Deaktivierungsfähigkeit klang cool, aber ich muss zu den Plugins gehen und überprüfen, ob meine Plugins aktiviert sind. Dazu bin ich zu faul. Es klang auch nützlich für die Fehlersuche, aber ich kann alles, was ich brauche, beheben, indem ich das PHP-Log anhefte.
Vielleicht bin ich nur eine Nörglerin, aber ich habe diese Art des Erstellens verwendet und festgestellt, dass sie für meine Art der Entwicklung nur dann nützlich war, wenn ich einen Code-Schnipsel hatte, den ich zu einem echten „Plugin“ machen und woanders verwenden wollte. Jetzt mache ich einfach eine Datei im lib-Verzeichnis meines Themes und bin sicher, dass sie beim Aktivieren des Themes automatisch geladen wird. Es einfach halten.
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 Inhaltstypen definiere, undheader.php, wo ich Code fallen lasse, 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.
Nur etwas, das man bei der Planung der Verwendung des mu-plugin-Ordners berücksichtigen sollte.
Sehr guter Punkt. Die relevante WP Codex-Seite hat einen Abschnitt über Einschränkungen, der sich mit den Beschränkungen befasst. Nichtsdestotrotz habe ich es für genau die Art von Dingen verwendet, die in diesem Beitrag ohne Probleme aufgeführt sind.
Wenn jemand interessiert ist, habe ich ein WordPress-Plugin, das die Erstellung eines Funktions-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 rund um die Datei functions.php, Funktions-Plugins und alternative Möglichkeiten zur Speicherung benutzerdefinierter Funktionen zu gestalten.
Danke @govertz. Möglicherweise sind Sie auch an einem weiteren meiner Plugins interessiert, 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 in einer Plugin- oder Theme-functions.php-Datei wären. http://wordpress.org/plugins/code-snippets