toscho.design

WordPress-Plugin: Magische Widgets

For discussions in English about bugs and feature requests use the GitHub issue tracker.

Neulich stand ich vor einem spannenden Problem: Ein Freund wollte eine Zeile JavaScript und einen Link auf ein Stylesheet in den Header seines Themes bringen. Dieses Theme stammt aus dem Verzeichnis auf wordpress.org, und es sollte weiterhin automatisch aktualisiert werden. Ich konnte also nicht direkt hineinschreiben.
Nun hätte ich ein Child-Theme anlegen können, aber das fand ich dann etwas zu umständlich. Obendrein wäre das eine Speziallösung gewesen, und ich bin nun einmal Generalist.
Ich wollte eine Lösung, die ich wiederverwenden kann. Und ihr vielleicht auch.

Zeit für einen kleinen Zaubertrick.

Das Konzept

Im Kopfteil eines jeden Themes, das auf wordpress.org zugelassen wird, finden wir die Funktion wp_head. Diese löst eine gleichnamige Aktion aus. Wenn wir uns in diese Aktion einklinken, können wir tun, was immer uns beliebt. Zum Beispiel Text ausgeben.

Als Plugin wäre das ein Vierzeiler:

<?php
/* Plugin Name: Simple Head Insert */
add_action( 'wp_head', 'simple_head_insert' );
function simple_head_insert() { echo '<!-- Buh! -->'; }

Ganz nett, aber irgendwie … nicht gut genug. Es ist immer noch zu speziell, weil die Ausgabe fest im PHP-Code steht. Wenn die Ausgabe oder die Position geändert werden soll, muß das Plugin umgeschrieben werden. Das ist sehr fehleranfällig.

Jemand anderes möchte vielleicht Code im Backend einfügen. Der muß sich das Plugin im Grunde selbst neu schreiben.

Also habe ich mir gedacht: Dann hänge ich doch einfach an die Aktion widgets_init eine Funktion, die eine Instanz einer Klasse erzeugt, die für die Aktionen wp_head, wp_footer, admin_head und admin_footer eine weitere Funktion registriert, die wiederum den Inhalt einer ebenfalls registrierten Sidebar ausgibt, die man frei mit einem Widget befüllen kann, das ich in eine weiteren Klasse gepackt habe.

Klarsoweit?

Nicht? Dann kannst du dir den Code auf GitHub ansehen und herunterladen. Für die Eingabe des HTML-Codes habe ich eine einfachere Variante des nativen Text-Widgets geschrieben; sie heißt Unfiltered Text Widget.

150 Zeilen mehr als die erste Version, dafür um so mächtiger. Frank wird mich sicher noch ermahnen, daß ich doch eine Sprachdatei einarbeiten sollte. Keine Lust. Insgesamt finde ich den Code immer noch angenehm einfach und enorm flexibel zugleich. Ich bin ausnahmsweise und sicher nur für kurze Zeit mal zufrieden damit.

Einsatz

Jetzt wollen wir uns noch ansehen, wie man das verdammte Ding benutzt.

Zunächst laden wir es herunter, packen es ins Pluginverzeichnis und aktivieren es. Ja, sehr spannend.

Jetzt gehen wir auf »Design/Widgets«, und da haben wir vier neue Sidebars und ein neues Widget namens »Unfiltered Text«.

Wir klappen zur Probe mal die Box für den »Front End Header« auf und ziehen das neue Widget hinein. Das können wir übrigens überall benutzen, auch in anderen Sidebars.

In das Eingabefeld schreiben wir ein Script:

<script>alert('Buh!');</script>

Und dann rufen wir das Frontend unserer Website auf:

