JSF facelet taglib backed by a UI component 

Joined:
08/13/2009
Posts:
164

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
<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:
  1. 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>
    

  2. 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;
        }
    }
    

  3. 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>
    

  4. 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:
  1. Put the JAR file generated by the above project in the WEB-INF/lib folder 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>
    

  2. 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>
    

Share |
| Comment  | Tags