Follow Us on Twitter

Apex Plug-ins

Gepubliceerd in

September 2010 - Sinds de Early Adopter release van Apex 4.0 hebben we kennis kunnen maken met verschillende nieuwe features, waaronder de Apex plug-ins. Deze langverwachte feature maakt het voor de ontwikkelaar mogelijk om gestructureerde, herbruikbare en uitwisselbare processen of user interface componenten te bouwen. Om in te grijpen in bijvoorbeeld het gedrag van een veld op het scherm waren we hiervoor nog aangewezen op veelvuldig gebruik van Javascript, al dan niet via een library als jQuery. Het resultaat was vaak dat die code over verschillende pagina’s verspreid en herhaald werd, waardoor aanpassingen en onderhoud steeds moeilijker werd. In dit Whitebook bespreken we de structuur en de mogelijkheden van een Apex plug-in.

Typen plug-ins

In Apex kennen we vier typen plug-ins:

  • Dynamic action
    Dynamic actions kunnen gebruikt worden om het scherm te manipuleren zonder dat de pagina herladen hoeft te worden. Denk hierbij aan het tonen en verbergen van items indien er een bepaalde conditie optreedt in het scherm, of een standaardactie voor effecten op het scherm. Deze actions kunnen ook rechtstreeks in de pagina geconfigureerd worden, maar als plugin is herbruikbaarheid gegarandeerd.
  • Item
    Item type plug-ins maken het mogelijk een eigen user-interface component te maken die door Apex developers gemakkelijk in een pagina te plaatsen zijn, net als de standaard typen die al aanwezig zijn. Een goed voorbeeld is een slider-control of een eigen implementatie van een Multi-selectlijst.
  • Region
    Zoals de naam al impliceert, stuurt een Region plug-in het gedrag en opmaak opmaak van een gedeelte van de pagina, zoals bij voorbeeld een kaart, RSS-feed of een proces dat sub-regions converteert in tabbladen.
  • Process
    Voert een PL/SQL proces met geconfigureerde parameters uit. Webservicecalls, log procedure of een proces dat Javascript genereert om het scherm te manipuleren wanneer de pagina geladen is.

Configuratie

Het maken van een Apex plug-in bestaat grofweg uit twee onderdelen. Enerzijds moet de plug-in declaratief geconfigureerd worden. Allereerst moet een naam en een interne naam opgegeven worden. De laatste zou uniek moeten zijn voor elke ontwikkelde plug-in , dus een goede praktijk is hiervoor een namespace notatie te gebruiken zoals nl.whitehorses.plugin.myplugin.

Om onderhoud te beperken kan gebruik gemaakt worden van het publish- en subscribemechanisme wat we al kennen van templates in Apex. De plugin kan in een aparte applicatie onderhouden worden en bij wijzigingen gepushed worden zodat alle plug-ins op een uniforme manier werken.

Atrributen

Per type plug-in zijn er een aantal standaardattributen. Het activeren van deze attributen zorgt ervoor dat bij gebruik van een plug-in item op een pagina hiervoor om input gevraagd wordt. Voorbeelden zijn een LOV definitie, formaatmasker of element attributen.
Daarnaast kunnen eigen attributen worden gedefinieerd voor verschillende typen zoals selectlists, PL/SQL code, SQL-query en referenties naar page items.

Een eigen attribuut heeft een aantal opties waaronder de scope. De scope kan ofwel "component" ofwel "Application" zijn. Indien voor de laatste optie wordt gekozen kan de waarde van het attribuut maar 1 keer in de applicatie \opgegeven worden. Dit kan vooral handig zijn wanneer er bijvoorbeeld een uniforme tekst gebruikt moet worden voor alle controls van de bettreffende plug-in (anders zou per instance van het plug-in item een waarde opgegeven kunnen worden).

Standaard- en custom attributen in de plug-in definitie
Standaard- en custom attributen in de plug-in definitie

Daarnaast zijn er standaardopties om aan te geven of het attribuut verplicht is en afhankelijk van het type attribuut kan de waarde meegenomen worden in de XLIFF-vertaling van de Apex applicatie.
Een hele mooie aanvulling is dat ook afhankelijkheden in attributen kunnen worden vastgelegd. Hiermee kan op basis van de opgegeven waarde van een vorig attribuut al dan niet beslist worden of input voor het het huidige attribuut gewenst is.
In de code van de plug-in kunnen deze waarden gebruikt worden om de uiteindelijke werking van de plug-in te sturen. De waarden van de attributen worden uitgelezen door de P_ITEM.ATTRIBUTE_{NN}- inputvariable van de standaardinterface uit te lezen.

Implementatie

Daarna volgt de daadwerkelijke implementatie. De PL/SQL broncode hiervan kan in de Apex Builder geplaatst worden, maar betere performance wordt bereikt wanneer deze in een database functie , al dan niet in een package, ondergebracht wordt.

De plug-in moet een vooraf vastgestelde interface implementeren voor bijvoorbeeld het genereren van run-time code of validatie van een item type. Deze interface bevat parameters van de PL/SQL types die terug te vinden zijn in de package specificatie APEX_PLUGIN. Een verschil met de early adopter releases van Apex 4.0 is dat nu het type apex_plugin.t_page_item_render_result teruggegeven moet worden.

Plug-in definitie
Plug-in definitie

Om bij het opbouwen van de pagina onze code te laten uitvoeren, moet de plug-in geconfigureerd worden welke PL/SQL-functies hiervoor verantwoordelijk zijn..
In het geval van een item type plugin zijn dit de functies om de generatie, validatie en eventueel AJAX-calls af te handelen. Dit gebeurt door in de sectie “Callbacks” de verantwoordelijke databasefuncties te benoemen.

