AddOn-Entwicklung #2 - Anatomie eines AddOns

Damit ein AddOn funktioniert und von REDAXO akzeptiert wird, muss es bestimmte Konventionen erfüllen. So müssen also bestimmte Dateien und Order existieren.

Ein typisches AddOn-Verzeichnis könnte so strukturiert sein:

Pflicht-Dateien

  • config.inc.php – diese ist die zentrale Initialisierungsdatei für das AddOn.
  • install.inc.php – die Anweisungen in dieser Datei werden ausgeführt, wenn das AddOn (re-)installiert wird.
  • uninstall.inc.php – die Anweisungen in dieser Datei werden ausgeführt, wenn das AddOn deinstalliert wird.

Optionale Dateien

Alle hier im Folgenden genannten Dateien und Verzeichnisse sind optional, doch bei den allermeisten AddOns wird man sie finden:

  • install.sql – hier werden die SQL-Anweisungen hinterlegt, um die nötigen Tabellen und Felder in der Datenbank anzulegen. Sie wird noch vor der install.inc.php ausgeführt.
  • uninstall.sql – hier werden die SQL-Anweisungen hinterlegt, um die AddOn-eigenen Tabellen und Felder wieder zu löschen. Auch sie wird noch vor der uninstall.inc.php ausgeführt.
  • help.inc.php – der Inhalt dieser Datei wird im Backend ausgegeben, wenn jemand auf das “[?]” neben einem AddOn-Namen klickt. Es wäre sinnvoll, hier immer einige Hilfshinweise zu hinterlegen für andere Benutzer.
  • pages/index.inc.php – diese Datei wird geladen, wenn jemand im Menü auf den betreffenden AddOn-Link aufruft.

AddOn in sieben Schritten

Weitere Verzeichnisse

Die meisten AddOns verfügen noch über weitere Verzeichnisse; diese kann man frei gestalten, doch es haben sich gewisse Konventionen eingebürgert:

  • classes/ – sofern das AddOn eigene Klassen benötigt, werden diese hier abgelegt.
  • functions/ – sofern das AddOn eigene Funktionen benötigt, werden diese hier abgelegt.
  • files/ – für Hilfsdateien (zum Beispiel Grafiken, Schriften, etc.) legt man am besten auch einen eigenen Ordner an.
  • lang/ – sofern man das mehrsprachige Backend von REDAXO unterstützt, sollte man auch die AddOnTextausgaben mehrsprachig anlegen. Die Sprachdateien liegen dann in diesem Ordner.
  • js/ – hier platziert man üblicherweise JavaScript-Dateien.
  • pages/ – die index-Datei in diesem Ordner ist die, die beim Aufruf des AddOns zunächst geladen wird. Verfügt das AddOn noch über weitere Unterseiten (Subnavigation), werden diese ebenfalls hier abgelegt und über einen GET-Parameter in der URL aufgerufen.
  • outout/ oder templates/ – oftmals ist es sinnvoll, die für die Ausgabe benötigten Dateien zentral hier anzulegen und nicht komplett in einem Modul zu speichern.

Config, install und uninstall

Nun denn, legen wir also für unser Adressen-AddOn innheralb des address-Ordners die zentrale config.inc.php an. Sie könnte folgenden Inhalt haben:

<?php
$mypage = 'adressen';
$I18N_adressen = new i18n($REX['LANG'], $REX['INCLUDE_PATH'].'/addons/'.$mypage.'/lang/');
$REX['ADDON']['rxid'][$mypage] = 'meinAddOnKey';
$REX['ADDON']['page'][$mypage] = $mypage;
$REX['ADDON']['name'][$mypage] = 'Adressliste';
$REX['ADDON']['perm'][$mypage] = 'adressen[]';
$REX['PERM'][] = 'adressen[]';
$REX['ADDON']['version'][$mypage] = '1.0';
$REX['ADDON']['author'][$mypage] = 'Peter Bickel';
?>

