Code modularisieren - APEX erweitern: Mit APEX 4.0 Plugins

Einführung

Eins der interessantesten neuen Features in APEX 4.0 ist die Erweiterbarkeit von APEX mit Hilfe von Plugins. In APEX 4.0 können Plugins für folgende Komponententypen geschrieben werden.

  • Region Type Plugins
  • Item Type Plugins
  • Dynamic Action Plugins
  • Process Type Plugins

Sobald ein Plugin in der Anwendung installiert ist, steht es dem Anwendungsentwickler zusätzlich zu den eingebauten Komponententypen zur Verfügung. Ist demnach ein Regions-Plugin installiert, so steht dieses neben den Standard-Regionstypen wie Bericht, Formular oder Diagramm bereit (Abbildung 1). Item-Type-Plugins werden nach Installation neben den eingebauten Elementtypen wie Textbox oder Auswahlliste aufgeführt. Es macht für die Entwicklung einer Anwendung keinen Unterschied, ob man eine eingebaute oder eine Plugin-Komponente verwendet.

Neuer Regionstyp "Plugin"
Neuer Regionstyp "Plugin"

Abbildung 1: Neuer Regionstyp "Plugin"

Grundsätzlich gilt, dass die gleichen Dinge, die in APEX 4.0 mit Plugins möglich sind, auch schon mit den früheren APEX-Versionen machbar waren. Das Besondere ist dagegen die Organisation des Codes. In einem Plugin werden der PL/SQL- und JavaScript-Code und alle zum Plugin gehörenden Dateien (CSS- und Bilddateien) in einem Paket gebündelt. Die Vorgehensweise zur Einbindung und Parametrisierung eines Plugins ist stets gleich, so dass ein APEX-Entwickler sich in einem neuen Plugin sehr schnell zurechtfinden dürfte,

Und das ist ein ganz entscheidender Vorteil: Der Code für ein bestimmtes Anwendungsfeature ist nun an einem Ort zusammengefasst (eben im Plugin) und nicht mehr quer über die Anwendung verteilt. Desweiteren entwickelt man ein Plugin typischerweise losgelöst von einer bestimmten Anwendung - das Plugin ist also leichter wiederzuverwenden. Packt man den Code (wie bisher) in die APEX-Anwendung, so ist es wahrscheinlich, dass man sich auf andere Anwendungskomponenten verlässt, der Code läuft also nur in besagter Anwendung und ist schwerer in andere übertragbar.

Fasst man das alles zusammen, ergeben sich zwei Anwendungsgebiete für APEX-Plugins:

  • Der naheliegendste Aspekt ist sicherlich die Möglichkeit, APEX zu erweitern und solche generischen Erweiterungen mit der Community zu teilen. Die von Oracle bereitgestellten Plugins ( Grouped Select List, Masked Input Field) gehen genau in diese Richtung.
  • Doch auch wenn man nicht vorhat, seine Entwicklungsarbeit in die Öffentlichkeit zu tragen, können Plugins sehr charmant sein. Denn Plugins sind ein hervorragender Ansatz, wiederverwendbare Komponenten zu entwickeln. So könnte die Neuanlage eines Kunden- oder Auftragsdatensatzes durchaus als Process-Type-Plugin entwickelt werden. Ein solches Plugin würde mit Sicherheit nicht an die Öffentlichkeit gehen; das wäre bei einem so unternehmensspezifischen Plugin auch gar nicht sinnvoll. Aber unternehmensintern kann es sehr wertvoll sein - denn jeder APEX-Entwickler, der einen solchen Datensatz anlegen muss, muss das nicht mehr selbst programmieren - es wird nur noch das Plugin geladen und verwendet. Es sind also auch unternehmensspezifische, interne "Plugin-Repositories" denkbar.

Ein vorhandenes Plugin einspielen und nutzen

Ein bereits vorhandenes Plugin einzuspielen, ist sehr einfach - wir werden diesen Vorgang daher hier nur kurz beschreiben und danach sofort zum Erstellen eines eigenen Plugins übergehen. Wenn Sie Ihrer Applikation Plugins hinzufügen möchten, navigieren Sie zunächst zu den Gemeinsamen Komponenten und dort zum Bereich Plugins (Abbildung 2).

"Plugins" bei den Gemeinsamen Komponenten

Abbildung 2: "Plugins" bei den Gemeinsamen Komponenten

