Notizen zur Pluginschreiberei für WordPress


spot the wordpress
Attribution-NonCommercial-ShareAlike License by miss604

Wordpressplugins selbst schreiben ist kein Problem. Die Dokumentation ist recht ordentlich, manche Dinge sind jedoch ein wenig hakelig. Aber mit ein wenig Hartnäckigkeit erzielt man rasch Ergebnisse.

Einen englischsprachigen Einstieg findet man hier:

Diese Anleitung orientiert sich an dem Plugin schmie_twitter. Download kann man es hier. Die Eigentlichen Funktionen sind soweit es geht von WordPresscode getrennt.

Das Plugin aktualisiert den Status bei Shortmessaging Diensten (Twitter und Identica), wenn ein neuer Artikel erstellt wurde, oder ein älterer aktualisiert wurde.

Näher betrachtet wird folgendes:

  • Das Erstellen einer Settingspage.
  • Lesen und Schreiben von WordPress Einstellungen
  • Das Hook- oder Action System von WordPress
  • Übersetzungen von Plugins
  • Verteilen eines Plugins über das Plugin Directory

Ich möchte an dieser Stelle keine deutsche Übersetzung der WordPressdokumentation erstellen, sondern kurz und bündig beschreiben, was wie funktioniert.

Dieses Plugin sendet keine Ausgaben an den Benutzer, abgesehen von einer Seite mit Einstellungen.

in guter Einstieg ist das Betrachten der Verzeichnisshierarchie

schmiddi@dasgrauen:~/web/schmie_twitter$ ls -R

.:

classes  img  lang  readme.txt  schmie_twitter_options.php  schmie_twitter.php  screenshot-1.png  uninstall.php

./classes:

Cschmie_twitter.php  CToIdentica.php  CTo_Twitter.php  CUrlshortener.php

./img:

logo.png

./lang:

schmie_twitter-de_DE.mo  schmie_twitter.de_DE.mo  schmie_twitter.po

Die beiden letzten Ordner sind relativ unwichtig. In img. liegt eine Bilddatei mit dem Logo und in lang sind die zur Internationalisierung nötigen Dateien abgelegt. Dazu später mehr.

In classes liegen 4 Klassen, die die Grundfuntionen bereitstellen.

schmie_twitter.php ist der Einstieg in das Plugin.

Um ein Plugin zu schreiben wird nur eine PHP Datei benötigt, die den Namen des Plugins trägt. Die Datei kann auch in einen Unterordner nach diesem Schema abgelegt werden : schmie_twitter/schmie_twitter.php

Wichtig ist die Einzigartigkeit des Namens. Leider bietet WordPress keine Namespacefunktionen oder sonstige Garantien der Einzigartigkeit. Ich wähle zur Namensvergebung einen Präfix und anschließend einen prägnanten Namen. Die Plugindatei benötigt einen speziellen Header, der von WordPress geparsed wird:

Actions & Hooks

Zumindest der Plugin Name muß gesetzt sein, damit WordPress das Plugin akzeptiert.

Was nun folgt ist normaler PHP Code:

	//Codeauszug schmie_twitter.php

	function post_twit($post_ID) {
	/**
	....
	**/
	}//function
	add_action('publish_post','post_twit');

