Application-Properties mittels SSJS auslesen

Um Serverseitig zu ermitteln, welche Dojo-Version verwendet wird, kann folgender Code verwendet werden:

<xp:label id="lblJSVersion">
   <xp:this.value><![CDATA[#{javascript:var reqParam = 
      new com.ibm.xsp.context.RequestParameters ( facesContext );
      reqParam.getLibraryVersion()}]]>
   </xp:this.value>
</xp:label>

[Code liefert unter 8.5.3 in der Standard-Einstellung „1.6.1“ zurück]

Um zu ermitteln, ob die Clientseitige Validierung aktiviert bzw. deaktiviert ist, liefert die Methode isClientSideValidation() das gewünschte Ergebnis:

<xp:label id="lblIsCSValidation">
   <xp:this.value><![CDATA[#{javascript: var reqParam = 
      new com.ibm.xsp.context.RequestParameters ( facesContext );
      reqParam.isClientSideValidation()}]]>
   </xp:this.value>
</xp:label>

[Liefer true bzw. false zurück, je nach Einstellung der Datenbank]

Welche Komprimierungseinstellung verwendet wird, kann so ermittelt werden:

<xp:label id="lblCompressMode">
   <xp:this.value><![CDATA[#{javascript:var reqParam = 
      new com.ibm.xsp.context.RequestParameters ( facesContext );
      reqParam.getCompressMode()}]]>
   </xp:this.value>
</xp:label>

[Liefert z.B. „gzip-nolength“ zurück, je nach Einstellung der Datenbank]

Ob überhaupt Dojo Verwendung findet, bzw. die XSPDojoLite.js-Version, liefert folgender Code:

<xp:label id="lblJsLibrary">
   <xp:this.value><![CDATA[#{javascript:var reqParam = 
      new com.ibm.xsp.context.RequestParameters ( facesContext );
      var jsLib = reqParam.getJsLibrary();

      switch(jsLib){
      case 1:
         return "dojo";
      break;
      case 2:
         return "lite";
      break;
      default:
         return "none";
      break;
      }}]]>
   </xp:this.value>
</xp:label>
Veröffentlicht unter Allgemein, Dojo Toolkit, Java, Java Script, Server, ServerSide JavaScript, XPages | Verschlagwortet mit , , , , , , | Schreib einen Kommentar

Performance-Tuning (4): Fein-Tuning von xsp.resources.aggregate

Mit Domino 8.5.3 wurde eine neue Option eingeführt, mit der automatisch verschiedene Ressourcen-Dateien vom Server vor der Auslieferung an den Browser zusammengefasst werden. Dadurch läßt sich die Performance einer Web-Applikation deutlich erhöhen, denn zum Einen werden dadurch weniger Anfragen vom Browser an den Server gesendet,  zum Anderen wird der Browser nicht unnötig „blockiert“, da sich die Anzahl der zu ladenden Ressourcen deutlich reduziert (siehe dazu RFC 2616)

In folgendem Artikel ist die neue Option xsp.resources.aggregate detailliert beschrieben, doch es gibt noch ein paar undokumentierte Optionen, mit denen sich das Verhalten der XPages-Engine genauer steuern läßt.

Dafür muß zu aller erst die Funktion aktiviert sein, das xsp.properties-File also folgende Zeile beinhalten:

xsp.resources.aggregate=true

Dann kann mit den folgenden Optionen das Verhalten für die einzelnen zu aggregierenden Ressourcen individuell festgelegt werden (Standardmäßig werden alle Ressourcen zusammen gefasst).

  • xsp.resources.aggregate.dojo

Wenn false, werden die Javascript-Libraries des Dojo Toolkits ausgeschlossen.

  • xsp.resources.aggregate.css

Schließt die Standard-CSS-Dateien aus, wenn false.

  • xsp.resources.aggregate.appcss

Schließt die CSS-Dateien der Applikation aus, wenn false.

  • xsp.resources.aggregate.appjs

Wenn false, werden die JavaScript-Libraries der Applikation ausgeschlossen.

Veröffentlicht unter Allgemein, CSS, Dojo Toolkit, Java Script, Performance, Server, Web, XPages, XSP | Verschlagwortet mit , , , , , , , , | Schreib einen Kommentar

Performance-Tuning (3): XSPClientLite.js

Im xsp.properties-File gibt es einen undokumentierten Parameter, mit der sich eine abgespeckte Version der JavaScript-Routinen im Client einbinden läßt: die XSPClientLite.js. Die Library wird bei einer Standard-Installation von der IBM mitgeliefert.