Faaaantastisch! Jetzt kann uns nichts mehr bremsen.

  • In den Footer des Frontends können wir den Tracking-Code des Analyse-Tools unserer Wahl eingeben – und schon geht das Gezähle los.
  • In den Header des Backends können wir schreiben:
    <style>#footer{display:none}</style>

    Und – zack! – ist der Footer weg.

  • Wir können den JavaScript-Code des Plugins Icon to Link einbauen.
  • Wer so richtig Spaß haben will, schreibt sich dies in beide Header:
    <style>body{display:none}</style>

Für weitere kreative Ideen und die obligatorischen … Verbesserungsvorschläge stehen euch die Kommentare offen.

Anpassen

Für Hacker habe ich zwei Filter eingebaut, die eine Kombination des Plugins mit dem eigenen Theme erlauben:

  1. 'magic_widgets_actions' übergibt einen Array mit den Aktionen. Den können wir per Filter in der functions.php frei ändern:
    add_filter( 'magic_widgets_actions', 'change_magic_widget_actions', 10, 1 );
    function change_magic_widget_actions( $arr ) 
    {
        // Add
        $arr['loop_start'] = 'Post List Start';
        // Remove
        unset( $arr['admin_footer'] );
        // Rename
        $arr['admin_head'] = 'HTML-Kopf Administration';
        return $arr;
    }

    Mehr Aktionen findet ihr im Codex, bei Adam R Brown und auf der-design.com.

    Ich habe mich auf die vier oben genannten Aktionen beschränkt, um die Widgetliste im Backend übersichtlich zu halten. Im Prinzip können wir aber auch 40 oder 400 Aktionen ansprechen.

  2. Den Namen Unfiltered Text können wir über den Filter 'magic_widgets_name' ändern (I18n für Arme!).

Fehlt was? Funktioniert alles?

Weitere Artikel dazu hier im Blog

