Intersult Taglib
This is version . It is not the current version, and thus it cannot be edited.
Back to current version   Restore this version

Die Intersult Taglib ist eine Facelet-Taglib mit einigen nützlichen Tags für die Entwicklung von JEE-Applikationen unter JSF und Seam.

Tag "meta"#

Der wohl interessanteste Tag von "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. Dabei sind Features enthalten, wie Component-Id-Generierung, JSF-Client-Id-Access aus Javascript, Javascript- und CSS-Header-Insertions, Resource-Exposition aus dem JAR, Text-Interpolation aller Text-Resources etc.

Attribute#

Der meta-Tag unterstützt einige Attribute:

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 useId="#{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 kann dieser Tag?

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>

Tag "clear"#

Bei verschachtelter Anwendung des meta-Tags werden Facelet-Parameter unkontrolliert in innere Facelets weiter gegeben. Insbesondere gefährdet ist ui:insert, da hier Facelets generisch eingefügt werden.

Dies findet bei ui:include und ui:param ebenso statt, wie bei der Definition von Tags in der Facelets-Taglib. Um dies zu verhindern, steht der Intersult clear-Tag zur Verfügung:

    <i:clear var="id,label">
        <ui:insert/>
    </i:clear>

Was geschieht hier? Der clear-Tag verhindert die weitere Propagierung der UIParameter (also auch Tag-Attribute) "id" und "label".

Beispiel inputGroup#

Das Beispiel soll den Nutzen des clear-Tags verdeutlichen. Zunächst wird ein Tag eingesetzt, der die Gruppierung von Eingabefeldern vornimmt:
    <i:inputGroup label="Gruppe">
        <i:inputText id="test" value="#{test}"/>
    </i:inputGroup>

Die Implementierung der inputGroup ist wie folgt:

	<i:meta var="comp" useId="#{id}" rendered="#{empty rendered or rendered}">
		<fieldset id="#{comp.clientId}">
			<legend>
				<h:outputText value="#{label}"/>
			</legend>
			<i:clear var="id,label">
				<ui:insert/>
			</i:clear>
		</fieldset>
	</i:meta>

Die Implementkerung von inputText:

<i:meta var="comp" useId="#{id}" rendered="#{empty rendered or rendered}">
	<h:panelGrid>
	        <h:inputLabel for="#{comp.id"} value="#{empty label ? 'Default' : label}"/>
		<h:inputText id="#{comp.id}" value="#{value}"/>
		<i:message id="#{comp.id}-message" for="#{comp.id}"/>
	</h:panelGrid>
</i:meta>

Der Tag inputText enthält wieder eine Referenz auf die Variable Label. Ohne Verwendung des clear-Tag wäre diese nun auf den äußeren Wert gesetzt, da der inputGroup-Tag den Wert nach innen hinein propagiert.

Tag "inputHidden"#

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.

ClassPathResource#

Mit dieser Klasse kann ein Resource-Path direkt aus dem ClassLoader in die Web-Applikation exponiert werden. Eine JAR-Datei die sich in einem WAR befindet, hat zunächst keine Möglichkeit auf einen URL zu mappen. Innerhalb eines Facelets aus einer Taglib können zwar URLs erzeugt werden mit h:graphicImage, h:outputLink etc., jedoch keine Dateien als Linkziel exponiert. Die Klasse ClassPathResource exponiert einen Resource-Path mittels eines Eintrag in die components.xml:
<component name="taglibResource" class="com.intersult.ui.util.ClassPathResource" scope="application">
    <property name="resourcePath">/taglib</property>
    <property name="classPath">/resource</property>
</component>

Die Resourcen sind dann zugreifbar mit:

<t:stylesheet path="#{taglibResource.get('/style.css')}"/>

Alle Resources mit Mime-Type text/* werden dabei interpoliert. Insbesondere CSS-Stylesheets und Javascript-Dateien die durch den meta-Tag geladen werden, können dabei mit EL-Expressions versehen werden. Dies ist z.B. interessant beim Styles vom Typ "background-image", da hier über "url(...)" auf eine Resource zugegriffen wird.

Installation#

Manuell#

Folgende Bibliotheken sind im Stand vom 07.06.2009. Daher sind nicht alle oben beschriebenen Features enthalten. Es wird dringend der im nächsten Abschnitt beschriebene Einsatz von Maven2 empfohlen.

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>