This page (revision-41) was last changed on 13-May-2015 13:30 by Dieter Käppel

This page was created on 16-Mar-2014 00:11 by Dieter Käppel

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
41 13-May-2015 13:30 26 KB Dieter Käppel to previous

Page References

Incoming links Outgoing links

Version management

Difference between version and

At line 3 removed 3 lines
!!!Inhalt
[{TableOfContents numbered=true}]
At line 42 removed one line
* Tags sind leichtgewichtig und kosten sehr wenig Performance. Die Hemmschwelle soll gering sein, selbst einfache Funktionen als Tags zu implementieren.
At line 44 changed one line
!!Übersicht der Konzepte
!!Geplanter Umfang
At line 49 removed one line
* __XML-Text:__ Text und Whitespace wird As-Is in den Output Stream kopiert um die Kontrolle über das Ergebnis zu maximieren. Es ist an jeder Stelle möglich, dieses Verhalten beliebig durch Tags zu ändern.
At line 53 removed 6 lines
* __EL-Methods:__ Method Expressions können genauso übergeben werden wie Value Expressions. Composite Tags und Native Tags können Value- und Method-Expressions gleichermaßen als Parameter entgegennehmen, unabhängig wo diese übergeben wurden, ohne extra Code.
* __XML-Schema:__ [Xplate] kommt mit XML-Schema (auch XSD genannt) aus, um die Tags zu beschreiben. Es sind keine besonderen Taglibs erforderlich, da Tags einfach mit dem entsprechenden XML-Namespace annotiert werden. Zum Unterstützen des Content-Assist von Entwicklungsumgebungen wird aus den Tags ein XML-Schema generiert.
* __Redirect:__ Seitenwechsel werden ausschließlich mit Redirect durchgeführt. Forwards bei denen der URL nicht mit der angezeigten Seite übereinstimmen sollen erst gar nicht eingeführt werden.
* __Navigation:__ Es gibt eine Navigation, mit der Page-Wechsel und Parameter-Übergabe gesteuert werden können.
* __Client-Ids:__ Jeder Tag bekommt automatisch eine Client-Id. Zur Einfachheit wird die gesamte Taghierarchie aneinandergefügt, getrennt durch den Tag.ID_SEPARATOR (Doppelpunkt). Falls ein Tag nicht explizit durch das Attribut "id" mit einer Id versehen wird, bekommt er seinen Index im Parent-Tag zugewiesen. Also ist der erste Tag "parent:0", der zweite "parent:1" und so weiter.
* __Asynchronous Processing:__ Asynchrone Bedienung des Browsers im XHTML-Code integriert aufgrund spezieller Tags. Submits asynchron an den Server geschickt, im Fall eines Fehlschlags wird informiert.
At line 63 removed 440 lines
!!Performance
Da [Xplate] auf Effizienz getrimmt ist, werden die Seiten sehr schnell verarbeitet. Sicher kommt es nicht nur auf die View-Schicht an, wenn es um die Performance einer Anwendung geht. Umgekehrt leidet die Performance einer sonst gut aufgebauten Application durch eine ineffiziente View-Schicht.
[Xplate] läd die Seiten beim ersten Zugriff. Und weil die Seiten statisch sind, werden sie für konsequente Aufrufe gecacht:
{{{
INFO 2014-04-20 16:46:40,373 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 1110 ms
INFO 2014-04-20 19:12:37,290 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 11 ms
INFO 2014-04-20 19:12:39,209 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 10 ms
INFO 2014-04-20 19:12:40,105 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 17 ms
INFO 2014-04-20 19:12:41,074 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 17 ms
INFO 2014-04-20 19:12:41,887 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 12 ms
INFO 2014-04-20 19:12:42,677 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 8 ms
INFO 2014-04-20 19:12:43,368 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 8 ms
INFO 2014-04-20 19:12:44,036 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 8 ms
INFO 2014-04-20 19:12:44,662 com.intersult.xplate.servlet.XplateServlet processing of '/index.xhtml' took 7 ms
}}}
!!!Konfiguration
[Xplate] kann durch eine Datei konfiguriert werden. Diese hat den Namen xplate-config.xml und befindet sich entweder in WEB-INF/xplate-config.xml oder META-INF/xplate-config.xml. Die Variante WEB-INF ist natürlich möglich, wenn Xplate über das XplateServlet in einem Servlet-Container gestartet wurde.
Die Konfiguration enthält unter anderem auch eine [XmlConfig|Abraxas#XMLKonfiguration], die über das XML-Element xmlConfig erreichbar ist.
Die Konfiguration kann so aussehen:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<xplate-config>
<xmlConfig>
<pretty>false</pretty>
</xmlConfig>
<resolver>com.intersult.xplate.spring.SpringBeanElResolver</resolver>
</xplate-config>
}}}
[Xplate] unterstützt folgende Konfigurationsparameter:
||Parameter||Beschreibung
|xmlConfig|Die [XML-Config|Abraxas] für das Parsen / Generieren von XML, also auch XHTML.
|resolver|Implementierungen von javax.el.ELResolver, die für das Auflösen von EL-Ausdrücken verwendet werden.
|resource|Implementierungen von com.intersult.xplate.api.Resource, die verwendet werden um Xplate-Pages zu laden.
|lifecycleConfig|Zu durchlaufende com.intersult.xplate.lifecycle.Phase für jeweilige HTTP-Methoden (z.B. GET, POST).
|nameStrategy|Implementierungen von com.intersult.xplate.api.NameStrategy, die das Generieren der Id's von Tags festlegen. Default ist com.intersult.xplate.config.IndexNameStrategy, der Id's mit ':' separiert und fehlende Id's durch deren Child-Index im Parent auffüllt.
|applicationState|Entweder DEVELOPMENT (default) oder PRODUCTION, um einige Optimierungen vorzunehmen.
!!!Tags
Mit [Xplate] werden die Basis-Tags ausgeliefert, die für den allgemeinen Gebrauch von HTML, Workflow und Metadaten nützlich sind.
!!Meta Tags
Meta-Tags sind Bestandteil von [Xplate] und unter dem XML-Namespace http://intersult.com/xplate/meta und haben das Prefix meta.
!Include Tag
Mit dem Include-Tag kann ein Fragment in eine bestehende Page eingebunden werden:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
<meta:include viewId="/fragment.xhtml"/>
</html>
}}}
Ein derartiges Fragment kann so aussehen:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<meta:tag xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
xmlns:flow="http://intersult.com/xplate/flow"
xmlns:h="http://intersult.com/xplate/html">
<p>
<h:text value="Included Tag"/>
</p>
</meta:tag>
}}}
__Hinweis:__ der Tag <meta:tag> stellt zum einen die Möglichkeit zur Verfügung, Namespaces anzugeben (xmlns:...), zum anderen sorgt er für ein einheitliches Interface.
Der Include-Tag kann auch Tags includen, die per EL-Expression referenziert werden. Auf diese Weise können HTML-Snippets als Parameter an Composite-Tags übergeben werden:
{{{
<flow:for id="row" value="#{container.elements}" var="element">
<p>
<meta:include tag="#{element}"/>
</p>
</flow:for>
}}}
Der For-Tag iteriert die Child-Elemente des Container-Tags, sodass die Variable "element" jeweils ein Element enthält. Der Include-Tag fügt jeden Tag aus der Iteration ein. Der Aufruf kann dann so aussehen:
{{{
<app:table>
<h:text value="Container Tag 1"/>
<h:text value="Container Tag 2"/>
<h:text value="Container Tag 3"/>
</app:table>
}}}
Möchte man nur eine Tag-Liste einfügen, geht dies auch mit dem Attribut "tags":
{{{
<meta:include tags="#{container.elements}"/>
}}}
!Attribute Tag
Attribute Tags sind eine erweiterte Möglichkeit, Werte für ein Attribut des Parent Tags zu erzeugen:
{{{
<h:text>
<meta:attribute name="value" value="Attribute value"/>
</h:text>
}}}
Der Tag <meta:attribute> unterstützt Attribute für das Zusammensetzen von Strings. Grundsätzlich sind diese Attribute für das implementieren der API AttributeProvider gedacht, können bei Bedarf auch als Attribute an den AttributeTag übergeben werden:
||Name||Default||Beschreibung
|finalizer|null|String mit dem dieser Teil des zusammengesetzten Attributs abgeschlossen wird.
|separator|" "|String zum Abtrennen einzelner Zeichenketten.
|postfix|null|Der String wird hinter dem letzten Teil der Zeichenkette angehängt.
__Hinweis:__ Attribut Tags sind generisch, das heißt sie können ohne extra Code oder Aufwand überall verwendet werden. Dies schließt Attribute von XHTML-Tags, sowie Pass-Through-Attribute ein.
!Param Tag
Der Param-Tag wird verwendet, um Parameter an andere Tags zu übergeben. Viele der mitgelieferten Tags unterstützten <meta:param>. Bei den entsprechenden Tags ist beschrieben, wozu im Einzelnen die Param-Tags nützlich sind.
Hier ein Beispiel für die Übergabe von Request-Parametern bei einer Navigation:
{{{
<h:submit value="Test" action="#{testBean.action}">
<flow:navigate viewId="/other.xhtml">
<meta:param name="test" value="test param"/>
</flow:navigate>
</h:submit>
}}}
Dies ist gleichbedeutend mit dem Java-Code:
{{{
Navigation navigation = XplateContext.instance().getNavigation();
navigation.getParams().put("test", "test param");
navigation.setViewId("/other.xhtml");
}}}
Mit <meta:param> können auch Tags (also im Endeffekt ein XHTML-Snippet) übergeben werden. Dies ist nützlich, wenn man einen Composite-Tag (oder native) erstellt und bestimmte Bereiche für den Container flexibel halten möchte:
{{{
<app:table id="table">
<meta:param name="someTags">
<h:text value="Tag Param 1"/>
<h:text value="Tag Param 2"/>
<h:text value="Tag Param 3"/>
</meta:param>
<h:text value="Container Tag 1"/>
<h:text value="Container Tag 2"/>
<h:text value="Container Tag 3"/>
</app:table>
}}}
Die Implementierung sieht dann so aus:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<meta:tag xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
xmlns:flow="http://intersult.com/xplate/flow"
xmlns:h="http://intersult.com/xplate/html">
<table>
<tr>
<flow:for id="header" value="#{container.paramMap.someTags.elements}" var="element">
<th>
<meta:include tag="#{element}"/>
</th>
</flow:for>
</tr>
<tr>
<flow:for id="row" value="#{container.elements}" var="element">
<td>
<meta:include tag="#{element}"/>
</td>
</flow:for>
</tr>
</table>
</meta:tag>
}}}
!Script Tag
Mit diesem Tag kann einem anderen Tag ein oder mehrere JavaScript-Fragmente zugeordnet werden:
{{{
<h:submit value="Ajax">
<meta:script name="onclick" value="alert('Test');"/>
</h:submit>
}}}
__Hinweis:__ Der Tag verhält sich ählich dem AttributeTag <meta:attribute> mit Vorbelegung von separator=" ", finalizer=";" und postfix="return false;".
!Resource Tag
Der Tag <meta:resource> liefert einen Resource-Pfad für ein Attribut. Damit können Bilder, JavaScripts, CSS-Styles und andere Dateien ausgegeben werden:
{{{
<img>
<meta:resource name="src" value="/word.png"/>
</img>
}}}
!!HTML Tags
[Xplate] behandelt Tags einheitlich. Alle Tags unterstützen EL-Expressions, Meta Tags etc. [Xplate] liefert daher nicht für jeden HTML-Tag einen eigenen Tag mit. Es reicht völlig aus, den Namespace in der Page anzugeben und enthaltene Tags in die Page zu schreiben:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8"/>
<title>test</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
}}}
Darüber hinaus bietet [Xplate] für bestimmte HTML-Elemente eine erweiterte Unterstützung an. Diese sind unter dem Namespace http://intersult.com/xplate/html mit dem Prefix h verfügbar.
!Text Tag
Mit diesem Tag ist das Ausgeben von Text möglich. Generell kann auch Text zwischen die Tags geschrieben werden, wie es bei XML gemeinhin üblich ist. Allerdings unterstützt der Text-Tag das dynamische Gestalten der Seite:
{{{
<h:text value="#{testBean.text}"/>
}}}
__Hinweis:__ Wenn XML-Text inline geschrieben wird, entsteht intern ein Tag vom Typ <h:text>.
!Form Tag
Zum Einfügen eines Form-Tags kann der Tag <h:form> verwendet werden, weil dieser automatisch eine Client-Id generiert, sowie die Kommunikation mit dem Server unterstützt:
{{{
<h:form id="form">
...
</h:form>
}}}
!Submit Tag
Um ein Formular abzuschicken, kann der Submit-Tag verwendet werden:
{{{
<h:form id="form">
<h:submit id="test" value="Test" action="#{testBean.action}"/>
</h:form>
}}}
__Erklärung:__ Das Attribut action kann eine Method-Expression enthalten, die beim Abschicken des Formulars durch den Knopf aufgerufen wird.
!Script Tag
Mit dem Script-Tag kann eine Java-Script Resource eingebunden werden:
{{{
<h:script src="/xplate/ajax.js"/>
}}}
Der Tag ist eigentlich eine Kurzform von:
{{{
<script type="text/javascript">
<meta:resource name="src" value="/xplate/ajax.js"/>
</script>
}}}
__Hinweis:__ Nicht zu verwechseln mit dem Script-Tag der Meta-Tags.
!!Flow Tags
Flow-Tags stehen unter dem Namespace http://intersult.com/xplate/flow und dem Prefix flow zur Verfügung.
!If Tag
Mit dem If Tag ist ein bedingtes Abarbeiten der untergeordneten Tags möglich:
{{{
<flow:if test="#{true}">
<h1>Hello World!</h1>
</flow:if>
}}}
!For Tag
Mit dem For-Tag ist eine Vervielfältigung von Tag-Inhalten möglich. Weil der Komponentenbaum in [Xplate] zustandsfrei ist, ist dabei kein erhöhter Speicherbedarf erforderlich. Die zu wiederholenden Komponenten werden beim Ausführen von Operationen auf dem Komponentenbaum kurzerhand durchiteriert.
{{{
<html>
...
<flow:for id="loop" value="#{testBean.list}" var="element">
<h:text value="#{tag.clientId} -> #{element}"/>
</flow:for>
...
</html>
}}}
Ergebnis:
{{{
0:1:loop:0:0 -> eins
0:1:loop:1:0 -> zwei
0:1:loop:2:0 -> drei
}}}
Der Tag <flow:for> unterstützt auch das Attribut "test", mit dem die iterierten Elemente gefiltert werden. Im Gegensatz zu einem verschachtelten <flow:if> wird für die ausgefilterten Elemente kein Index erzeugt. Je nach Situation kann das eine oder andere von Vorteil sein.
!Navigation Tag
Die Navigation kann auch durch einen Flow-Tag durchgeführt werden:
{{{
<h:submit value="Test" action="#{testBean.action(testBean.text)}">
<meta:set value="#{testBean.text}" target="#{testBean.target}"/>
<flow:navigate viewId="/other.xhtml"/>
</h:submit>
}}}
Dem Navigation Tag können auch Parameter mit dem Tag <meta:param> übergeben werden:
{{{
<flow:navigate viewId="/other.xhtml">
<meta:param name="test" value="test param"/>
</flow:navigate>
}}}
!!!Composite Tags
In [Xplate] können Composite Tags gebaut werden. Diese können dann wir andere Tags in einer Page verwendet werden. Composite Tags werden angesprochen, indem der Namespace mit http://intersult.com/xplate/tag/<prefix>/ beginnt. Die entsprechenden XHTML-Dateien werden dann unter <base-path>/tag/<prefix>/ zugegriffen.
{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
xmlns:flow="http://intersult.com/xplate/flow"
xmlns:h="http://intersult.com/xplate/html"
xmlns:app="http://intersult.com/xplate/tag/app">
...
<app:composite/>
...
</html>
}}}
Der Composite Tag befindet sich dann unter /tag/app/composite.xhtml:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<meta:tag xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
xmlns:flow="http://intersult.com/xplate/flow"
xmlns:h="http://intersult.com/xplate/html">
<p>
<h:text value="Composite Tag"/>
</p>
</meta:tag>
}}}
!!Attribute
Composite-Tags können auch Attribute festlegen, die der Container übergeben kann:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<meta:tag xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
xmlns:flow="http://intersult.com/xplate/flow"
xmlns:h="http://intersult.com/xplate/html">
<meta:param name="message" value="No message specified"/>
<h:text value="#{message}/>
</meta:tag>
}}}
Der Tag wird dann so aufgerufen:
{{{
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:meta="http://intersult.com/xplate/meta"
xmlns:flow="http://intersult.com/xplate/flow"
xmlns:h="http://intersult.com/xplate/html"
xmlns:app="http://intersult.com/xplate/tag/app">
...
<app:composite message="Hello tag!"/>
}}}
__Hinweis:__ Da auf den Container mit #{container} zugegriffen werden kann, könnten die Attributwerte auch mit #{container.attributes.<name>.evaluated} erreicht werden. Definitionen mit <meta:param> sind null, wenn der Container das Attribut nicht angibt und erlauben einen Default-Wert. Des Weiteren beschreiben die Param-Angaben das Interface des Composite-Tags.
!!!Native Tags
[Xplate] wurde designed für das unkomplizierte Implementieren von Tags. Native Tags, also Tags im Java-Code zu schreiben, ist jedoch in den meisten Fällen gar nicht erfordedrlich, da die Composite Tags derart flexibel sind, dass damit 90% aller Anforderungen abgedeckt werden. Für spezielle Aufgaben können natürlich Tags in Java implementiert werden, dies ist ebenfalls sehr einfach:
{{{
@XmlNamespace(value = "http://intersult.com/xplate/test", localPart = "hello", prefix = "test")
public class TextTag extends Tag {
public TextTag(TagConfig config) {
super(config);
}
public void renderBegin() {
XplateContext.instance().getWriter().writeText("Hello World!");
}
}
}}}
__Hinweis:__ Ein Native-Tag braucht nirgends registriert zu werden. Es existiert keine Tag-Lib, die Annotation ist völlig ausreichend, damit [Xplate] den Tag findet. Der Namespace http://intersult.com/xplate/test legt den Xml-Namespace fest, unter welchem der Tag später in die XHTML-Datei eingebunden wird. Ein Namespace kann dabei viele Tags enthalten, sodass Tags gruppiert werden können und die Page übersichtlich bleibt. Der Wert "prefix" gibt an, unter welchen Prefix der Tag später eingefügt wird und localPart den eigentlichen Tag-Namen.
Der Tag wird dann so benutzt:
{{{
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:test="http://intersult.com/xplate/test">
...
<test:hello/>
...
</html>
}}}
__Erklärung:__ Im äußeren Tag <html> der Seite wird der Namespace http://intersult.com/xplate/test unter dem Präfix "test" eingebunden. Der Tag <test:hello> steht nun auf der Seite zur Verfügung, sowie andere Tags die für den gleichen Namespace vorhanden sind.
!!!Navigation
Die Navigation in [Xplate] ist über den XplateContext zugreifbar, mit context.getNavigation(). Die Klasse "Navigation" stellt das Basisobjekt dar, um einen Wechsel der View durchzuführen. Auf der Client (Web-Browser Seite) bedeutet dies, dass auf eine andere Web-Page gesprungen wird (andere URL) und gegebenenfalls ein HTTP Redirect durchgeführt wird.
Die Navigation kann direkt durch im Java-Code einer aufgerufenen Action-Methode genutzt werden:
{{{
public void action(String message) {
Navigation navigation = XplateContext.instance().getNavigation();
navigation.getParams().put("message", message);
navigation.setViewId("/other.xhtml");
}
}}}
__Hinweis:__ Die Navigation wird meist bequemer durch den [Navigation-Tag|Xplate#Navigation Tag] durchgeführt.
!!!Expressions
In den Expressions stehen Spring-Beans durch den SpringBeanElResolver, Application-, Session- und Request-Context und die zusätzlich konfigurierten Resolvern zur Verfügung. Darüber hinaus liefert [Xplate] weitere spezifische Variablen:
||Variable||Beschreibung
|this|Der aktuelle Tag, in dem sich die EL-Expression befindet
|context|Der XplateContext, ein Short-Cut für context.tagContext.tagFrame.tag
|composite|Der aktuelle Composite- oder Include Tag. Tatsächlich wird einfach der oberste Tag der aktuellen Page referenziert. Es ist ein Short-Cut für context.tagContext.compositeTagFrame.tag
|container|Der aktuelle Composite- oder Include-Parent Tag. Es ist ein Short-Cut für context.tagContext.containerTagFrame.tag