17 Kommentare

  1. Wolfgang Wagner am 05.01.2011 · 15:40

    Wow, das ist ein ziemlich cooles Plugin. Das kann ich früher oder später sicher mal brauchen. Danke! :)

  2. Frank am 05.01.2011 · 21:27

    Ich finde es super, dass wir uns so ergänzen ;)
    Ich würde lediglich einen Hinweis geben, keine Ermahnung, die ich dafür ab und an vor dir bekomme und brauche. Schön umgesetzt, bis auf die Mehrsprachigkeit.

  3. Dieter am 05.01.2011 · 22:13

    Ich verstehe fast nur Bahnhof und deshalb auch eine vielleicht blöde Frage:

    Mit WordPress 3.0 wurde der Weg wie das Kommentarformular angesprochen werden soll verändert. Bei vielen Plugins für das Kommentarfeld habe ich jetzt das Problem, nicht mehr einfach den manuell einzufügenden Code einbauen zu können. Wäre das nicht mit Hilfe einer entsprechenden Erweiterung Deines Plugins für das Kommentarformular bzw. bestimmter Hooks (?) dort wieder herstellbar?

    Genial finde ich, dass sich mit Deiner Lösung keine Probleme bei einer automatischen Themeaktualisierung ergeben würde.

  4. H.-Peter Pfeufer am 05.01.2011 · 23:23

    Ich habe da eine ganz andere Frage. Wieso das Plugin nicht über das Verzeichnis auf wordpress.org veröffentlichen? Das würde bei eventuellen Updates um einiges vorteilhafter sein :-)

    Aber ansonsten, geniale Idee.

  5. Thomas Scholz am 06.01.2011 · 01:06

    @Dieter: Ja, du kannst mit diesem Plugin HTML-Code (kein PHP) an die Aktionen des Kommentarformulares binden. Du findest alle neun Aktionen in der Funktion comment_form() in der Datei wp-includes/comment-template.php. Da kannst du dich richtig austoben.

    Ich habe dem Repository mal ein Plugin beigefügt, das die Magic Widgets um diese neun Sidebars ergänzt. Es demonstriert auch ganz gut, wie flexibel dieser Ansatz ist, glaube ich. Viel Spaß!

  6. Thomas Scholz am 06.01.2011 · 01:19

    @H.-Peter Pfeufer: Ich habe seit einiger Zeit ein Plugin im Repository auf wordpress.org: Remove Redundant Links, das ist der dramatisch verbesserte Nachfolger des Codes zum Entfernen der Deppenlinks (den Namen bedauere ich inzwischen). Dazu wollte ich auch noch mal bloggen …

    Dies ist ein Experiment, das ich erst eine Weile ausprobieren möchte. Bis jetzt kann ich schon sagen:

    • SVN nervt gewaltig. Ich bin ein Git-Mensch, und wenn ich von Git aus SVN bedienen will, muß ich auf einige Git-Features verzichten oder mehr herumhacken, als ich möchte.

    • Die Aktualisierung dort funktioniert nur unzuverlässig. Manchmal wird die nächste Version des Plugins zum Download angeboten, aber die Readme der vorherigen Version angezeigt. Tagelang.

    • Und ich bin von den oft sehr eigenwilligen Entscheidungen der Leute dort abhängig. Die passen mir nicht immer, zumindest seltener als die GitHubs.

    Mittelfristig will ich mal einen eigenen Updateserver aufsetzen, damit die automatische Aktualisierung auch mit meinen Plugins funktioniert. Dazu fehlt mir gerade die Zeit, aber ich behalte es im Blick.

  7. Thomas Scholz am 17.01.2011 · 17:15

    Jetzt gibt es das Plugin auch auf wordpress.org.

  8. Carsten am 30.01.2011 · 10:51

    Danke für das Plugin, also den Tipp ^^ kann ich sehr gut gebrauchen. Ich nutze selber noch WP 2.9 wegen der Performance und kann ich gut gebrauchen bei mir!

  9. Thomas Scholz am 30.01.2011 · 11:03

    @Carsten: WP 2.9 ist langsamer und deutlich unsicherer als Version 3. Ich teste meine Plugins auch nicht mehr mit alten Versionen; beim nächsten Update des Plugins könnte es also schon Probleme geben.

  10. Martin BHH am 30.03.2011 · 14:11

    Ich bin gerade an meiner ersten WP-Site dran und habe schon mal mit child-theme angefangen, als ich auf dieses hier gestoßen bin. Installieren ist kein Problem und BUH macht es auch sehr schön. Jetzt habe ich die nachträglich in den header.php des child-themes eingefügten Verweis in das unfiltered text widged für den frontend header eingegeben:

    Aber das funktioniert nicht. Habe ich was vergessen? Oder funktioniert das Plugin nur beim Original-Theme. Wäre für Info dankbar.

  11. Martin BHH am 30.03.2011 · 14:18

    &lt;link rel="shortcut icon" href="&lt;?php bloginfo('stylesheet_directory'); ?&gt;/pix-bhh/favicon.ico" /&gt;

    So vielleicht?

  12. Thomas Scholz am 30.03.2011 · 14:22

    @Martin BHH: PHP wird im Widget nicht ausgeführt. Das wäre nur sehr umständlich und obendrein recht unsicher umzusetzen.

  13. Martin BHH am 30.03.2011 · 14:31

    Danke für Info. Vielleicht brauche ich's ja noch für etwas anderes.

  14. Marcus am 02.05.2011 · 12:04

    Hammer-Sache! Seit Wochen kämpfe ich mit den Widgets rum, dachte schon, es liegt am Theme. Aber nun eindlich ein Lichtblick. Hoffe, es klappt letztendlich alles.

  15. Pascal am 02.08.2011 · 20:20

    Cooles teil, funktioniert dieses Plugin auch Mühelos mit der aktuellsten WP Version?

  16. Thomas Scholz am 02.08.2011 · 20:29

    Ja, tut es.

  17. Tobias am 07.11.2011 · 12:34

    Prima, danke für den Tip, kann ich direkt mal bei mir austesten.