Normalerweise ist dieser Bereich zu Beginn leer. Zunächst ist sicherlich ein Klick auf die Schaltfläche View Plugin Repository zu empfehlen (Abbildung 3). Sie werden dann auf die "offizielle" Plugin-Seite des APEX-Entwicklerteams geleitet. Daneben steht mit www.apex-plugin.com ein alternatives Repository für Plugins der Community bereit.

Schaltfläche "View Plugin Repository"

Abbildung 3: Schaltfläche "View Plugin Repository"

Nach dem Herunterladen können Sie das Plugin mit einem Klick auf die Schaltfläche Importieren einspielen. Der Dialog ähnelt sehr stark einem APEX-Anwendungsimport.

Heruntergeladenes Plugin per Import einspielen

Abbildung 4: Heruntergeladenes Plugin per Import einspielen

Wenn Sie bspw. ein Item-Type-Plugin eingespielt haben, steht es danach bei den Elementtypen zur Verfügung (Abbildung 5). Welche Parameter zu setzen sind, hängt vom Plugin ab. Wie gut die Hilfetexte gepflegt sind, hängt vom Entwickler des Plugins ab.

Ein neues Element vom Typ "Star Rating" anlegen
Ein neues Element vom Typ "Star Rating" anlegen

Abbildung 5: Ein neues Element vom Typ "Star Rating" anlegen

Ein eigenes Plugin entwickeln

Im folgenden wird, anhand eines einfachen Beispiels, beschrieben, wie Sie ein eigenes Plugin entwickeln können. In diesem Tipp werden wir mit einem Regions-Plugin namens "Client-Status" beginnen: Es soll Angaben zum eingeloggten Benutzer anzeigen, also dessen Name, die IP-Adresse, den verwendeten Browser und die Uhrzeit, zu der die Session geöffnet wurde.

