JSF facelet taglib backed by a UI component
November 08, 2011 20:55:00 Last update: November 21, 2011 18:19:44
In the simple taglib example, I used a tag handler class to implement a taglib. This is an example to implement a taglib with a UI component. The purpose is to use a custom tag to split a string and print each part in a separate paragraph, i.e., print
with custom tag
These are the files:
How to use:
<p>john</p> <p>steve</p> <p>mike</p>
with custom tag
<my:foreach>:
<my:foreach var="who" value="john steve mike"> <p>#{who}</p> </my:foreach>
These are the files:
-
pom.xml<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>component-tag</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>component-tag</name> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-api</artifactId> <version>2.1.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>2.2.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project>
-
src/main/java/com/example/UIForeash.java:package com.example; import java.io.IOException; import java.util.Iterator; import java.util.Map; import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.component.UIComponentBase; import javax.faces.context.FacesContext; public class UIForeach extends UIComponentBase { public static final String COMPONENT_TYPE = "com.example.Foreach"; public static final String COMPONENT_FAMILY = "com.example"; // data object private Object value; // variable name private String var; public UIForeach() { } public String getFamily() { return COMPONENT_FAMILY; } public String getVar() { return this.var; } public void setVar(String var) { this.var = var; } // value is set only when the value attribute does not contain EL. // otherwise, setValueExpression is called with the EL value. public Object getValue() { if (this.value == null) { ValueExpression vex = this.getValueExpression("value"); if (vex != null) { return vex.getValue(getFacesContext().getELContext()); } } return this.value; } public void setValue(Object value) { this.value = value; } public void encodeChildren(FacesContext ctx) throws IOException { if (!isRendered()) { return; } String[] values = ((String) this.getValue()).split("\\s+"); for (int i = 0; i < values.length; i++) { Map<String, Object> attrs = ctx.getExternalContext().getRequestMap(); attrs.put(this.var, values[i]); Iterator<UIComponent> it = this.getChildren().iterator(); while (it.hasNext()) { UIComponent c = it.next(); c.encodeAll(ctx); } } } public boolean getRendersChildren() { return true; } }
-
src/main/resources/META-INF/faces-config.xml:<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd" version="2.1"> <component> <component-type>com.example.Foreach</component-type> <component-class>com.example.UIForeach</component-class> </component> </faces-config>
-
src/main/resources/META-INF/foreach.taglib.xml:<?xml version="1.0" encoding="UTF-8"?> <facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee" version="2.0"> <namespace>http://www.example.com/ns/mytags</namespace> <tag> <tag-name>foreach</tag-name> <component> <component-type>com.example.Foreach</component-type> </component> </tag> </facelet-taglib>
How to use:
- Put the JAR file generated by the above project in the
WEB-INF/libfolder of the web app. If the web app is a Maven project, just add the taglib project as a dependency:<dependency> <groupId>com.example</groupId> <artifactId>component-tag</artifactId> <version>1.0</version> </dependency>
- In the facelet page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:my="http://www.example.com/ns/mytags"> <h:head> <title>Facelets Taglib Demo</title> </h:head> <h:body> <div id="header"><h2>Facelets Taglib Demo</h2></div> <div id="content"> <my:foreach var="who" value="john steve mike"> <p>#{who}</p> </my:foreach> </div> </h:body> </html>