In der ersten Zeile geben wir dem AddOn einen Namen, unter dem es in der weiteren Programmierung angesprochen werden kann.
Danach definieren wir eine Sprachinstanz, um damit bei einem mehrsprachigen Backend alle enthaltenen Sprachen zu unterstützen. Dazu später mehr.

In der dritten Zeile folgt die Vergabe eines eindeutigen AddOnKeys – diese darf nicht mit anderen kollidieren und ist besonders wichtig, wenn man das AddOn auch anderen im Downloadbereich auf der REDAXO-Website zur Verfügung stellen will. Man erhält diesen Key, wenn man dort im MyRedaxo-Bereich ein eigenes AddOn anlegt. Dieser ID hilft z.B. u.a. dabei, dass keine gleichnamigen, von anderen AddOns angelegten DB-Tabellen entstehen.

Zur korrekten Definition des AddOnKeys gibt es ein eigenes kleines Tutorial:

Der AddOnKey - Bedeutung und Konventionen

Als nächstes folgt die Belegung der page-Variable, die zum Erzeugen der Backend-URLs für dieses AddOn benötigt wird. Das AddOn wird hier in unserem Beispiel also angesprochen über /redaxo/index.php?page=adressen.
Der Array-Schlüssel “name” schließlich dient zur Anzeige des Navigationspunkts, und mit “perm” können wir für jeden Backend-User die Berechtigung zum Zugriff auf dieses AddOn steuern. Die AddOn-Rechte ließen sich noch wesentlicher feiner einstellen (zum Beispiel für jede Unterseite des AddOns oder für jede Aktion wie neu anlegen oder löschen), aber das würde hier zu weit führen.

Die Schlüssel “version” und “author” dienen lediglich zur Information, die beim Anklicken des Fragezeichens – damit ruft man wie schon erwähnt die Hilfeseite des AddOns auf – bei einem AddOn angezeigt wird. Ebenfalls mit ausgegeben wird hier der – mit HTML-Code formatierbare – Inhalt der bereits angesprochenen Datei help.inc.php, die dazu vorgesehen ist, dem Redakteur Hilfen und Hinweise zum AddOn zu geben.

AddOn in sieben Schritten

install.inc.php und uninstall.inc.php

Die Datei install.inc.php enthält alle Befehle, die bei der Installation des AddOns einmalig ausgeführt werden. Sie muss mindestens folgende Zeile enthalten:

<?php
$REX["ADDON"]["install"]["adressen"] = 1;
// Install-Status wird von 0 auf 1 geändert
?>

Der Aufbau der uninstall.inc.php sieht analog aus.

Möchten wir noch eigene Tabellen in der Datenbank anlegen, könnten wir diese Befehle in der install-Datei mit aufnehmen. Noch einfacher: Man muss einfach eine Datei install.sql mit den gewünschten SQL-Befehlen im AddOn-Verzeichnis anlegen; diese wird automatisch bei der Installation ausgeführt. Für unser Adressen-AddOn könnte sie diesen Inhalt haben:

DROP TABLE IF EXISTS "%TABLE_PREFIX%553_gruppen";
DROP TABLE IF EXISTS "%TABLE_PREFIX%553_adressen";
CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%553_gruppen` ( "id" int(11) NOT NULL auto_increment, "gruppe" varchar(255) NOT NULL default "", PRIMARY KEY ("id") ) ENGINE=MyISAM;
CREATE TABLE IF NOT EXISTS `%TABLE_PREFIX%553_adressen` ( "id" int(11) NOT NULL auto_increment, "name" varchar(255) NOT NULL default "", "vorname" varchar(255) NOT NULL default "", "strasse" varchar(255) NOT NULL default "", "plz" varchar(30) NOT NULL default "", "stadt" varchar(255) NOT NULL default "", "status" int(11) NOT NULL default "1", "r_gruppe" int(11) NOT NULL default "0", PRIMARY KEY ("id")
) ENGINE=MyISAM;

Kurz erklärt: Hierdurch legt die Installation zwei neue Tabellen an – nachdem diese vorher gelöscht wurden, um einer möglichen Konfusion durch eine voran gegangene Installation vorzubeugen. Bei beiden Tabellen wird der für jede REDAXO-Installation individuelle Prefix vor den Tabellennamen gesetzt; üblicherweise lautet er “rex_”. Dieses Vorgehen mit dem Prefix ist auch deswegen sinnvoll, weil die REDAXO-eigene Export-Funktion nur Tabellen mit diesem Prefix exportiert.
Ebenfalls in den Tabellennamen integriert ist die eindeutige AddOn-ID, die verhindern soll, dass die Tabellennamen mit denen anderer AddOns kollidieren.

Die Adressentabelle ist mit den üblichen postalischen Adressfeldern ausgestattet; daneben soll uns die Verknüpfung mit einer Gruppentabelle die Zuweisung einer Adresse zu einer Gruppe (Händler, Kunde, etc.) ermöglichen. Als Verknüpfungsfeld zur Gruppentabelle dient das Feld ,r_gruppe‘. Falls wir gleich ein Ausgabemodul automatisch bei der Installation anlegen lassen wollen, könnten wir diese natürlich ebenfalls mit in die install.sql aufnehmen.

Das AddOn im Backend

Nun könnte das AddOn theoretisch installiert werden und ließe sich über einen eigenen Menüpunkt im Backend ansprechen. Doch wir müssen ja noch die Seiten erstellen, die die Adress-Datensätze ergänzen, verändern und löschen können. Diese Seiten müssen wir im AddOn-Unterordner pages speichern. Von zentraler Bedeutung ist hier insbesondere die Datei index.inc.php. Sie wird als erstes beim Aufruf des AddOns geladen und regelt die weitere Navigation der Unterseiten.

AddOn in sieben Schritten

<?php
$Basedir = dirname(__FILE__);

$page = rex_request("page", "string");
$subpage = rex_request("subpage", "string");
$func = rex_request("func", "string");

include_once $REX["INCLUDE_PATH"]."/layout/top.php";

$subpages = array(
array("adressen", "Adressen"),
array("gruppen", "Gruppen")
);

rex_title("Adressliste", $subpages);

switch($subpage) {
case "gruppen":
require $Basedir ."/gruppen.inc.php";
break;
default:
require $Basedir ."/adressen.inc.php";
}

include_once $REX["INCLUDE_PATH"]."/layout/bottom.php";
?>

Ok, sehen wir uns das mal näher an:
Die ersten Zeilen dienen dazu, den aktuellen Verzeichnisnamen in einer Variable abzulegen und die REQUEST-Parameter in der URL zu säubern. Dies ist im Backend zwar weit weniger wichtig als im Frontend, sollte aber trotzdem beachtet werden. rex_request(“page”, “string”) zum Beispiel prüft hier im konkreten Fall die per REQUEST übertragene Variable page, ob sie aus einem String besteht und gibt – sofern vorhanden – deren Wert zurück.

Zur Information: $page steuert den Zugang zum AddOn, $subpage den Zugang zu einer eventuellen Untermenü-Seite, und das ebenfalls über die URL ausgelieferte $func dient üblicherweise zur Unterscheidung, ob wir uns innerhalb des AddOns im Auflistungs- oder Editiermodus befinden.

Anschließend wird der Kopfbereich der Seite (Header) inkludiert und ein Array für die Unterseiten des AddOns angelegt – in diesem Fall sind es zwei, eins für die Verwaltung der Gruppen und eines für die Adressen. Der erste Wert des Arrays ist die per URL übertragene subpage-Variable, der zweite der korrespondierende Seitentitel, der mit dem Befehl rex_title() als sichtbarer Seitentitel angezeigt wird. Der Switch-Operator bindet je nach URL die – noch zu erstellende – Adress-Seite oder Gruppen-Seite aus unserem pages-Ordner ein; dann folgt die Ausgabe des Fußbereichs (Footer). Dies ist unser nächster Schritt: Wir erstellen nun die beiden Dateien gruppen.inc.php und adressen.inc.php im pages-Ordner.

Weiter zum Teil 3 - rex_list und rex_form

Zurück zum Teil 1 - Einleitung