All diese Informationen lassen sich mit wenigen PL/SQL-Aufrufen ( bspw. OWA_UTIL.GET_CGI_ENV('REMOTE_ADDR') ermitteln - und es ist natürlich ein leichtes, diese Anforderungen als APEX-Bericht zu implementieren. Aber darum geht es hier nicht: Das Plugin soll dem APEX-Entwickler künftig die Aufgabe abnehmen, das SQL für einen solchen Bericht zu schreiben. Das Plugin kann dann in einer Anwendung mit wenigen Klicks genutzt weerden.

Navigieren Sie also nochmals zu den Gemeinsamen Komponenten und dort zu den Plugins. Anstelle von Importieren klicken Sie nun die Schaltfläche Erstellen. Sie sehen dann den Dialog zum Erzeugen eines neuen Plugins (Abbildung 6).

Ein neues Plugin erstellen

Abbildung 6: Ein neues Plugin erstellen

Dass ein Plugin zwei Namen hat, fällt wahrscheinlich jedem als erstes auf. Das erste Eingabefeld Name ist der Name, der dem APEX-Entwickler angezeigt wird, wenn er eine neue Region erstellt und unter den installieren Regions-Plugins wählen soll. Der zweite Internal Name dient der globalen Eindeutigkeit. Es ist vorgesehen und beabsichtigt, dass Plugins in der Community geteilt werden - es ist also wahrscheinlich, dass ein Plugin, das in einem Unternehmen entwickelt wurde, woanders eingesetzt wird. Um die daraus entstehenden potenziellen Namenskonflikte zu verhinden, gibt es den internen Namen. Am besten halten Sie sich hier an das URL-Konzept - für unser neues Plugin wählen Sie also Client-Status als Name und com.oracle.de.apexcommunity.clientstatus als internen Namen. Als Typ wählen Sie Region aus.

Im nächsten Abschnitt kann der Code über den APEX-Subscription-Mechanismus von einem anderen Plugin abonniert werden. Dieser Mechanismus erlaubt das Führen einer Master-Anwendung (mit Plugins), deren Änderungen dann auf die abonnierenden Anwendungen übertragen werden können. Das ist sehr nützlich, wenn ein Plugin in mehreren Anwendungen verwendet werden und dann bspw. eine neue Version eingespielt werden soll. Das aktualisierte Plugin kann dann mit einem Klick auf alle Anwendungen übertragen werden. Mehr zum Subscription-Feature in diesem Community-Tipp.

Das nächste, wichtige Feld ist der PL/SQL Code, der in diesem Fall für das Rendering der Region verantwortlich ist. Da das Plugin sich an die APEX-Infrastruktur anpassen muss, ist für die verschiedenen Plugin-Typen eine ganz bestimmte Funktionssignatur vorgeschrieben. Für ein Regions-Plugin muss mindestens die Render-Funktion wie folgt ausprogrammiert werden.

function {name of function} (
    p_region              in apex_plugin.t_region,
    p_plugin              in apex_plugin.t_plugin,
    p_is_printer_friendly in boolean )
    return apex_plugin.t_region_render_result

Den Namen der Funktion selbst können Sie dabei frei wählen. Er muss nur unterhalb im Bereich Callbacks als Render Function eingetragen werden. Hinterlegen Sie also den folgenden PL/SQL-Code:

function render_client_status (
  p_region              in apex_plugin.t_region,
  p_plugin              in apex_plugin.t_plugin,
  p_is_printer_friendly in boolean 
) return apex_plugin.t_region_render_result is
  -- Übernahme der Plugin-Parameter in lokale Variablen
  l_table_attributes  apex_application_page_regions.attribute_01%type := p_region.attribute_01;
  l_cell_attributes   apex_application_page_regions.attribute_02%type := p_region.attribute_02;
  l_show_ipaddress    apex_application_page_regions.attribute_03%type := p_region.attribute_03;

  l_app_name          varchar2(200);
begin
  -- Escaping der Parameter 
  l_table_attributes := apex_plugin_util.escape(l_table_attributes, true);
  l_cell_attributes  := apex_plugin_util.escape(l_cell_attributes, true);

  select application_name into l_app_name
  from apex_applications
  where application_id = v('APP_ID');

  sys.htp.prn ('<table class="'||l_table_attributes||'">');
  sys.htp.prn ('<tbody>');
  sys.htp.prn ('<tr>');
  sys.htp.prn ('<td '||l_cell_attributes||'>');
  sys.htp.prn ('Anwendung: '); 
  sys.htp.prn ('</td>');
  sys.htp.prn ('<td '||l_cell_attributes||'>');
  sys.htp.prn (l_app_name);
  sys.htp.prn ('</td>');
  sys.htp.prn ('</tr>');
  sys.htp.prn ('<tr>');
  sys.htp.prn ('<td '||l_cell_attributes||'>');
  sys.htp.prn ('Benutzername: '); 
  sys.htp.prn ('</td>');
  sys.htp.prn ('<td '||l_cell_attributes||'>');
  sys.htp.prn (v('APP_USER')); 
  sys.htp.prn ('</td>');
  sys.htp.prn ('</tr>');
  if l_show_ipaddress = 'Y' then
    sys.htp.prn ('<tr>');
    sys.htp.prn ('<td '||l_cell_attributes||'>');
    sys.htp.prn ('IP-Adresse: '); 
    sys.htp.prn ('</td>');
    sys.htp.prn ('<td '||l_cell_attributes||'>');
    sys.htp.prn (sys.owa_util.get_cgi_env('REMOTE_ADDR'));
    sys.htp.prn ('</td>');
    sys.htp.prn ('</tr>');
  end if;
  sys.htp.prn ('</tbody>');
  sys.htp.prn ('</table>');
  return null;
end;

Tragen Sie danach render_client_status als Render Function Name ein, navigieren Sie nach oben und klicken Sie auf Erstellen. Wenn Ihr PL/SQL-Code fehlerfrei ist, werden Sie wieder auf die gleiche Seite verzweigt, unterhalb der Callbacks können Sie aber nun Standard-Attribute und Benutzerdefinierte Attribute (Plugin-Parameter) Ihres Plugins festlegen und Dateien hochladen.

Im PL/SQL-Code werden zu Beginn drei Parameter referenziert. Ihr PL/SQL-Code bekommt alle Informationen über Attribute und den Kontext, aus dem das Plugin heraus ausgeführt wird, in den Parametern p_region und p_plugin übergeben Das APEX-Team hat sich hier für ein Record-Strukturen (apex_plugin.t_region bzw. apex_plugin.t_plugin) entschieden. Aus dieser werden die konkreten Parameter ausgelesen und der besseren Übersichtlichkeit halber in lokale PL/SQL-Variablen übernommen. Der Rest des Codes generiert mit Hilfe von htp.p bzw. htp.prn den HTML-Code zur Darstellung der gewünschten Informationen. Klicken Sie als als nächstes im Bereich Benutzerdefinierte Attribute auf die Schaltfläche Attribut hinzufügen, um die drei Parameter einzurichten.

Der erste Plugin-Parameter wird festgelegt

Abbildung 7: Der erste Plugin-Parameter wird festgelegt

Abbildung 7 zeigt die Einrichtung des ersten Parameters. Mit diesem kann der Entwickler HTML-Attribute festlegen, die vom Plugin in das <table> Tag eingebaut werden sollen. Legen Sie analog dazu den zweiten Parameter für die Attribute der Tabellenzellen an. Der dritte Parameter soll eine Ja/Nein-Auswahl sein - damit legt der Entwickler fest, ob die IP-Adresse angezeigt werden soll oder nicht. Abbildung 8 zeigt, wie das aussieht.

Plugin-Parameter "Zeige IP-Adresse" festlegen

Abbildung 8: Plugin-Parameter "Zeige IP-Adresse" festlegen

Sie können zu jedem Parameter einen Hilfetext vergeben - und es ist auch sehr empfehlenswert, hier etwas Zeit zu investieren. Denn ein Plugin ist nicht mehr und nicht weniger als ein Code-Modul, bei dem Sie davon ausgehen, dass es eine andere Person verwenden wird. Zuviel Dokumentation kann es da also gar nicht geben. Wenn Sie alle Parameter definiert haben, können Sie Ihr Plugin mit der Schaltfläche Änderungen anwenden oben rechts abspeichern.

Das Plugin wurde erstellt

Abbildung 9: Das Plugin wurde erstellt

Nun können Sie Ihr Plugin ausprobieren. Navigieren Sie zu einer Anwendungsseite oder erstellen Sie eine neue und gehen Sie in den Dialog für eine neue Region. Als Regionstyp wählen Sie Plugin und in der Liste der verfügbaren Plugins Client-Status aus (Abbildung 10).

Eine neue Region vom Typ "Client-Status" wird erstellt

Abbildung 10: Eine neue Region vom Typ "Client-Status" wird erstellt

Wie bei jeder neuen Region können Sie dann Titel und Anzeigeposition bestimmen. Interessant wird der nächste Dialog - denn hier werden die von Ihnen vorhin deklarierten Parameter mit Werten belegt (Abbildung 11).

Die Parameter der Plugin-Region werden festgelegt

Abbildung 11: Die Parameter der Plugin-Region werden festgelegt

Nachdem Sie die Region erzeugt haben, starten Sie die Seite - das Ergebnis sollte in etwa wie in Abbildung 12 aussehen.

Das neue Plugin in Aktion

Abbildung 12: Das neue Plugin in Aktion

Das Besondere daran ist nicht die Ausgabe, die hätte man auch mit einem Bericht schaffen können. Vielmehr ist die Tatsache, dass beim Hinzufügen der Region keine Kenntnisse mehr über den Inhalt erforderlich waren. Das Plugin kann als Baustein verwendet werden und zwar nicht nur in dieser, sondern in jeder anderen APEX-Anwendung. Dazu muss es lediglich exportiert und in der anderen Anwendung importiert werden. Navigieren Sie hierzu nochmals zu den Gemeinsamen Komponenten , dort zu den Plugins und dann zu Ihrem Plugin Client-Status (Abbildung 13).

Plugin bearbeiten

Abbildung 13: Plugin bearbeiten

Mit einem Klick auf Plugin Exportieren (ganz rechts) kommen Sie auf den in Abbildung 14 dargestellten Dialog. Hier können Sie das Plugin, so wie Sie es von APEX-Anwendungen gewohnt sind, exportieren.

Plugin exportieren

Abbildung 14: Plugin exportieren

Die Exportdatei kann nun in andere APEX-Anwendungen auf dem gleichen Server oder auf anderen Servern importiert werden. Das Plugin kann somit einfach verteilt und von vielen anderen APEX-Entwicklern verwendet werden.

Fazit

Das neue APEX 4.0-Feature Plugins eignet sich hervorragend zur Organisation von Anwendungscode in Komponenten. Nicht nur generische Features wie ein "Star Rating" oder "Masked Input Field" eignen sich als Plugin - auch unternehmensspezische Komponenten können als Plugin gekapselt und damit einfach wiederverwendet werden. Sammelt man Plugins dann noch in einer Master-Anwendung und verwendet den Subscription-Mechanismus, so hat man eine sehr effiziente Kontrolle über Komponenten und deren Aktualisierungen.

Am besten beginnen Sie gleich heute mit der Entwicklung von Plugins - wenn Sie in Ihrer Anwendung Regionen vom Typ Dynamischer PL/SQL Inhalt haben oder den gleichen PL/SQL-Code in APEX-Prozessen immer wieder schreiben, sind das perfekte Kandidaten für ein Plugin.

Mehr Informationen

Zurück zur Community-Seite