Bemerkenswert ist der add_action Mechanismus. (http://codex.wordpress.org/Function_Reference/add_action)

Um dies zu erklären, muß auf die Hook Mechanismen eingegangen werden. Bestimmten Ereignisse sind mit Hooks (Haken) oder actions (Aktionen) verbunden. Wenn diese Ereignisse ablaufen, wird abgeprüft, welche Funktionen noch ausgeführt werden sollen. Diese werden mit der add_action Funktion angemeldet. In unserem Fall wird bei dem Ereigniss ‚publish_post‘ also bei der Veröffentlichung eines Posts die Funktion post_twit angehängt und entsprechend ausgeführt.

Ein weiteres Beispiel:

/**** Save Settings **/
	$st= new CSchmie_twitter();
	add_action( 'admin_init', 'register_mysettings' );
	function register_mysettings() {
		global $st;
		$st->register_mysettings();
	}//function

Hier wird deutlich, dass das Actionsystem nur Funktional und nicht objekt-orientiert angesteuert werden kann. In der Funktion register_mysettings wird die Methode register_mysettings des CSchmie_twitter Objekts aufgerufen. Das Schlüsselword global wird benötigt um die Variable innerhalb der Funktion bekannt zu machen, da PHP merwürdige Gültigkeitsbereiche im Vergleich zu anderen Sprachen hat.

Ein letztes Beispiel wäre das Erzeugen einer Settingspage:

/** @see schmie_twitter_options.php ***/
add_action('admin_menu', 'schmie_twitter_create_menu');
function schmie_twitter_create_menu() {
	add_options_page('schmie_Twitter Settings', 'schmie_twitter Settings', 'administrator', __FILE__, 		'schmie_twitter_settings_page', __FILE__);

}//function

function schmie_twitter_settings_page() {
	if ( file_exists ( dirname(__FILE__).'/schmie_twitter_options.php' )) {
		include( dirname(__FILE__).'/schmie_twitter_options.php' );
	} else {
		e( '

Couldn't locate the settings page.

', 'wp-to-twitter' );
	}//fi
}//function
Auch hier werden wieder Grenzen des Systems aufgezeigt. Zuerst wird die Action create_menu() bei der Generierung des Administratormenüs aufgerufen und erzeugt die Links zu der Einstellungsseite und anschließend wird die Einstellungsseite generiert. Der include Mechanismus ist analog zum Präprozessorbefehl in C.
Durch die Modularisierung mit Hooks kann dies nicht in einem Schritt geschehen. Möglich wäre nur eine Zusammenfassung innerhalb einer neuen Funktion . (@@@wirklch? Meta Hooks?)

Optionspages

Der nächste Punkt ist das Erstellen einer Einstellungsseite (Optionspage).
Zum größten Teil werden hier nur Abgleichungen mit der Datenbank erledigt.
Wichtig hierbei sind die Funktionen register_settings(‚optiongroup‘,’option‘), und get_option(‚option‘).
WordPress speichert sämtliche Einstellungen in einer Datenbanktabelle namens Options. Die Funktion register_settings prüft das Vorhandensein der Einstellung und legt sie gegebenfalls an. Bei Optiongroup handelt es sich um eine Art Namespace, um die Einzigartigkeit zu gewährleisten.
Die Verarbeitung der Einstellungen geschieht über ein HTML Formular. Zuerst wird die Optiongroup bekannt gemacht:
<?php settings_fields( ’schmie_settings_group‘ ); ?>
Der Lese / Schreibzugriff wird über die Funktion get_option(‚option‘) abgewickelt. Die Funktion ist robust, doch leider mit sehr viel HTML verbunden:
BESCHREIBUNG
<input name="OPTION NAME" type="text" value=";" />

Zum einen ergbit dies eine sehr unelegante Vermischung aus PHP un HTML, zum anderen ist es mit einigem Schreibaufwand verbunden. Generatorfunktionen sind meines Wissens nicht vorhanden. Sehr nützlich für mich waren ein paar einfache PHP Funktionen, die die Einstellungen mit einem HTML Rumpf ausgeben:

function schmie_generate_textfield($description,$option,$password=false) {
	$option_val=get_option($option);
	$type='text';
	if ($password)
		$type='password';

echo "	
        $description
        
        ";
}//function

//looks nice :)
schmie_generate_textfield(__("Twitter Password", 'schmie_twitter'), 'schmie_tw_pass',true);

Bei der Namenswahl sollte man immer recht vorsichtig sein, damit keine WordPressfunktionen überschrieben werdem. Auch hier hat sich wie bei Settings das Präfixsystem für mich bewährt.

Übersetzung

Das Thema Internationalisierung sollte direkt zu Anfang der Entwicklung betrachtet werden. Dies erspart viel Änderungen am Code. Verwendet wird die innerhalb der Sprache PHP implementierte Gettext Bibliothek. Das Softwarepaket gettext ist für Übersetzungen erforderlich.

Links:
http://www.gnu.org/software/gettext/manual/gettext.html
http://www.php.net/manual/de/intro.gettext.php
http://codex.wordpress.org/I18n_for_WordPress_Developers

Sehr empfehlenswert ist dieser Beitrag aus der Blogosphäre, der deutlich tiefer auf die Thematik eingeht. Leider habe ich den Artikel zu spät entdeckt:(:

http://www.tuxlog.de/wordpress/2007/wordpress-plugins-ubersetzen-mit-gettext-po-und-pot-dateien/

Zuerst muß im Code gekennzeichnet werden, was übersetzt werden soll. Dabei wird die Zeichenkette mit einem Funktionsaufruf umschlossen und ein Namespace für die Übersetzung angegeben:

$foo=__('Dies könnte Ihre Übersetzung sein', 'NAMESPACE') .

Eine direkte Ausgabe erfolgt mit :

_e('Hallo Welt', 'NAMESPACE');

Platzhalter sind auch möglich:

_e("$ctr Flaschen Bier an der Wand",'NAMESPACE');

oder mit

printf(__("%d Flaschen Bier an der Wand",'NAMESPACE'), $ctr);

Das Einsetzten des Namespaces kann auch durch diverse Skripte (z.B.: innerhalb der Admin Funktionen im WordPress Plugindirectory). Dann genügt auch ein $bar = __(‚Hallo W‘);

Nun wird mit xgettext mit den o.g. Admin Funktionen eine POT Datei (Portable Object Template) erzeugt.

xgettext -L PHP -k –keyword=_e –keyword=__ –from-code=utf8 –default-domain=schmie_twitter –output=schmie_twitter.pot *.php

Dabei handelt es sich um eine Liste der zu übersetzenden Strings. Nun erstellt man eine Kopie der POT Datei und pflegt die entsprechenden Übersetzungen dort ein:

cp schmie_twitter.pot schmie_twitter-de_DE.po

Dies kann per Texteditor oder speziellen Tools wie KBabel oder Poedit erfolgen.

Wenn dies erledigt ist, wird eine binäre Datei mit der Namenskonvention pluginname-<lang_string>.mo mit msgfmt erzeugt:
msgfmt -o schmie_twitter.mo de_DE.po
Den Namnesstring erfährt man in der wp-config.php. Die Datei ist im Hauptverzeichniss der WordPress installation zu finden. Der String für deutschsprachige Unterstützung sieht so aus: define (‚WPLANG‘, ‚de_DE‘);

Nun muß die Übersetzung innerhalb des PHP Codes geladen werden. Dies geschieht mit folgenden Zeilen:

$path= basename(dirname(__FILE__));
	$domain='schmie_twitter';
	load_plugin_textdomain('schmie_twitter', false, $path . '/lang');
Ich habe mich dazu entschlossen alle Übersetzungen in den Unterordner lang zu legen.

Deinstallation:

Ein Skript kann händisch entfernt werden, indem einfach alle PHP Dateien entfernt werden. Datenbankeinträge bleiben dabei jedoch vorhanden. Deswegen solle immer der Deinstallationsmechanismus von WordPress verwendet werden.
Um eine Uninstallroutine zu schreiben, gibt es 2 Möglichkeiten:
-per hook
-Uninstall.php
Bei der Methode mit Hook wird wie bei den oben beschrieben Actions vorgegangen:
register_uninstall_hook(__FILE__, 'my_uninstall_hook');
	function my_uninstall_hook() {
		delete_option('option_1');
	}//
Allerdings wurde dieser Hook erst mit der Version 2.7 von WordPress implementiert. Man kann zwar mit function_exists(callback) eine Fehlermeldung abfangen, allerdings passiert bleiben die Einstellungen in der Datenbank.
Deshalb sollte man dem Weg mit der Uninstall.php den Vorzug geben. Dabei wird im Hauptverzeichnis des Plugins die genannte Datei erzeugt. Bevor man an das entfernen der Einstellungen geht, sollte man Prüfen, ob die WP_UNINSTALL Konstante gesetzt ist:

	if(!defined('WP_UNINSTALL_PLUGIN') )
	    exit();
	delete_option( 'schmie_tw_user' );

das WordPress Plugin Directory

Da man Plugins aus dem Directory recht bequem direkt in WordPress installieren kann, empfiehlt es sich seine Werke dort zu veröffentlichen. Nach der Registrierung (Passwort aufschreiben) füllt man einen Antrag auf Aufnahme des Plugins an. Ein WordPress Mensch schaut sich das Plugin an und nach einer gewissen Zeit (Spanne: Stunden bis Tage) wird das Plugin freigeschaltet. Zuerst schaut man sich die Pluginseite an, vor allem den Adminbereich. Was jetzt noch fehlt ist die Beschreibung im Directory. Dies geschieht über ein Textfile. Ausreichende Infos gibts hier.
Es gibt auch eine sehr brauchbare Seite mit Informationen zum Repo http://wordpress.org/extend/plugins/about/svn/.

Hier die Schnellversion (auch für den Laien):
Die Adresse des Repo’s findet Ihr auf Eurer Pluginseite.
Zuerst wird in ein leeres Verzeichniss ausgecheckt (Check Out):

	svn co http://plugins.svn.wordpress.org/schmie-twitter/

Hier gibts 3 Ordner branches tags trunk. Die aktuelle Version des Plugins liegt immer im trunk.
Also das Plugin dorthin kopieren. Nun fügen wir die Dateien dem Repository hinzu:

svn add trunk/*

Sehr nett ist es ältere Versionen im Tagsverzeichnis zu sichern. Dann stehen auch diese Versionen zum Download zur Verfügung. Falls man mal in älteren Code sehen will und nicht so bewandert mit SVN ist, hat man hier alles schnell zur Hand also:

svn cp trunk tags/1.0

Eingecheckt wird so (Check In):

svn ci -m "hey du willst es hier ist es"

Anmeldung am Repository mit den Directory Benutzerdaten.
Jetzt noch ein paar Worte für diejenigen, die noch nie mit Versionierungssoftware gearbeitet haben. Löschen im Dateimanager ist recht sinnlos, wenn man mit SVN oder ähnlichem arbeitet, da die Datei(en) zwar von der Platte getilgt sind, aber nicht aus dem Repo. Das gilt auch für Verschieben oder Umbenennen von Dateien. Auf solche Details ist immer zu achten. Eine gute Dokumentation für Subversion findet sich in Version Control with Subversion.

Das wärs von mir zu diesem Zeitpunkt. Viel Freude beim skripten / programmieren. Für Tipps oder Verbesserungen bin ich wie immer sehr dankbar. Wenn ich mal wieder ein Widget schreibe oder eines besseren belehrt werde, wird der Artikel angepasst.

Advertisements
Dieser Beitrag wurde unter php, programmieren, wordpress abgelegt und mit , , , , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Eine Antwort zu Notizen zur Pluginschreiberei für WordPress

  1. Pingback: KW12: iPads gewinnen, Pac-Man Planet, Limit bei CSS-Dateigröße und mehr - Der Softwareentwickler Blog

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s