Hierbei handelt es sich um eine deutlich kleinere Version der XSP Routinen, allerdings auch mit einem kleineren Funktionsumfang: Es fehlen z.B. die Routinen für Partial Refreshs, auf die aber je nach Anwendungsfall auch verzichtet werden kann. Hingegen sind z.B. die Clientseitige Validierung enthalten, oder aber die Methoden für das Auf-/Zuklappen von Sections, uvm.

Durch die kompakte Größe von nur 11 KB (rund 2/3 kleiner als die „normale“ XSPClient-Library) läßt sich aber die Ladezeit verringern bzw. der Seitenaufbau der XPage beschleunigen; ob die Library die nötigen Funktionen bietet, die man auf der XPage verwenden möchte, muß aber im Einzelfall getestet werden.

Um die Library zu verwenden, muß im xsp.properties-File folgender Eintrag hinzugefügt werden:

xsp.client.script.libraries=lite

Dadurch wird die XSPClientLite.js anstelle der XSPClientDojo.js in der XPage eingebunden und vom Client verwendet.

Veröffentlicht unter Allgemein, Dojo Toolkit, HTML, Java Script, Performance, Web, XPages, XSP | Verschlagwortet mit , , , , , , , , , | 2 Kommentare

Quick-n-Dirty: Kontrolle über $$OpenDominoDocument

Wird ein Dokument via $$OpenDominoDocument.xsp geöffnet, muß nicht zwangsläufig eine passende XPage mit gleichem Namen der gespeicherten Form vorhanden sein, um das Dokument anzuzeigen.

Auch über das xsp.properties-File läßt sich das Verhalten steuern. Durch folgende Eintrag kann einer Form eine bestimmten XPage zugeordnet werden:

xsp.domino.form.xpage.formname=xpage

Wichtig ist, daß der Name der Form klein geschrieben sein muß. Um der Form TestForm (bzw. dem Wert des Form-Feldes) die XPage xptest.xsp zuzuordnen, muß der Eintrag so aussehen:

xsp.domino.form.xpage.testform=xptest
Veröffentlicht unter Allgemein, Web, XPages | Verschlagwortet mit , , , , , | Schreib einen Kommentar

Quick-n-Dirty: Dojo-Version auf Datenbankebene setzen

Will man unterschiedliche Dojo-Versionen einsetzen, ist dies nicht nur auf Serverebene möglich. Auch für jede einzelne Datenbank läßt sich die gewünschte Dojo-Version über das xsp.properties-File vorgeben.

Zwar greift die Manipulation der Dojo-Version im xsp.properties-File nur auf dem Domino-Server (die installierte Version vorausgesetzt)…

xsp.client.script.dojo.version=1.5.0

…fügt man allerdings folgende Zeile in das xsp.properties-File in der Datenbank hinzu, wird die entsprechende Dojo-Version geladen:

xsp.client.script.dojo.path=/domjs/dojo-1.5.0

[Der Pfad /domjs entspricht dem Verzeichnis \domino\js im Notes Data-Verzeichnis]

Um die korrekte Einbindung zu überrpüfen, kann die aktuelle Dojo-Version im Client mit der Funktion dojo.version ausgegeben werden.

<xp:scriptBlock id="scriptBlockDJVersion"
    value="XSP.addOnLoad( function(){ alert( dojo.version ); } );">
</xp:scriptBlock>

P.S. Leider setzt die XPages-Engine immer einen Slash vor den Pfad der eingebundenen Library, so dass die Angabe einer URL leider nicht funktioniert.

Veröffentlicht unter Allgemein, Dojo Toolkit, Java Script, Server, Web, XPages | Verschlagwortet mit , , , , , , , | Ein Kommentar

Quick-n-Dirty: Manipulation von UI Komponenten via SSJS (2)

Ist einer der Items durch einen Mehrfachwert definiert worden,  muss das entsprechende Item anders behandelt werden. Eine Definition wie folgt…

<xp:comboBox id="comboBox1">
   <xp:selectItems>
      <xp:this.value><![CDATA[#{javascript:
         var vItem = new java.util.Vector();
         vItem.add("A|1");
         vItem.add("B|2");
         vItem.add("C|3");
         vItem
      }]]></xp:this.value>
   </xp:selectItems>
</xp:comboBox>

…ist auch intern als Array zu behandeln. Eine Funktion, die mit beiden Item-Typen umgehen kann (auch im Mix), kann dann wie folgt aufgebaut sein:

function getSelectableValues( id ) {
   var ComboBox = getComponent( id );
   var ChildrenList:java.util.ListIterator;
   ChildrenList = ComboBox.getChildren().listIterator()
   while (ChildrenList.hasNext()) {
      var Child = ChildrenList.next();     
      if( typeof( Child ) == 'com.ibm.xsp.component.UISelectItemsEx' ){
         var hlp = Child.getValue();
         for( var i=0; i< hlp.length; i++ ){
            print( hlp[i].getLabel() + "|" + hlp[i].getValue() );
            hlp[i].setLabel("ABC" + i );
            hlp[i].setValue("123" + i );
            hlp[i].setDisabled(true);
         }
         Child.setValue(hlp);
      }
      if( typeof( Child ) == 'com.ibm.xsp.component.UISelectItemEx' ){
         print( Child.getItemLabel() + "|" + Child.getItemValue() );
      }
   }
}

getSelectableValues( 'comboBox1' );

[Fett: Wenn Änderungen am Mehrfachwert-Item vorgenommen werden, muss das Item nach der Bearbeitung mit „setValue()“ erneuert werden]

Die Namen der Methoden sind ohne „Item“ zu verwenden, z.B. setItem() anstelle von setItemValue().

Veröffentlicht unter Allgemein, Java, Java Script, Server, ServerSide JavaScript, XPages | Verschlagwortet mit , , , , , , | Ein Kommentar

Quick-n-Dirty: Manipulation von UI Komponenten via SSJS

Serverseitig lassen sich die die Items einer Auswahlbox (z.B. eine Combobox, Listboxen, usw.) auslesen und ggf. manipulieren. Hier eine Combobox mit drei Items:

<xp:comboBox id="comboBox1">
   <xp:selectItem itemLabel="A" itemValue="1"></xp:selectItem>
   <xp:selectItem itemLabel="B" itemValue="2"></xp:selectItem>
   <xp:selectItem itemLabel="C" itemValue="3"></xp:selectItem>
</xp:comboBox>

Um via SSJS die Items der UI Komponente und deren Eigenschaften zu erhalten, kann man wie folgt darauf zu greifen:

function listSelectableValues( id ) {
   var cBox = getComponent( id );
   var cList:java.util.ListIterator;
   cList = ComboBox.getChildren().listIterator();
   while (ChildrenList.hasNext()) {
      var c = ChildrenList.next()
      print ("Label: " + c.getItemLabel() );
      print ("Value: " + c.getItemValue() );
      print ("IsDisabled: " + c.isDisabled() ); 
   }
}

listSelectableValues( 'comboBox1' );

Auf der Serverkonsole werden nun die Eigenschaften der drei Items ausgegeben.

Natürlich lassen sich die Items auch manipulieren:

<xp:button value="Label" id="button1">
   <xp:eventHandler event="onclick" submit="true"
      refreshMode="partial" refreshId="comboBox1">
      <xp:this.action><![CDATA[#{javascript:
         var cBox = getComponent( 'comboBox1' );
         var cBoxChildren = cBox.getChildren();
         var cBoxChild = cBoxChildren.get(0);

         // --- disablen
         cBoxChild.setItemDisabled(true);

         // --- das Label ändern
         cBoxChild.setItemLabel("DISABLED");

         // --- den Value ändern
         cBoxChild.setItemValue("disabled");
      }]]></xp:this.action>
      </xp:eventHandler>
</xp:button>

Der Button führt einen PartialRefresh auf die ComboBox aus, deaktiviert das erste Item (es ist nicht mehr selektierbar) und ändert sowohl das Label als auch den Wert des ersten Items.

Veröffentlicht unter Allgemein, Java, Java Script, Server, ServerSide JavaScript, XPages | Verschlagwortet mit , , , , , , | Schreib einen Kommentar

Der Fluch des Partial Refreshs (2)

Anscheinend liest jemand bei Google meinen Blog und reagierte auf meinen Artikel:

Heise Newsticker: Googlebot erfasst künftig mehr dynamische Seiteninhalte

Jetzt müssen nur noch die Browser-Hersteller einlenken…

Veröffentlicht unter HTML, Server, Web, XPages | Verschlagwortet mit , , , , | Schreib einen Kommentar

Quick-n-Dirty: Text ohne -Tags

Verwendet man ein <xp:text>-Element, wird dieser von der XPages-Engine immer mit einem <span>-Tag gerendert:

