29 September 2009

Create Custom JSF Facelet Component

Because it took me a while to find the right steps I don't want to hold back my findings:

1. Create a facelet taglib:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://unibe.ch/tags</namespace>
    <tag>
        <tag-name>publikation</tag-name>
        <component>
            <component-type>unibe.PublikationComponent</component-type>
        </component>
    </tag>
</facelet-taglib>


2. Add taglib to web.xml

<context-param>
  <param-name>facelets.LIBRARIES</param-name>
  <param-value>/WEB-INF/facelets/publikation.taglib.xml</param-value>

</context-param>

3. Add component to faces-config.xml

<component>
  <component-type>unibe.PublikationComponent</component-type>
  <component-class>ch.unibe.search.ui.PublikationComponent</component-class>
</component>


4. Implement Component. (I just extended UIOutput for my purposes):

public class PublikationComponent extends UIOutput {

    private PublikationTO getPublikation() {
        ValueExpression ve = getValueExpression("item");
        if (ve != null) {
            return (PublikationTO) ve
                    .getValue(getFacesContext().getELContext());
        } else {
            return null;
        }
    }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        final ResponseWriter writer = context.getResponseWriter();
        PublikationTO publikation = this.getPublikation();
        if (publikation != null) {
            writer.startElement("p", null);
            for (AutorTO autor : publikation.getAutoren()) {
                if (autor.getId() == null) {
                    writer.writeText(autor.getName() + ", "
                            + autor.getVorname(), null);
                    writer.writeText(" ", null);
                } else {
                    writer.startElement("a", null);
                    writer.writeAttribute("href", "result.jsf?autorId="
                            + autor.getId(), null);
                    writer.writeText(autor.getName() + ", "
                            + autor.getVorname(), null);
                    writer.endElement("a");
                    writer.writeText(" ", null);
                }
            }
            writer.writeText("(" + publikation.getJahr() + ") ", null);
            writer.writeText(publikation.getTitel(), null);
            writer.endElement("p");
        } else {
            writer.write("Fehler");
        }
    }
}


5. Use your component

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:unibe="http://unibe.ch/tags" template="/template.xhtml">
    <ui:define name="content">
        <h1>Resultate</h1>
        <h:dataTable id="items" value="#{search.results}" var="result">
            <h:column>
                <unibe:publikation item="#{result}" />   
            </h:column>
        </h:dataTable>
        <h:messages layout="table" style="font-size:12px;" />
    </ui:define>
</ui:composition>


That's it ;-)

Keine Kommentare: