I'm creating a custom tag in my application but for some reason it's not working, I followed this tutorial (which is the clearest one that I found to put here as reference) but, like other tutorials that I did, my custom tag ins not called.
WEB-INF/example.taglib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
version="2.0">
<namespace>http://example.com/facelettags</namespace>
<tag>
<tag-name>hello</tag-name>
<handler-class>example.MenuTagHandler</handler-class>
</tag>
</facelet-taglib>
My tag handler class
package example;
public class MenuTagHandler extends TagHandler {
private String name = "Anonymous";
public MenuTagHandler(TagConfig config) {
//other constructor stuff
Logger.getLogger(MenuTagHandler.class).info("aaaa");
//other constructor stuff
}
@Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
Logger.getLogger(MenuTagHandler.class).info("aaaa");
UIComponentBase c = new UIComponentBase() {
@Override
public void encodeEnd(FacesContext ctx) throws IOException {
ResponseWriter w = ctx.getResponseWriter();
w.write(String.format(
"<p>Hello %s! I am FaceletTag.</p>",
name));
}
// abstract method in base, must override
@Override
public String getFamily() {
return "com.example.facelettag.test";
}
};
parent.getChildren().add(c);
}
}
My .xhtml file
<?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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:exampler="http://example.com/facelettags" >
<example:hello />
</ui:composition>
The rendered result is
<example:hello></example:hello>
Unfortunately nothing is printed in the log, does anyone have any idea on why it is not calling the tag handler?
If the *.taglib.xml
file is not inside the /META-INF
of a JAR file which is placed in /WEB-INF/lib
and thus won't be automatically detected and registered (like as in case of all those 3rd party JSF component libraries like PrimeFaces, RichFaces, etc), then you'd need to manually register it in webapp's web.xml
as follows:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/example.taglib.xml</param-value>
</context-param>
Unrelated to the concrete problem, please note that what you've so far is not a custom component. This is a custom taghandler which in turn creates an anonymous instance of UIComponentBase
. This is not necessarily the "best" practice. If you do not need to perform any actions related to the component tree during view build time, then you do not need the taghandler part at all. Just create a fullworthy @FacesComponent
class instead.