I'm in the process of writing a set of custom PrimeFaces components, using PrimeFaces 5.0 and running inside JBoss EAP 6.2.
I'm first building a custom component that renders a bog-standard html <input/>; tag as an initial proof of concept.
The short version of my problem:
With my namespace defined as st, the tag <st:input/> renders not an <input/> tag... but <st:input/> </st:input>.
The long version:
- I have two projects set up for this. The set of PrimeFaces custom components lives inside a maven project built with NetBeans. The jar need to be redistributable, and I deploy this onto my app server.
The second project is a showcase for the custom components.
- The custom component project is set up in the following way:
2.1 in the faces-config.xml:
<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">
<name>myfacestest</name>
</faces-config>
2.2 In myfacestest.taglib.xml I define my input tag:
<?xml version="1.0"?>
<facelet-taglib version="2.0"
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-facelettaglibrary_2_0.xsd"
id="st">
<namespace>http://org.myfacestest.faces/ui</namespace>
<tag>
<tag-name>input</tag-name>
<component>
<component-type>org.myfacestest.faces.Input</component-type>
<renderer-type>org.myfacestest.faces.InputRenderer</renderer-type>
</component>
</tag>
</facelet-taglib>
2.3 In Input.java (my custom component) I do the following:
@FacesComponent(value = Input.COMPONENT_TYPE)
@ResourceDependencies(
{@ResourceDependency(library = "primefaces", name = "jquery/jquery.js"),
@ResourceDependency(library = "primefaces", name = "primefaces.js"),
@ResourceDependency(library = "myfacestest", name = "input.js"),
@ResourceDependency(library = "myfacestest/css", name = "input.css")})
public class Input extends UIInput implements Widget {
public static final String COMPONENT_TYPE = "org.myfacestest.faces.Input";
public static final String COMPONENT_FAMILY = "org.myfacestest.faces.components";
public String getFamily() {
return COMPONENT_FAMILY;
}
...
2.4 The renderer for this component contains the following:
@FacesRenderer(componentFamily = Input.COMPONENT_FAMILY, rendererType = InputRenderer.RENDERER_TYPE)
public class InputRenderer extends CoreRenderer {
public static final String RENDERER_TYPE = "org.myfacestest.faces.components.InputRenderer";
@Override
public void decode(FacesContext context, UIComponent component) {
String submittedValue = (String) context.getExternalContext().getRequestParameterMap().get(component.getClientId(context));
((Input) component).setSubmittedValue(submittedValue);
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
this.encodeMarkup(context, (Input) component);
this.encodeScript(context, (Input) component);
}
private void encodeMarkup(FacesContext context, Input input) throws IOException {
ResponseWriter writer = context.getResponseWriter();
//Object value = input.getValue() != null ? input.getValue() : 0;
writer.startElement("input", input);
writer.writeAttribute("id", input.getClientId(), null);
writer.writeAttribute("name", input.getClientId(), null);
writer.endElement("input");
}
private void encodeScript(FacesContext context, Input component) throws IOException {
String clientId = component.getClientId();
String widgetVar = component.resolveWidgetVar();
WidgetBuilder wb = getWidgetBuilder(context);
wb.initWithDomReady("Input", widgetVar, clientId);
wb.finish();
}
...
2.5 Since this jar is deployed as a module on my application server, I have my-faces-test-0.1.jar (named via the Maven POM) deployed in the following folder inside jboss:
modules/system/layers/base/org/myfacestest/faces/main
with the following inside my module.xml:
<module xmlns="urn:jboss:module:1.1" name="org.myfacestest.faces">
<resources>
<resource-root path="my-faces-test-0.1.jar"/>
</resources>
<dependencies>
</dependencies>
</module>
- My showcase project is set up in the following way.
3.1 Since I deploy this to my jboss app server, I've added the following in my jboss-deployment-structure.xml:
<module name="org.myfacestest.faces"/>
3.2 I have an xhtml that uses the tag as follows:
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:st="http://org.myfacestest.faces/ui"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
3.3 In the same file, inside the <h:body> and <h:form> elements:
<st:input/>
Given this setup, why would the custom component not render? There is nothing in my jboss logs, even with logging levels set to debug.
<module name="org.myfacestest.faces" export="true" meta-inf="export"/>- Kenneth Clark