Adminwidget
HowTo: Adminwidget
Das Dashboard des Kajona-Backends bietet die Möglichkeit, Widgets hinzuzufügen, zu löschen oder zu verschieben. Um eigene Funktionalitäten auf das Dashboard zu bringen bietet Kajona die Möglichkeit, eigene Widgets zu erstellen und auf das Dashboard zu legen.
Das Erstellen eines eigenen Widgets ist recht einfach und soll anhand des Wetter-Widgets beschrieben werden. Die hier beschriebene Vorgehensweise lässt sich einfach auf eigene Widgets übertragen und anwenden.
Das Wetter-Widget soll die aktuelle Temperatur sowie einen Vorhersagewert für einen zu definierenden Ort ausgeben können. Hierfür soll auf die Webservices von YAHOO zugegriffen werden. Um das Widget international einsetzen zu können sollte zwischen Grad Celsius und Fahrenheit umgeschaltet werden können.
Eine aktuelle Version dieses Widgets gibt es auch auf www.kajona.de zum Download.
Neue Widgets nehmen wir gerne in unsere Download-Archive auf, einfach per Forum, Mail oder Kontaktformular schreiben.
Dateistruktur erstellen
Das im Folgenden entwickelte Widget soll natürlich nicht nur für das eigene System verwendet werden, sondern soll auch an andere Kajona-User weitergegeben werden können. Von daher sollte das Widget gleich in einer Version erstellt werden, die später weiter verteilbar ist.
In unserem Fall legen wir nun einen Ordner „widget_weather“ an, der nachstehende Dateien und Ordner beinhaltet:
widget_weather
|- admin
| |- widgets
| |- class_adminwidget_weather.php
|
|- texte
|- admin
|- modul_adminwidget
|- texte_adminwidgetweather_de.php
Als Grafik sieht das dann so aus:

Doch nun zur Bedeutung der einzelnen Dateien im Detail:
- /admin/widgets/class_adminwidget_weather.php
Diese Datei beinhaltet die eigentliche Logik des Widgets. Hier wird die Ausgabe aufbereitet und an Kajona übergeben.
- /texte/admin/modul_adminwidget/texte_adminwidgetweather_de.php
Texte die auf der Oberfläche des Widgets angezeigt werden sind in dieser Datei erfasst.
Benötigte Klassen erstellen
Nachdem nun alle benötigten Dateien angelegt wurden, geht es nun an das Erstellen der benötigten Klasse, also des Programmcodes.
Da nur eine Klasse implementiert werden muss handelt es sich um das
Widget
Wie in Kajona üblich gilt die Namenskonvention Dateiname = Klassenname. Im Vorfeld wurde die Datei bereits unter dem Namen „class_adminwidget_weather.php“ angelegt, dies führt dann zwingendermaßen zum Klassennamen „class_adminwidget_weather“. Der Aufbau der Klasse wird durch das zu implementierende Interface und durch die abzuleitende Basisklasse definiert, Näheres folgt nun.
<?php
Damit die Klasse alle benötigten Interfaces, Klassen und Funktionen kennt, müssen diese zu Beginn erst einmal inkludiert werden:
include_once(_adminpath_."/widgets/class_adminwidget.php");
include_once(_adminpath_."/widgets/interface_adminwidget.php");
Die nun zu definierende Klasse muss von der Klasse „class_adminwidget“ abgeleitet werden und das Interface „interface_adminwidget“ implementieren.
class class_adminwidget_weather extends class_adminwidget implements interface_adminwidget {
Der Konstruktor der Klasse wird, im Gegensatz zu vielen anderen Klassen, zur Konfiguration des Widgets verwendet. Hier werden die Felder definiert, die später gespeichert werden sollen. Gemäß den Anforderungen sind dies die Werte für die Einheit und den Ort. Diese werden über die Methode „setPersistenceKeys()“ der Basisklasse mitgeteilt.
public function __construct() {
parent::__construct();
//register the fields to be persisted and loaded
$this->setPersistenceKeys(array("unit", "location"));
}
Um alles Weitere, das Laden und Speichern der Daten, kümmert sich Kajona. Der nächste Schritt ist die Methode „getEditForm()“. Wie der Name schon besagt erzeugt diese das Formular um das Widget zu bearbeiten. Da das Wetter-Widget zwei Werte zur Konfiguration besitzt sollten diese hier aufbereitet werden. Für das Einstellen der Einheit wird ein Dropdown-Feld verwendet, für den Ort ein Eingabefeld. Um dem Benutzer beim Ausfüllen des Ortes behilflich zu sein, soll ein Hinweisetext mit einem Verweis auf die Yahoo-Wetter-Seiten eingeblendet werden. Die Texte werden aus den Textdateien ausgelesen. Da bei einem späteren Bearbeiten auch die bisher eingegebenen Werte angezeigt werden sollen, kann auf diese über die Methode „getFieldValue()“ zugegriffen werden. Der Name entspricht hierbei den im Konstruktor definierten PersistenceKeys. Ebenso sollte die ID des Formularelements mit dem jeweiligen PersistenceKey übereinstimmen.
public function getEditForm() {
$strReturn = "";
$strReturn .= $this->objToolkit->formInputDropdown("unit",
array("f" => $this->getText("weather_fahrenheit"),
"c" => $this->getText("weather_celsius")),
$this->getText("weather_unit"), $this->getFieldValue("unit"));
$strReturn .= $this->objToolkit->formTextRow($this->getText("weather_location_finder"));
$strReturn .= $this->objToolkit->formInputText("location", $this->getText("weather_location") , $this->getFieldValue("location"));
return $strReturn;
}
Das erzeugte Formular sieht dann wie folgt aus:

Nachdem nun alle Daten erfasst wurden können diese auf dem Dashboard ausgewertet werden. Dies erfolgt in der Methode „getWidgetOutput()“. Auf die im System gespeicherten Werte kann wieder über die Methode „getFieldValue()“ zugegriffen werden.
Um die Ausgabe zu formatieren bietet die Basisklasse Ausgabemethoden wie „widgetText()“ und „widgetSeparator()“ an. An dieser Stelle sollte NICHT auf die Methoden des Toolkits zugegriffen werden.
Im Falle des Wetter-Widgets wird über den Remoteloader auf die Wetterdaten zugegriffen. Das Ergebnis in Form einer XML-Datei wird dann aufbereitet und dem Benutzer präsentiert. Da die Struktur der Datei hier nicht von Interesse ist wird dieser Teil nicht näher betrachtet. An sich kann in dieser Methode jedoch beliebiger Code zum Laden und Aufbereiten der darzustellenden Informationen ausgeführt werden.
public function getWidgetOutput() {
$strReturn = "";
try {
include_once(_systempath_."/class_remoteloader.php");
$objRemoteloader = new class_remoteloader();
$objRemoteloader->setStrHost("weather.yahooapis.com");
$objRemoteloader->setStrQueryParams("/forecastrss?p=".$this->getFieldValue("location")."&u=".$this->getFieldValue("unit"));
$strContent = $objRemoteloader->getRemoteContent();
}
catch (class_exception $objExeption) {
$strContent = "";
}
[...]
return $strReturn;
}
Die Ausgabe führt zu einem Bild wie dem folgenden:

Last but not least folgt die Methode „getWidgetName“. Diese sollte einen kurzen Namen des Widgets zurückgeben. Dieser wird in den Dialogen und den Dropdowns des Dashboards verwendet.
public function getWidgetName() {
return $this->getText("weather_name");
}
}
?>
Texte
Die Textdatei stellt alle benötigten Texte zur Verfügung. Diese sollten in der Regel selbsterklärend sein :). Um ein doppeltes Auflisten zu vermeiden befinden sich diese im Anhang.
Und das wars schon. Fertig ist das erste, eigene Widget. Nun muss dieses nur noch im System getestet werden.
Viel Spaß beim Erstellen weiterer, eigener Widgets.
P.S.: Wir freuen uns immer darüber, neue Widgets auf www.kajona.de veröffentlichen zu dürfen.
Anhang - class_adminwidget_weather.php
<?php
include_once(_adminpath_."/widgets/class_adminwidget.php");
include_once(_adminpath_."/widgets/interface_adminwidget.php");
class class_adminwidget_weather extends class_adminwidget implements interface_adminwidget {
public function __construct() {
parent::__construct();
//register the fields to be persisted and loaded
$this->setPersistenceKeys(array("unit", "location"));
}
public function getEditForm() {
$strReturn = "";
$strReturn .= $this->objToolkit->formInputDropdown("unit", array("f" => $this->getText("weather_fahrenheit"), "c" => $this->getText("weather_celsius")),
$this->getText("weather_unit"), $this->getFieldValue("unit"));
$strReturn .= $this->objToolkit->formTextRow($this->getText("weather_location_finder"));
$strReturn .= $this->objToolkit->formInputText("location", $this->getText("weather_location"), $this->getFieldValue("location"));
return $strReturn;
}
public function getWidgetOutput() {
$strReturn = "";
try {
include_once(_systempath_."/class_remoteloader.php");
$objRemoteloader = new class_remoteloader();
$objRemoteloader->setStrHost("weather.yahooapis.com");
$objRemoteloader->setStrQueryParams("/forecastrss?p=".$this->getFieldValue("location")."&u=".$this->getFieldValue("unit"));
$strContent = $objRemoteloader->getRemoteContent();
}
catch (class_exception $objExeption) {
$strContent = "";
}
if($strContent != "") {
include_once(_systempath_."/class_xml_parser.php");
$objXmlparser = new class_xml_parser();
$objXmlparser->loadString($strContent);
$arrWeather = $objXmlparser->xmlToArray();
if(isset($arrWeather["rss"])) {
if(isset($arrWeather["rss"][0]["channel"][0]["yweather:location"][0]"attributes"]["city"]))
$strReturn .= $this->widgetText($this->getText("weather_location_string").$arrWeather["rss"][0]["channel"][0]["yweather:location"][0]["attributes"]["city"]);
if(isset($arrWeather["rss"][0]["channel"][0]["item"][0]["yweather:condition"][0]["attributes"]["temp"]))
$strReturn .= $this->widgetText($this->getText("weather_temp_string")
.$arrWeather["rss"][0]["channel"][0]["item"][0]["yweather:condition"][0]["attributes"]["temp"]
." °".$arrWeather["rss"][0]["channel"][0]["yweather:units"][0]["attributes"]["temperature"]);
$strReturn .= $this->widgetSeparator();
$strReturn .= $this->widgetText($this->getText("weather_forecast"));
$strReturn .= $this->widgetText($arrWeather["rss"][0]["channel"][0]["item"][0]["yweather:forecast"][0]["attributes"]["date"].": "
.$arrWeather["rss"][0]["channel"][0]["item"][0]["yweather:forecast"][0]["attributes"]["high"]
." °".$arrWeather["rss"][0]["channel"][0]["yweather:units"][0]["attributes"]["temperature"]);
$strReturn .= $this->widgetText($arrWeather["rss"][0]["channel"][0]["item"][0]["yweather:forecast"][1]["attributes"]["date"].": "
.$arrWeather["rss"][0]["channel"][0]["item"][0]["yweather:forecast"][1]["attributes"]["high"]
." °".$arrWeather["rss"][0]["channel"][0]["yweather:units"][0]["attributes"]["temperature"]);
}
else
$strReturn .= $this->getText("weather_errorloading");
}
else
$strReturn .= $this->getText("weather_errorloading");
return $strReturn;
}
public function getWidgetName() {
return $this->getText("weather_name");
}
}
?>
Anhang - texte_adminwidgetweather_de.php
<?php
$text["weather_name"] = "Wetter";
$text["weather_unit"] = "Einheit:";
$text["weather_fahrenheit"] = "Fahrenheit";
$text["weather_celsius"] = "Celsius";
$text["weather_location"] = "Orts-Id:";
$text["weather_location_finder"] = "Die ID zu einem Ort finden Sie unter <a href=\"http://weather.yahoo.com\" target=\"_blank\">http://weather.yahoo.com</a>
(z.B. in der URL eines angezeigten Wetterberichts)";
$text["weather_errorloading"] = "Fehler beim Laden der Wetterdaten.";
$text["weather_location_string"] = "Ort: ";
$text["weather_temp_string"] = "Temperatur: ";
$text["weather_forecast"] = "Vorhersage:";
?>