Het opgeven van een functie voor de validatie van de plug-in is optioneel, maar zou altijd aanwezig moeten zijn. Hiermee wordt voorkomen dat door middel van javascript of andere manipulatie een item type plugin een onrechtmatige waarde krijgt en opgeslagen wordt. In het geval van een slider die een minimumwaarde van 0 heeft en een maximum waarde van 100 bij 10 stappen zou dus gecontroleerd moeten worden of de waarde die opgestuurd wordt naar de server ook binnen dit bereik ligt. Het is prettig dat standaardvalidaties onderdeel kunnen zijn van de plug-in zelf, zodat in de builder hiervoor geen aparte maatregelen moeten worden genomen.

Het principe van de AJAX calls is niet echt veranderd ten opzichte van de vorige Apex versies. Vanuit Javascript wordt een call gemaakt naar een proces dat de data voor het control teruggeeft. Het verschil is echter, dat er vroeger een on-demand proces gemaakt moest worden, maar nu kan het proces in de plug-in code ondergebracht worden. Door het gebruik van de PL/SQL functie apex_plugin.get_ajax_identifier, en deze identifier in de Javascript code van de plugin te genereren kan het control gekoppeld worden aan het dataproces. De URL naar het dataproces is dan niet meer APPLICATION_PROCESS={procesnaam} maar PLUGIN={ajax identifier}. De plug-in zorgt dan voor de executie van het dataproces zoals geconfigureerd in de “Callbacks” sectie van de Apex Builder.

Statische files

Statische files, zoals Javascripts en CSS-files, kunnen opgeladen worden als onderdeel van de plugin. Deze files worden dan runtime toegevoegd aan de html van de pagina.
Het toevoegen van een statische javascript-file gebeurt door in de plugin de procedure APEX_JAVASCRIPT.ADD_LIBRARY te gebruiken. Deze procedure zorgt ervoordat bij meerdere instances van de plug-in op dezelfde pagina maar eenmalig de referentie naar file in de HTML output komt.

apex_javascript.add_library ( 
   p_name           => 'myplugin.js'
,  p_directory      => p_plugin.file_prefix 
,  p_version        => null
,  p_skip_extension  => true
);

De substitutievariable #PLUGIN_PREFIX# wijst naar de plaats waarin de statische files zijn opgeslagen bij de plugin in de database. Wanneer een plug-in file een mimetype “text” heeft, kan binnen deze file ook #PLUGIN_PREFIX# gebruikt worden om bijvoorbeeld in een css-bestand een plaatje op te halen als achtergrond.
Wanneer we in de source van de pagina kijken zien we dat de plug-in files geladen worden via de wwv_flow_file_mgr.get_file procedure, die al bekend was voor het downloaden van Application- of workspace files:

wwv_flow_file_mgr.get_file?p_plugin_id=662805144232129096&p_security_group_id=1286315371635912&p_file_name=someplugin.js

Indien de performance optimaal moet zijn kan er gekozen worden voor een vaste locatie, of de #IMAGE_PREFIX# substitutie, die standaard naar /i/ wijst. Ook tijdens het ontwikkelen van de Javascript library van de plug-in of de CSS-files is het handig de prefix naar een locatie te laten verwijzen waar rechtstreeks wijzigingen op de files aangebracht kunnen worden: dit voorkomt veelvuldig opladen in de Apex file repository.

jQueryUI

Apex 4.0 heeft standaard de beschikking over de jQuery en jQueryUI Javascript libraries. De laatste bestaat uit een aantal user interface componenten en effecten die gebruikt kunnen worden om de user experience van een applicatie naar een hoger niveau te tillen. Daarnaast zijn er op het internet ontelbare zogenaamde “widgets” te vinden die volgens de jQueryUI interfacestandaard werken. Deze widgets kunnen als basis dienen voor de plugin, waarbij met minimale inspanning goede resultaten behaald kunnen worden.

Conclusie

De mogelijkheid om in Apex plug-ins gebruiken kan een enorme produktiviteitswinst bieden. De mogelijkheden zijn eindeloos en zijn slechts beperkt door de fantasie van de ontwikkelaar. Een bijkomend voordeel is dat codefragmenten om de user interface te sturen niet meer gemaakt hoeven te worden tijdens de ontwikkeling van de applicatie. De werking van componenten zijn eenduidig vastgelegd en kunnen declaratief, zonder schrijven van extra code of javascript ingebed worden in de pagina’s. Dit betekent dat ontwikkelaars die minder bedreven zijn in bijvoorbeeld Javascript, toch gebruik kunnen maken van de kracht van frameworks als jQuery en jQueryUI.

De mogelijkheid om een plug-in als op zichzelf staand pakketje te exporteren maakt het ook gemakkelijker om de code ervan te onderhouden en veilig te stellen. Let wel op dat wanneer de implementatie van de plug-in in een package of databasefunctie ondergebracht is, deze standaard niet mee geëxporteerd wordt. De code zal dan verplaatst moeten worden naar de “PL/SQL source” in de plug-in configuratie.
De community is in ieder geval enthousiast Het heeft nu al geresulteerd in een flink aantal sites waar ontwikkelaars hun kunsten tentoon hebben gesteld. Een waarschuwing is echter op zijn plaats, de kwaliteit van sommige plugins laat te wensen over. Desondanks zijn er meer dan genoeg aanknopingspunten om te leren om een eigen plug-in te maken.

Referenties

Waardering:
 

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.