Die Intersult Taglib ist eine Facelet-Taglib mit einigen nützlichen Tags für die Entwicklung von JEE-Applikationen unter JSF und Seam.
Der wohl interessanteste Tag in der Intersult Bibliothek com.intersult.ui ist der meta-Tag. Was ist ein Meta-Tag? Das ist ein Tag zur Konstruktion einer Component mittels einer XHTML-Datei mit vollwertigem Id- und Rendering-Verhalten. Der Bau eigener Components wird damit zum Kinderspiel, da in der Regel kein Java-Code mehr geschrieben werden braucht.
Beispiel Infobox#
Als Aufgabenstellung soll ein Facelet gebaut werden, das auf einer XHTML-Seite wie folgt eingebaut werden kann:
<i:info id="info" value="Dies ist die Infobox"/>
Die Implementierung erfolgt als Facelet in der Datei info.xhtml:
<ui:composition>
<i:meta bindId="id" var="comp" rendered="#{empty rendered or rendered}">
<s:graphicImage id="#{comp.id}" url="#{empty img ? '/images/information.png' : img}"
onmouseover="$('#{comp.clientId}-text').style.display = '';"
onmouseout="$('#{comp.clientId}-text').style.display = 'none';"/>
<s:span id="#{comp.id}-text" style="display: none; position: fixed; background-color: yellow; padding: 3px;">
<h:outputText value="#{value}"/>
</s:span>
</i:meta>
</ui:composition>
Die *.taglib.xml enthält folgenden Eintrag, um das Facelet zu registrieren:
<tag>
<tag-name>info</tag-name>
<source>/tag/info.xhtml</source>
</tag>
Was passiert hier? Der meta-Tag generiert eine Component-Id und stellt diese unter der unter var angegebenen Variable (hier comp) zur Verfügung. Diese Variable hat zwei Properties:
- id Innerhalb des meta-Tags kann hier eine Id abgerufen werden und als Zuweisung für eine andere Komponente verwendet werden. Diese Id darf natürlich nur einmal verwendet werden, da die im Component-Tree von JSF eindeutig sein muss. Werden mehrere Ids gebraucht, können diese mit #{comp.id}-suffix erzeugt werden. Die Id wird von JSF generiert, falls von außen keine Id-Variable mit bindId übergeben wurde oder die Variable einen leeren Wert ergibt. Im Gegensatz zum Zuweisen normaler Ids darf bindId="id" benutzt werden, auch wenn die Variable 'id' nicht zugewiesen oder einen Leerstring enthält. Der meta-Tag arbeitet dann ganz normal mit der generierten Id.
- clientId Innerhalb des meta-Tags kann hier die clientId, als die im HTML-Code tatsächlich heraus generierte Id abgefragt werden. Dies wird vom JavaScript-Code gebraucht.
Was kann dieser Tag?
- Id-Parameter: Die Id der Facelet-Component verhält sich identisch zu einem in Java entwickelten Tag. Wird keine Id angegeben, wird über den JSF-Mechanismus eine Id generiert. Optional kann eine Id angegeben werden, diese wird dann auch verwendet.
- clientId: Es steht immer die clientId zur Verfügung, sodass beliebiger Code in JavaScript hinzugefügt werden kann. Dieser Code kann ohne Konflikte an mehreren Stellen auf einer XHTML-Seite included werden kann.
- rendered-Attribut: Das Attribut rendered ist etwas tricky, da die Component sowohl gerendered werden muss, wenn rendered nicht angegeben wurde (Prüfung mit empty) als auch wenn rendered="true" angegeben wurde.
- img-Attribut: Das Attribut img ist ebenfalls optional. Der ?-:-Operator prüft, ob das img angegeben wurde, wenn nicht wird als Default-Wert '/images/information.png' eingesetzt. Andernfalls wird der angegebene Wert verwendet.
Als Luxus kann noch eine TLD im Verzeichnis META-INF abgelegt werden, sodass z.B. der Content Assist von Eclipse eine Code Completion für die eben gebaute Component vornehmen kann:
<tag>
<name>info</name>
<tag-class/>
<body-content>empty</body-content>
<description>Renderes a info icon with popup div.</description>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
<description>Text for popup.</description>
</attribute>
<attribute>
<name>img</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>java.lang.String</type>
<description>Optional: Image for the info icon.</description>
</attribute>
<attribute>
<name>rendered</name>
<description>
Flag indicating whether this component (and its children) should be rendered. Expressions must evaluate
to a boolean.
</description>
</attribute>
</tag>
Einschränkungen: Der meta-Tag ist nur mit State-Saving auf dem Server getest, d.h. ohne Serialisierung. Wenn es Probleme gibt, in der web.xml folgende Parameter setzen:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
Dieser Tag ist eine Erweiterung des inputHidden aus der Tomahawk Bibliothek um das Property "from". Selbst in Seam-Projekten werden Informationen aus der Oberfläche, insbesondere bei Listen, als URL-Parameter übergeben. Dies unterwandert das Konzept der Komponenten, da der URL-Parameter dann auf Page-Ebene behandelt wird. Dafür muss zusätzlicher Code geschrieben werden, vermindert die Wartbarkeit und erhöht die Fehleranfälligkeit durch Inkonsistenzen zwischen URL-Parameter und Code-Verarbeitung. Des Weiteren widerstrebt es dem Konzept von meaningful URL und läd zur Manipulation ein.
Beispiel#
Folgendes Beispiel zeigt den Einsatz des inputHidden-Tags für ein Steuerelement eines Paging-Mechanismus einer Liste. Es ist ein Mini-Formular mit einem commandLink und dem inputHidden, das den gewünschten Index direkt auf die Liste schreibt.
<h:form>
<h:commandLink action="redirect">#{index}</h:commandLink>
<i:inputHidden value="#{list.firstResult}" from="#{index}"/>
</h:form>
Statt dem h:commandLink kann natürlich auch ein a4j:commandLink benutzt werden.
Installation#
Manuell#
Folgende Bibliotheken sind im Stand vom 07.06.2009:
Maven2 Integration#
Wesentlich einfacher gestaltet sich die Integration der com.intersult.ui-Bibliothek, wenn ein Build mit
Maven2 durchgeführt werden kann:
<project>
...
<dependencies>
...
<dependency>
<groupId>com.intersult</groupId>
<artifactId>com.intersult.ui</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
...
<repositories>
...
<repository>
<id>intersult-repository</id>
<name>Intersult Repository</name>
<url>http://repository.intersult.com/repository</url>
</repository>
...
</repositories>
...
</project>