Programmierung von Extensionen für das MediaWiki
Transcrição
Programmierung von Extensionen für das MediaWiki
Programmierung von Extensionen für das MediaWiki Eine Hinführung zum Thema Karin Haenelt 13.3.2013 (14.9.2012) Inhalt Programmierung von Extensionen für das MediaWiki ........................................................ 1 1 Einführung ..................................................................................................................... 2 2 Einbindung von Extensionen in das MediaWiki ............................................................ 3 3 Arten von Extensionen .................................................................................................. 4 4 Beispiel 1: HelloWorld – Textausgabe auf einer Wikiseite ........................................... 4 4.1 Quelltext der Wikiseite “Test” ................................................................................. 5 4.2 Ansicht der Wikiseite “Test” .................................................................................... 5 4.3 Programm HelloWorld.php ...................................................................................... 5 4.3.1 Vollständiger Quellcode der Extension ................................................................ 5 4.3.2 Einleitungskommentar ......................................................................................... 6 4.3.3 Prüfung der Einbindung in MediaWiki ................................................................. 6 4.3.4 Registrierung der Extension für die Seite Spezial:Version im MediaWiki ........... 6 4.3.5 Registrierung der Extension im MediaWiki.......................................................... 7 4.3.6 Funktionaler Kern der Extension .......................................................................... 7 4.4 5 localSettings.php ...................................................................................................... 8 Beispiel 2: CategoryList – Datenbankabfrage und Ausgabe auf einer Wikiseite .......... 8 5.1 Quelltext der Wikiseite “Test” ................................................................................. 8 5.2 Ansicht der Wikiseite “Test” .................................................................................... 8 5.3 Programm CategoryList.php .................................................................................... 8 5.3.1 Vollständiger Quellcode der Extension ................................................................ 9 5.3.2 Einleitung und Registrierung .............................................................................. 12 5.3.3 Funktionaler Kern der Extension ........................................................................ 12 5.3.4 Vorbereitung der Tabellenausgabe.................................................................... 12 5.3.5 Datenbankabfrage.............................................................................................. 14 5.3.6 Verarbeitung der Ergebnisse der Datenbankabfrage ........................................ 16 Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 1 /26 5.3.7 Rückgabewert..................................................................................................... 16 5.4 6 7 LocalSettings.php ................................................................................................... 17 Beispiel 3: Eine Spezialseiten-Extension ..................................................................... 17 6.1 Die Installationsdatei: MyExtension.php ............................................................... 17 6.2 Die Spezialseite: SpecialMyExtension.php ............................................................. 18 6.3 Die Internationalisierungsdatei: MyExtension.i18n.php ....................................... 18 6.4 Die Aliasdatei: MyExtension.alias.php ................................................................... 19 Beispiel 4: Eine Spezialseiten-Extension mit Parametereingabe ................................ 19 7.1 Die Installationsdatei: MyExtensionP.php ............................................................. 20 7.2 Die Spezialseite: SpecialMyExtensionP.php ........................................................... 21 7.3 Die Internationalisierungsdatei: MyExtensionP.i18n.php ..................................... 22 7.4 Die Aliasdatei: MyExtensionP.alias.php ................................................................. 23 8 Zugriff auf die Wiki-Datenbank mit phpMyAdmin...................................................... 23 9 Zugriff auf die Texte der Wikiseiten über die Datenbank ........................................... 24 10 Dokumentationen zur Entwicklung von Extensionen ................................................. 25 10.1 Entwicklung von Extensionen ................................................................................ 25 10.2 MediaWiki-Dokumentationen ............................................................................... 25 10.3 Semantic MediaWiki-Dokumentationen................................................................ 25 11 Technischer Hinweis: Softwareversionen .................................................................. 25 12 Information und Kontakt............................................................................................. 25 13 Copyright ..................................................................................................................... 26 1 Einführung MediaWiki ist eine open source Software mit definierten Schnittstellen zur Einbindung von Extensionen. Inzwischen gibt es eine Vielzahl öffentlich verfügbarer Extensionen. Eine aktuelle Liste steht unter http://www.mediawiki.org/wiki/Category:Extensions . Eine Beschreibung der Schnittstellen und ein Handbuch zum Schreiben von Extensionen findet sich unter http://www.mediawiki.org/wiki/Manual:Developing_extensions. Zur Entwicklung sei auf das Handbuch verwiesen. Dieses Skript hier soll lediglich ein “kleines Beispiel zum Ausprobieren” vorstellen, mit dem man einen ersten Einblick in die Programmierung einer Extension gewinnen kann. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 2 /26 2 Einbindung von Extensionen in das MediaWiki Die Struktur für die Einbindung von Extensionen sieht folgendermaßen aus: $IP /extensions/ HelloWorld / HelloWorld.php localSettings.php - Die MediaWiki-Software installiert man in einem Verzeichnis nach Wahl. Wir nennen das Verzeichnis hier $IP (Installation Path). In diesem Verzeichnis liegen sämtliche Programme und Verzeichnisse, die zum Basissystem gehören. - Im Verzeichnis $IP gibt es ein Verzeichnis extensions. Sämtliche Extensionen legt man in diesem Verzeichnis ab. Dabei ist es gute Konvention, für eine Extension einen eigenen Ordner anzulegen. Für die Extension “HelloWorld” gibt es dann also ein Verzeichnis $IP/Extensions/HelloWorld. - In dem Verzeichnis der jeweiligen Extension liegen alle Dateien, die zu der betreffenden Extension gehören, beispielsweise $IP/Extensions/HelloWorld/HelloWorld.php - Im Verzeichnis $IP gibt es die Datei localSettings.php. In dieser Datei wird die Einbindung einer Extension mit einem include_once-Statement oder einem require_once-Statement eingetragen. include_once() und require_once() sind PHP-Funktionen. Diese Funktionen binden Dateien in einen Quellcode ein - im aktuellen Fall binden sie also die Dateien mit dem Quellcode der Extensionen in den Quellcode des MediaWiki-Kernsystems ein. Beide Funktionen überprüfen, ob die Datei bereits eingebunden ist und sorgen dafür, dass eine Einbindung nur einmal erfolgt (once). require()wirft im Fehlerfall einen E_COMPILE_ERROR aus und beendet damit Programmausführung. include() erzeugt hingegen nur eine Warnung (E_WARNING) und gestattet so die weitere Programmausführung. (http://www.php.net/manual/de/function.require.php) Mit dem statement include_once(“$IP/Extensions/HelloWorld/HelloWorld.php”); in der Datei localSettings.php wird die Extension also Bestandteil des Wikis. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 3 /26 3 Arten von Extensionen Das Handbuch http://www.mediawiki.org/wiki/Manual:Developing_extensions sieht folgende Arten von Extensionen vor: - Tag Extensions: erweitern die Wiki-Syntax um zusätzliche Tags, wie beispielsweise <myTag> und stellen zu diesen Tags spezielle Auswertungsfunktionen bereit. Ein Beispiel einer solchen Extension ist die Extension http://wikitools.com/wiki/Wiki_Category_Tag_Cloud . Diese Extension führt das Tag <tagcloud> ein. Die Verwendung des Tags auf einer Wikiseite führt dazu, dass die Liste der Kategorien im jeweiligen Wiki in Form einer Tag Cloud angezeigt wird. - Parser Functions: erweitern ebenfalls die Wikisyntax und fügen eine weitere Funktionalität hinzu. Allerdings werden sie im Unterschied zu Tag Extensions in den Wiki-Parser integriert. Ihre Ausgabe kann beispielsweise als Vorlagenparameter verwendet werden. Die Notation ist {{ #functionname: param1 | param2 | param3 }}. - Hooks: ermöglichen es, für definierte MediaWiki-Eerignisse eigene Funktionen bereitzustellen. Beispielsweise ruft die Angabe $wgHooks['ArticleSaveComplete'][] = 'MyExtensionHooks::articleSaveComplete'; die Funktion MyExtensionHooks::articleSaveComplete an Stelle der standardmäßig für ‘ArticleSaveComplete’ vorgesehenen Funktion auf. - Special Pages: Spezialseiten sind Wikiseiten, die durch Programme erzeugt werden und daher nicht wie normale Wikiseiten editierbar sind. Sie stehen im Namensraum “Spezial”. Mit Extensionen kann man auch Spezialseiten erzeugen - Skins: Skins erlauben die Anpassung des Erscheinungsbildes eines Wikis. - Magic Words: sind Schlüsselworte zum Aufruf einer Funktion Wir stellen in diesem Skript zwei Beispiele einer Tag Extension und zwei Beispiele einer Special Page-Extension vor. 4 Beispiel 1: HelloWorld – Textausgabe auf einer Wikiseite Wir zeigen ein kleines Beispiel, in dem wir das Tag <hW> einführen. Wenn wir dieses Tag auf eine Wikiseite schreiben, sollen auf dieser Seite an Stelle dieses Tags die Worte “hello World” erscheinen. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 4 /26 4.1 Quelltext der Wikiseite “Test” Auf eine Wikiseite mit dem Titel “Test” (der Titel ist beliebig wählbar) schreiben wir den folgenden Wikiquelltext <hW></hW> 4.2 Ansicht der Wikiseite “Test” Sobald unsere Extension fertig programmiert und funktionstüchtig in das Wiki eingebunden sein wird, wird unsere Wikiseite nach dem Speichern folgendermaßen aussehen: Abbildung 1 4.3 Anzeige der Wikiseite “Test” mit dem neuen Tag <hW> Programm HelloWorld.php Das Entwicklungshandbuch für Extensionen sieht vor, dass man zu jeder Extension (http://www.mediawiki.org/wiki/Manual:Developing_extensions) mindestes drei Dateien erstellt, nämlich - MyExtension/MyExtension.php (Setup-Code der Extension) - MyExtension/MyExtension.body.php (Ausführungscode der Extension) - MyExtension/MyExtension.i18.php (Übersetzungen der Systemausgaben) Für Extension für den allgemeinen Gebrauch ist diese Aufteilung sehr nützlich. In unserem einfachen Beispiel verwenden wir jedoch nur eine Datei. Wir zeigen an Hand des Quellcodes unseres Beispiels das Grundgerüst des Aufbaus einer Tag Extension. 4.3.1 Vollständiger Quellcode der Extension 1 2 3 4 5 6 7 8 <?php /** * Beispiel-Extension * @author Karin Haenelt * @version 1.0 * * This program is free software; you can redistribute it and/or Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 5 /26 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ if( !defined( 'MEDIAWIKI' ) ) die( "This is an extension to the MediaWiki package and cannot be run standalone." ); # credits $wgExtensionCredits['parserhook'][] = array ( 'name' => 'HelloWorld', 'url' => '', 'version' => '1.0', 'svn-revision' => '', 'author' => "Karin Haenelt", 'description' => "", ); $wgExtensionFunctions[] = 'registerHelloWorld'; # registering extension function registerHelloWorld() { global $wgParser; $wgParser->setHook('hW', 'myHelloWorld'); } # parser function function myHelloWorld() { $output = "hello World"; return $output; } 4.3.2 Einleitungskommentar Die Zeilen 3-17 enthalten den Einleitungskommentar für die Extension. Davon enthalten die Zeilen 8 bis 17 einen für open source Programme üblichen Hinweis auf die GNU General Public License. 4.3.3 Prüfung der Einbindung in MediaWiki Die Zeilen 19-20 enthalten eine Überprüfung der Einbindung in das MediaWiki. 4.3.4 Registrierung der Extension für die Seite Spezial:Version im MediaWiki MediaWiki listet auf der Seite Spezial:Version die jeweils eingebundenen Extensionen. Es ist gute Praxis, für die Eintragung einer Extension auf der Seite Spezial:Version zu sorgen. Die Information hierfür wird in dem Array $wgExtensionCredits gespeichert. Die Zeilen 22 bis Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 6 /26 29 zeigen die Spezifikation für die Extension HelloWorld. Die hier angegebene Information wird wie folgt auf der Seite Spezial:Version angezeigt: Abbildung 2 Anzeige der Einbindung der Extension auf der Wikiseite Spezial:Version 4.3.5 Registrierung der Extension im MediaWiki Die Registrierung der Funktion im MediaWiki erfolgt in den Zeilen 32 bis 38: 32 33 34 35 36 37 38 $wgExtensionFunctions[] = 'registerHelloWorld'; # registering extension function registerHelloWorld() { global $wgParser; $wgParser->setHook('hW', 'myHelloWorld'); } $wgExtensionFunction[] ist eine Liste von callback Funktionen, die aufgerufen werden, wenn MediaWiki vollständig initialisiert ist. Im aktuellen Fall soll die Funktion registerHelloWorld aufgerufen werden. Diese Funktion ist in den Folgezeilen spezifiziert. $wgParser->setHook('hW', 'myHelloWorld'); sorgt dafür, dass MediaWiki das <hW> Tags mit der Funktion myHelloWorld verbindet und beim Auftreten dieses Tags auf einer Wikiseite diese Funktion zur Interpretation des Tags aufruft. 4.3.6 Funktionaler Kern der Extension Der funktionale Kern der Extension, d.h. die Funktion, die beschreibt, welche Operation beim Auftreten des Tags <hW> ausgeführt werden soll, steht in den Zeilen 40 bis 45: 40 41 42 43 44 45 # parser function function myHelloWorld() { $output = "hello World"; return $output; } In unserem Beispiel findet nur eine ganz kleine Aktion statt: Die Variable $output erhält den Inhalt “hello World” und wird dann als Rückgabewert an das MediaWiki-Kernsystem Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 7 /26 zurückgegeben. Auch HTML-Anweisungen können im Rückgabewert enthalten sein (z.B. <b>hello World</b>). Das MediaWiki-Kernsystem sorgt dafür, dass der Rückgabewert auf der MediaWiki-Seite erscheint. 4.4 localSettings.php In die Datei localSettings.php schreiben wir nun noch die folgende Zeile: include_once(“$IP/Extensions/HelloWorld/HelloWorld.php”); 5 Beispiel 2: CategoryList – Datenbankabfrage und Ausgabe auf einer Wikiseite In unserem zweiten Beispiel zeigen wir einen Zugriff auf die Wikidatenbank über die Datenbanksschnittstelle und eine Aufbereitung der Ergebnisse für die Ausgabe auf der Wikiseite. Im Beispiel lassen wir uns die Liste der Kategorien zusammen mit ihrer Frequenz ausgeben. 5.1 Quelltext der Wikiseite “Test” Auf eine Wikiseite mit dem Titel “Test” (der Titel ist beliebig wählbar) schreiben wir den folgenden Wikiquelltext <catList>Liste der Kategorien</catList> Abbildung 3 5.2 Quelltext der Wikiseite “Test” Ansicht der Wikiseite “Test” Sobald unsere Extension fertig programmiert und funktionstüchtig in das Wiki eingebunden sein wird, wird unsere Wikiseite – abhängig davon, welche Kategorien wir in unserem Wiki vergeben haben - nach dem Speichern folgendermaßen aussehen: Abbildung 4 5.3 Anzeige der Wikiseite “Test” mit dem neuen Tag <catList> Programm CategoryList.php Wir erläutern nun den Quellcode dieses Beispiels Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 8 /26 5.3.1 Vollständiger Quellcode der Extension 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 <?php /** * BeispielExtension * @author Karin Haenelt * @version 1.0 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /** * Erlaeuterung * Diese Extension definiert das Parser-Tag "catList". * Dieses Tag kann auf einer Wiki-Seite verwendet werden. * <catList></catList> liefert eine Tabelle aller Kategorien und der * Anzahl ihres Vorkommens */ if( !defined( 'MEDIAWIKI' ) ) die( "This is an extension to the MediaWiki package and cannot be run standalone." ); # credits $wgExtensionCredits['parserhook'][] = array ( 'name' => 'CategoryList', 'url' => '', Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 9 /26 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 95 97 98 99 100 101 102 103 104 105 106 107 108 109 110 'version' => '1.0', 'svn-revision' => '', 'author' => "Karin Haenelt", 'description' => "", ); $wgExtensionFunctions[] = 'registerCategList'; #----------------------------------------------------# registering extension #----------------------------------------------------function registerCategList() { global $wgParser; $wgParser->setHook('catList', 'CategList'); return true; } #----------------------------------------------------# parser function #----------------------------------------------------function CategList($input) { # http://localhost/Testwiki/index.php global $wgServer; //z.B. http://localhost global $wgScript; //z.B. Testwiki/index.php $thisWikiLinkBegin = '<a href="' . $wgServer . $wgScript . "?title="; $htmlOut = "<b>" . $input . "</b>"; $htmlOut .= '<table class="wikitable sortable">'; $htmlOut= $htmlOut . "<tr><td>" . "Kategorie" . "</td><td>" . "Frequenz" . "</td>"; $categoryName = ''; $categoryOccCount = 0; Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 10 /26 # get database # MediaWiki-Datenbankschnittstelle # - Lesezugriff auf DB wfGetDB(DB_SLAVE), # Konvention: speichern in $dbr # - Schreibzugriff auf DB wfGetDB(DB_Master), # Konvention: speichern in $dbw # - select-Query mit Funktion select() # Format: $dbr->select('table_to_select from', # array('fieldname1', 'f..2'), # array( 'field_to_match' => 'value' ) ); # - entspricht in SQL: # SELECT cat_title, cat_pages FROM category WHERE cat_pages > 0 # ORDER By cat_title ASCENDING $dbr = &wfGetDB(DB_SLAVE); $res = $dbr->select('category', array('cat_title','cat_pages'), 'cat_pages > 0', '', array('ORDER BY' => 'cat_title ASC')); $numCategories = $dbr->numRows($res); for ($i = 0; $i < $numCategories; $i++) { $row = $dbr->fetchObject($res); $categoryName = $row->cat_title; $categoryOccCount = $row->cat_pages; $link = $thisWikiLinkBegin . "Kategorie:" . $categoryName . '">' . $categoryName . "</a>"; $htmlOut = $htmlOut . "\n<tr><td>" . $link . "</td><td>" . $categoryOccCount . "</td>"; } Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 11 /26 $dbr->freeResult( $res ); # final output $htmlOut = $htmlOut . "</table>"; return $htmlOut; } 5.3.2 Einleitung und Registrierung Die Zeilen 4 bis 49 enthalten die Einleitungskommentare und Registrierungen, wie wir sie schon im Beispiel “HelloWorld” gesehen haben. Wir verweisen hierzu auf die Erläuterungen zum Beispiel “HelloWorld”. 5.3.3 Funktionaler Kern der Extension Die Funktion CategList (Zeile 51-110) beschreibt, wie das Tag <categList> interpretiert werden soll. Wir beschreiben in den nächsten Abschnitten die folgenden Bestandteile dieser Funktion: 56 – 66: Vorbereitung der Tabellenausgabe 69 – 91: Datenbankabfrage 93- 103: Verarbeitung der Ergebnisse der Datenbankabfrage 105-110: Rückgabewert 5.3.4 Vorbereitung der Tabellenausgabe 56 57 58 59 60 61 62 63 64 65 66 # http://localhost/Testwiki/index.php global $wgServer; //z.B. http://localhost global $wgScript; //z.B. Testwiki/index.php $thisWikiLinkBegin = '<a href="' . $wgServer . $wgScript . "?title="; $htmlOut = "<b>" . $input . "</b>"; $htmlOut .= '<table class="wikitable sortable">'; Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 12 /26 $htmlOut= $htmlOut . "<tr><td>" . "Kategorie" . "</td><td>" . "Frequenz" . "</td>"; $categoryName = ''; $categoryOccCount = 0; Die Zeilen 56 bis 66 setzen die Startwerte für die Variablen, mit denen die Ausgabe aufgebaut wird. 57 $wgServer ist eine globale Variable des MediaWiki. Der Wert dieser Variablen ist die Basis-URL des Servers, also z.B. http://www.mediawiki.org. (Quelle: http://www.mediawiki.org/wiki/Manual:$wgServer ) $wgScriptPath ist eine globale Variable des MediaWiki. Der Wert dieser Variablen ist der Pfad von DOCUMENT ROOT bis zum Installationsverzeichnis des Wiki. Der Wert wird bei der Installation des Wikis automatisch in der Datei localSettings.php gesetzt. (Quelle: http://www.mediawiki.org/wiki/Manual:$wgScriptPath ) 58 $wgScript ist eine globale Variable des MediaWiki. Der Wert dieser Variablen ist “{$wgScriptPath}/index.php” (Quelle: http://www.mediawiki.org/wiki/Manual:$wgScript ) 59 $thisWikiLinkBegin ist eineVariable dieses Beispiels: der Wert ist der Beginn der HTML-Spezifikation eines Links auf eine Wikiseite: Sei - $wgServer = http://localhost und - $wgScript = Testwiki/index.php Dann ist der Wert von $thisWikiLinkBegin die Zeichenkette <a href=“http://localhost/Testwiki/index.php?title=“ 61 $htmlOut ist eine Variable dieses Beispiels, Wir benutzen sie um im Programm sukzessive den HTML-Code für die auszugebende Tabelle aufzubauen. In dieser Zeile erzeugen wir zunächst die Überschrift der Tabelle und verwenden dafür die Eingabe der Funktion ($input) – das ist die Zeichenkette, die auf der Wikiseite zwischen dem öffnenden und schließenden categListTag steht, das den Aufruf der Funktion veranlasst. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 13 /26 62 $htmlOut startet die Tabellendefinition. Die Tabellenklasse wikitable sortable ist eine in MediaWiki vordefinierte Tabellenklasse: eine Tabelle mit einem bestimmten Layout (Farbe etc.) und sortierbaren Spalten. 63 $htmlOut fügt die Definition der beiden Überschriftszellen der Tabelle des Beispiels hinzu. 5.3.5 Datenbankabfrage 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 # get database # MediaWiki-Datenbankschnittstelle # - Lesezugriff auf DB wfGetDB(DB_SLAVE), # Konvention: speichern in $dbr # - Schreibzugriff auf DB wfGetDB(DB_Master), # Konvention: speichern in $dbw # - select-Query mit Funktion select() # Format: $dbr->select('table_to_select from', # array('fieldname1', 'f..2'), # array( 'field_to_match' => 'value' ) ); # - entspricht in SQL: # SELECT cat_title, cat_pages FROM category WHERE cat_pages > 0 # ORDER By cat_title ASCENDING $dbr = &wfGetDB(DB_SLAVE); $res = $dbr->select('category', array('cat_title','cat_pages'), 'cat_pages > 0', '', array('ORDER BY' => 'cat_title ASC')); $numCategories = $dbr->numRows($res); Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 14 /26 Die Zeilen 69 bis 91 zeigen einen Zugriff auf die Wikidatenbank. Eine Beschreibung dieses Zugriffs findet sich unter http://www.mediawiki.org/wiki/Manual:Database_access . MediaWiki stellt für diesen Zugriff eine abstrakte Schnittstelle bereit. Der Zugriff erfolgt mit der wfGetDB()-Funktion, und zwar mit wfGetDB(DB_SLAVE)für den lesenden Zugriff und wfGetDB(DB_MASTER) für den schreibenden Zugriff. Die Funktion liefert ein Datenbankobjekt, das zum Zugriff auf die Datenbank verwendet werden kann. Es ist Konvention, ein Datenbankobjekt zum Lesen in der Variablen namens $dbr zu speichern und ein Datenbankobjekt zum Schreiben in der Variblen namens $dbw. Der übliche Kern eines Lesezugriffs (http://www.mediawiki.org/wiki/Manual:Database_access) sieht folgendermaßen aus: $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( /* ...SQL-Query im MW-Format... */ ); foreach( $res as $row ) { ... } Abbildung 5 Kern eines Lesezugriffs auf die Wiki-Datenbank Die select-Methode liefert eine Tabelle in Form eines Objekts zurück, die in der foreachSchleife zeilenweise verarbeitet wird. Für die Operationen auf der Datenbank stellt MediaWiki eine Schnittstelle zur Verfügung: die Abfrage erfolgt mit Methoden für das Datenbankobjekt. Eine dieser Methoden ist die Funktion select(). Sie bildet die MediaWiki-Schnittstelle für ein SELECT-statement. Die Komponenten des SELECTstatements werden als Parameter der select()-Funktion kodiert. Ein Beispiel ist (http://www.mediawiki.org/wiki/Manual:Database_access): $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( 'category', array( 'cat_title', 'cat_pages' ), // // // 'cat_pages > 0', // __METHOD__, // // array( 'ORDER BY' => 'cat_title ASC' ) // $table $vars (columns of the table) $conds $fname = 'Database::select', $options = array() ); Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 15 /26 Dieses Beispiel entspricht der SQL-Query SELECT cat_title, cat_pages FROM category WHERE cat_pages > 0 ORDER BY cat_title ASC Gesucht werden im Beispiel aus der Tabelle category die Spalten cat_Title (enthält den Titel der Kategorie) und cat_pages (enthält die Anzahl der Seiten, auf denen die Kategorie vorkommt). Die select()-Funktion liefert ein Objekt vom Typ ResultWrapper (http://svn.wikimedia.org/doc/classResultWrapper.html ). Die Methode numRows() liefert die Anzahl der Zeilen eines Result-Objekts. 5.3.6 Verarbeitung der Ergebnisse der Datenbankabfrage 93 94 95 95 97 98 99 100 101 102 103 for ($i = 0; $i < $numCategories; $i++) { $row = $dbr->fetchObject($res); $categoryName = $row->cat_title; $categoryOccCount = $row->cat_pages; $link = $thisWikiLinkBegin . "Kategorie:" . $categoryName . '">' . $categoryName . "</a>"; $htmlOut = $htmlOut . "\n<tr><td>" . $link . "</td><td>" . $categoryOccCount . "</td>"; } $dbr->freeResult( $res ); Die for-Schleife bearbeitet die zurückgelieferte Tabelle zeilenweise. Die Methode fetchObject() gehört ebenfalls zur Klasse ResultWrapper. Sie liefert jeweils die nächste Zeile eines Resultats in Form eines Objekts. In Zeile 97/98 wird für jede Kategorie ein Link in HTML-Spezifikation aufgebaut. In Zeile 99/100 wird die HTML-Spezifikation einer Tabellenzeile erzeugt und der Variablen $htmlOut hinzugefügt. 5.3.7 Rückgabewert 105 106 107 108 109 110 # final output $htmlOut = $htmlOut . "</table>"; return $htmlOut; Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 16 /26 } Nach Abschluss der Verarbeitung des Ergebnisses wird die HTML-Tabelle abgeschlossen (Zeile 107) und schließlich die in $htmlOut angesammelte Spezifikation an MediaWiki zum Seitenaufbau zurückgeliefert 5.4 LocalSettings.php require_once("$IP/extensions/Category/CategoryList.php"); 6 Beispiel 3: Eine Spezialseiten-Extension Eine Anleitung zur Programmierung von Extensionen mit Spezialseiten findet sich unter: http://www.mediawiki.org/wiki/Manual:Special_pages. Für den allgemeinen Fall sei auf diese Seite verwiesen. Dort ist als Vorlage für die Programmierung von Extensionen ein Beispiel “MyExtension” durchgespielt. Wir zitieren hier das Beispiel. Nach MediaWiki-Konventionen gehören zu einer Spezialseitenextension mindestens die folgenden Seiten - <ExtensionName>.php Die Installationsseite. <ExtensionName> ist durch den Namen der eigenen Extension zu ersetzen. - Special<ExtensionName>.php Das Programm für die Spezialseite (der eigentliche Code der Extension) - <ExtensionName>.i18n.php Die Internationalisierungsdatei, die die Meldungen des Programms in verschiedenen Sprachen enthält - <ExtensionName>.alias.php Die Alias-Datei der Spezialseite, die den Namen der Spezialseite in verschiedenen Sprachen enthält Die Beispiele der vier Dateien unter http://www.mediawiki.org/wiki/Manual:Special_pages sind (die Dateien können direkt im Quellcode übernommen und als Extension eingebunden werden): 6.1 Die Installationsdatei: MyExtension.php <?php # Alert the user that this is not a valid entry point to MediaWiki if they try to access the special pages file directly. if (!defined('MEDIAWIKI')) { echo <<<EOT To install my extension, put the following line in LocalSettings.php: Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 17 /26 require_once( "$IP/extensions/MyExtension/MyExtension.php" ); EOT; exit( 1 ); } $wgExtensionCredits['specialpage'][] = array( 'path' => __FILE__, 'name' => 'MyExtension', 'author' => 'My name', 'url' => 'https://www.mediawiki.org/wiki/Extension:MyExtension', 'descriptionmsg' => 'myextension-desc', 'version' => '0.0.0', ); $dir = dirname(__FILE__) . '/'; # Location of the SpecialMyExtension class # (Tell MediaWiki to load this file) $wgAutoloadClasses['SpecialMyExtension'] = $dir . 'SpecialMyExtension.php'; # Location of a messages file (Tell MediaWiki to load this file) $wgExtensionMessagesFiles['MyExtension'] = $dir . 'MyExtension.i18n.php'; # Location of an aliases file (Tell MediaWiki to load this file) $wgExtensionMessagesFiles['MyExtensionAlias'] = $dir . 'MyExtension.alias.php'; # Tell MediaWiki about the new special page and its class name $wgSpecialPages['MyExtension'] = 'SpecialMyExtension'; 6.2 Die Spezialseite: SpecialMyExtension.php <?php class SpecialMyExtension extends SpecialPage { function __construct() { parent::__construct( 'MyExtension' ); } function execute( $par ) { global $wgRequest, $wgOut; $this->setHeaders(); # Get request data from, e.g. $param = $wgRequest->getText('param'); # Do stuff # ... $output = 'Hello world!'; $wgOut->addWikiText( $output ); } } 6.3 Die Internationalisierungsdatei: MyExtension.i18n.php <?php /** * Internationalisation for myextension * * @file Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 18 /26 * @ingroup Extensions */ $messages = array(); /** English * @author <your username> */ $messages['en'] = array( 'myextension' => 'My Extension', // Important! This is the string // that appears on Special:SpecialPages 'myextension-desc' => "Extension's description", ); /** Message documentation * @author <your username> */ $messages['qqq'] = array( 'myextension-desc' => "{{desc}}", ); 6.4 Die Aliasdatei: MyExtension.alias.php <?php /** * Aliases for myextension * * @file * @ingroup Extensions */ $specialPageAliases = array(); /** English * @author <your username> */ $specialPageAliases['en'] = array( 'MyExtension' => array( 'MyExtension', 'My Extension' ), ); /** Deutsch * @author <your username> */ $specialPageAliases['de'] = array( 'MyExtension' => array( 'MeineErweiterung', 'Meine Erweiterung' ), ); 7 Beispiel 4: Eine Spezialseiten-Extension mit Parametereingabe Wir erweitern das Besipiel um die Möglichkeit der Parametereingabe. Die Basis dieses Beispiels sind - http://www.mediawiki.org/wiki/Manual:Special_pages - die MediaWiki-Spezialseite, Spezial:Export, die Eingabeparameter annimmt und verarbeitet. Der Quellcode dieser Seite steht im MediaWiki-Programmpaket unter $IP/includes/specials/SpecialExport.php. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 19 /26 - http://www.mediawiki.org/wiki/Manual:Parameters_to_Special:Export (die Schnittstellendokumentation zu SpecialExport.php) Der Quellcode des Beispiels steht unter: http://kontext.fraunhofer.de/haenelt/kurs/SMW/Programmbeispiele.php bzw. http://kontext.fraunhofer.de/haenelt/kurs/SMW/Programmbeispiele/MyExtensionP.zip Das Beispiel liefert eine Spezialseite, auf der man einen Parameter als Zeichenkette eingeben kann. Die Verarbeitung des Parameters besteht darin, dass der Parameterwert auf der Seite ausgegeben wird. An dieser Stelle wären auch andere Arten der Verarbeitung möglich. Das Einlesen von Parametern ist mit Hilfe der WebRequest-Klasse des MediaWiki-Pakets ($IP/includes/WebRequest.php) möglich. Ein Hinweis auf die Schnittstelle findet sich auf der Seite http://www.mediawiki.org/wiki/Manual:Special_pages#WebRequest.php. Die Schnittstelle funktioniert wie folgt: - einbinden von global $wgRequest in den Code der Extension - Verwendung der Funktionen dieser Klasse, beispielsweise WebRequest>getVal($key) Wir geben die Quellcode-Dateien für die Spezialseite mit Parametereingabe an. 7.1 Die Installationsdatei: MyExtensionP.php <?php # Alert the user that this is not a valid entry point to MediaWiki if they try to access the special pages file directly. if (!defined('MEDIAWIKI')) { echo <<<EOT Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 20 /26 To install my extension, put the following line in LocalSettings.php: require_once( "$IP/extensions/MyExtensionP/MyExtensionP.php" ); EOT; exit( 1 ); } $wgExtensionCredits['specialpage'][] = array( 'path' => __FILE__, 'name' => 'MyExtensionP', 'author' => 'Karin Haenelt', 'url' => 'https://www.mediawiki.org/wiki/Extension:MyExtension', 'descriptionmsg' => 'myextensionp-desc', 'version' => '0.0.0', ); $dir = dirname(__FILE__) . '/'; # Location of the SpecialMyExtensionP class # (Tell MediaWiki to load this file) $wgAutoloadClasses['SpecialMyExtensionP'] = $dir . 'SpecialMyExtensionP.php'; # Location of a messages file (Tell MediaWiki to load this file) $wgExtensionMessagesFiles['MyExtensionP'] = $dir . 'MyExtensionP.i18n.php'; # Location of an aliases file (Tell MediaWiki to load this file) $wgExtensionMessagesFiles['MyExtensionPAlias'] = $dir . 'MyExtensionP.alias.php'; # Tell MediaWiki about the new special page and its class name $wgSpecialPages['MyExtensionP'] = 'SpecialMyExtensionP'; 7.2 Die Spezialseite: SpecialMyExtensionP.php <?php class SpecialMyExtensionP extends SpecialPage { function __construct() { parent::__construct( 'MyExtensionP' ); } function execute( $par ) { global $wgRequest, $wgOut; $this->setHeaders(); # Do stuff # ... $output = 'Hello world!'; $wgOut->addWikiText( $output ); $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getTitle()->getLocalUrl( 'action=submit' ) ) ); $form .= Xml::inputLabel( wfMsg('myextensionp-parameter1'), 'parameter1', 'parameter1', 40 ) . ' '; $form .= Xml::submitButton( wfMsg( 'myextensionp-enter' ), array( 'name' => 'addparameter1' ) ) . '<br />'; Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 21 /26 $form .= Xml::closeElement( 'form' ); $wgOut->addHTML($form); # Get request data from, e.g. if ( $wgRequest->getCheck( 'addparameter1' ) ) { $parameter1 = $wgRequest->getText( 'parameter1' ); # processing of parameters, e.g. $msg = wfMsg( 'myextensionp-parameter1-entered' ) . "'''" . $parameter1 . "'''"; $wgOut->addWikiText($msg); } } } Das Eingabeformular wird mit Hilfe der Klasse Xml ($IP/includes/Xml.php) definiert. In dieser Klasse stehen weitere Elemente für ein Eingabeformuler zur Verfügung (z.B. checkLabel, radiolabel, listDropDown u.a.) Ab MediaWiki 1.17 sollte an Stelle der Funktion wfMsg() die Funktion wfMessage() verwendet werden (http://www.mediawiki.org/wiki/Manual:Messages_API ) 7.3 Die Internationalisierungsdatei: MyExtensionP.i18n.php (im folgenden Text stimmen die Zeilenumbrüche der Meldungen nicht mit dem Programm überein: Einzelzeilen sind hier auf dem Papier teilweise zu zwei Zeilen umgebrochen) <?php /** * Internationalisation for myextensionp * * @file * @ingroup Extensions */ $messages = array(); /** English * @author <your username> */ $messages['en'] = array( 'myextensionp' => 'My Extension with Parameters', // Important! // This is the string that appears on Special:SpecialPages 'myextensionp-desc' => "Test of a SpecialPage extension with Parameters", 'myextensionp-enter' => "enter", 'myextensionp-parameter1' => "parameter 1 (please enter an arbitrary string)", 'myextensionp-parameter1-entered' => "The following value has been entered for parameter 1: ", ); /** Message documentation * @author <your username> */ $messages['de'] = array( Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 22 /26 'myextensionp' => 'Meine Extension mit Parametern', // Important! // This is the string that appears on Special:SpecialPages 'myextensionp-desc' => "Test einer Spezialseitenextension mit Parametern", 'myextensionp-enter' => "eingeben", 'myextensionp-parameter1' => 'Parameter 1 (bitte eine beliebige Zeichenkette eingeben)', 'myextensionp-parameter1-entered' => 'Der folgende Wert wurde für Parameter 1 eingegeben: ', ); 7.4 Die Aliasdatei: MyExtensionP.alias.php <?php /** * Aliases for myextensionp * * @file * @ingroup Extensions */ $specialPageAliases = array(); /** English * @author <your username> */ $specialPageAliases['en'] = array( 'MyExtensionP' => array( 'MyExtensionP', 'My ExtensionP' ), ); /** Deutsch * @author <your username> */ $specialPageAliases['de'] = array( 'MyExtensionP' => array( 'MeineErweiterungMitParametern', 'Meine ErweiterungP' ), ); Die beiden fett markierten Einträge müssen unbedingt übereinstimmen. Andernfalls funktioniert das Programm nicht. 8 Zugriff auf die Wiki-Datenbank mit phpMyAdmin Sofern die Möglichkeit besteht, phpMyAdmin auf dem Wiki-Server zu nutzen (http://www.phpmyadmin.net/home_page/index.php), bietet phpMyAdmin bietet eine bequeme Möglichkeit, die Wiki-Datenbank anzusehen. Im Paket XAMPP ist phpMyAdmin enthalten. Bei lokaler Installation findet man phpMyAdmin im Browser standardmäßig unter http://localhost/phpmyadmin/ . Über die linke Seitenleiste erhält man zuerst eine Übersicht aller vorhandenen Datenbanken, und nach Anklicken einer Datenbank eine Übersicht der Tabellen dieser Datenbank. Klickt man eine Tabelle an, kann man die Tabelle in Tabellenform ansehen. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 23 /26 Abbildung 6 Ansicht der Beispieltabelle in phpMyAdmin Anmerkung: Die Inhalte einer Wikiseite stehen in der Tabelle “text”. phpMyAdmin zeigt standardmäßig nur Informationen zur Größe der Dateien an. Möchte man die Texte direkt lessen, kann man die Option “Zeige BLOB” direkt über der Tabelle aktivieren. 9 Zugriff auf die Texte der Wikiseiten über die Datenbank In der Tabelle “text” stehen die alle gespeicherten Versionen der Texte der Wikiseiten. Um die aktuellen Versionen der Seiten zu finden, muss man mehrere Tabellen benutzen. Die Information ist folgendermaßen in der Datenbank modelliert: page revision text page_title page_latest rev_id rev_text_id old_id old_text Testseite 34 58 34 58 Dies ist der Text der Testseite Die zugehörige Datenbankabfrage lautet in SQL: SELECT page.page_title, text.old_text FROM page, revision,text WHERE page.page_latest = revision.rev_id AND revision.rev_text_id = text.old_id Die entsprechende Abfrage lautet mit der Wiki-Wrapper-Funktion select(): $res=$dbr->select(array(‘page’,’revision’,’text’), array(‘page_title’,’old_text’), array(‘page_latest=rev_id’,’rev_text_id=old_id’); Inhalt der Variblen $res ist nach dieser Abfrage ein Tabellenobjekt, das mit den entsprechenden Funktionen zeilen- und spaltenweise durchgearbeitet werden muss. Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 24 /26 10 Dokumentationen zur Entwicklung von Extensionen Für die Entwicklung von Extensionen findet man im Internet einige nützliche Dokumentationen: 10.1 Entwicklung von Extensionen - Extensionen http://www.mediawiki.org/wiki/Manual:Extensions - Schreiben von http://www.mediawiki.org/wiki/Manual:Developing_extensions Extensionen 10.2 MediaWiki-Dokumentationen - MW-Dokumentation http://svn.wikimedia.org/doc/main.html - MW Code- http://www.mediawiki.org/wiki/Manual:Code Dokumentation - Verzeichnis der http://www.mediawiki.org/wiki/Manual:Configuration_settings globalen Variablen http://www.mediawiki.org/wiki/Manual:Database_access - MWDatenbankschnittstelle 10.3 Semantic MediaWiki-Dokumentationen - Ausgabeschnittstellen http://semantic-mediawiki.org/doc/classSMWQueryResult.html semantischer Queries 11 Technischer Hinweis: Softwareversionen Diese Anleitung bezieht sich auf das MediaWiki in der Version 1.16.5 und 1.18.1 in der Standardform http://www.mediawiki.org/wiki/MediaWiki/de mit PHP 5.2.8 (apache2handler) und MySQL 5.1.30-community. 12 Information und Kontakt PD Dr. Karin Haenelt Fraunhofer-Gesellschaft e.V., Julius-Reiber-Straße 15a, 64293 Darmstadt Telefon 06151-6674821 E-Mail [email protected] Karin Haenelt: Programmierung von Extensionen für das MediaWiki, 13.3.2013, 25 /26 13 Copyright © Karin Haenelt, Haenel 2012 Versionen: 4.9.2012, 21.6.2012, 16.1.2012 Karin Haenelt: Programmierung von Extensionen Ext für das MediaWiki, 13.3..2013, 26 /26