So wird aus folgendem Beispiel

<xp:text value="Hello world!" id="computedField1" ></xp:text>

der folgende HTML-Code generiert:

<span id="view:_id1:computedField1">Hello world!</span>

Um den überflüssigen <span>-Tag loszuwerden, muß nur die Id des Elements weggelassen werden; ein disableTheme muß bei der Verwendung von Themes hinzugefügt werden:

<xp:text disableTheme="true" value="Hello world!" />

Und schon generiert die XPage-Engine nur den Text „Hello world!“.

P.S.: Die neue Option disableOutputTag (8.5.3) ist dafür nicht geeignet; damit soll der Output komplett unterbunden werden und ist z.B. für RepeatControls sinnvoll. Die Ausgabe wird dann komplett unterdrückt (also auch kein „Hello world!“).

Veröffentlicht unter Allgemein, HTML, Web, XPages | Verschlagwortet mit , , , , | Schreib einen Kommentar

Der Fluch des Partial Refreshs

Bei der Architektur von Web 2.0-Applikationen gibt es ein paar Besonderheiten zu beachten, die es im „alten“ Web nicht gegeben hat, denn der konzeptionelle Ansatz, durch die AJAX-gestützten Abfragen nur einzelne Segmente einer Webseite zu laden (und diese Abfragen im Hintergrund durchzuführen), kann sich zu einem grundlegenden Problem entwickeln: Zum Einen leidet die Benutzbarkeit einer Applikation, denn das Verlinken der Inhalte ist nicht möglich, zum Anderen können Suchmaschinen die Seiten nicht oder nur noch teilweise indizieren.

Zum Erläuterung des Problems hier eine kleine Denksportaufgabe: Wie verlinke ich eine bestimmte Seite, z.B. die zweite Seite des XPages-Developer-Forums? Das Verlinken eines Beitrages stellt kein Problem dar, aber die zweite Seite zu verlinken ist nicht möglich.

Im „guten alten Web“, bei dem die Webseiten immer komplett geladen und die Optionen zum Großteil über URL-Parameter gesteuert werden, existiert als Nebeneffekt automatisch eine Möglichkeit, ein Bookmark zu setzen, wie z.B. hier: Domino 8.5 Forum, Seite 2, Kategorisierung eingeklappt.

Auch ist es für die Bots der Suchmaschinen viel einfacher, allen Verlinkungen innerhalb einer Webseite zu folgen, denn hinter dem Link verbirgt sich eine (neue) Seite, die es ebenfalls zu indizieren gilt.

Im Falle von XPages-Applikationen gibt es diese Möglichkeiten nicht Out-Of-The-Box. Man kann hier getrost vom „Fluch des Partial Refreshes“ sprechen kann, denn so muß die Google-Spezifikation für durchsuchbare AJAX-Applikationen in die XPages händisch eingebaut werden. Und das für jeden Pager, jede Aktion, jeden Serverseitigen Link…

Um die Funktionalität der Bookmarks wieder herzustellen, kann der URL Hash „angezapft“ werden; dieser muß jedoch via Javascript gesetzt bzw. ausgewertet werden. Eine Hilfe hierfür bietet der Dojo Toolkit mittels dojo.hash. Die Variante der URL Manipulation OHNE ein Neuladen der Webseite ist auch mit älteren Browsern möglich; mit HTML 5 ist die Möglichkeit geschaffen worden, die URL wirklich manipulieren zu können. Eine nette Implementierung findet sich auch unter https://github.com/balupton/history.js. Die HTML 5 – Variant e ist Serverseitig auswertbar, da sich die URL-Parameter ohne Reload der Seite setzen lassen (und im HTTP Request übertragen werden). Aber leider ist diese Funktionalität nicht in älteren Browser verfügbar.

Will man kompatibel bleiben, bleibt also nur der Weg über den URL-Hash. Im Falle eines Seitenaufrufs über ein Bookmark muß der Hash-Part der URL im Client ausgewertet werden, denn der Hash wird NICHT via HTTP Request übertragen (und damit auch nicht Serverseitig auswertbar). Erst nach dieser Auswertung können diese Informationen z.B. mit einen Partial Refresh übertragen werden.

Eine Beispiel-Implementation ist in Arbeit und wird bei Gelegenheit veröffentlicht.

Veröffentlicht unter Dojo Toolkit, HTML, Java Script, JSF, Server, ServerSide JavaScript, Web, XPages | Verschlagwortet mit , , , , , , , , | 2 Kommentare