Facelets and JSTL (Converting a Date to a String for use in a field)

Indeed, you cannot use the “good old” JSTL in Facelets anymore the way as you would do in JSP. Facelets only supports a limited subset of JSTL (and has it already builtin, the JSTL JAR file is in fact superfluous).

You’re forced to write a custom tag or better, a custom EL function, for this purpose.

Let’s assume that we want to be able to do this:

<ice:graphicImage ... title="#{fmt:formatDate(bean.date, 'yyyy-MM-dd')}" />

Roughly said thus the same what the JSTL <fmt:formatDate> tag can do, but then in flavor of an EL function so that you can use it everywhere without the need for an “intermediating” tag. We want it to take 2 arguments, a Date and a SimpleDateFormat pattern. We want it to return the formatted date based on the given pattern.

First create a final class with a public static method which does exactly that:

package com.example.el;

import java.text.SimpleDateFormat;
import java.util.Date;

public final class Formatter {

    private Formatter() {
        // Hide constructor.
    }

    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

}

Then define it as a facelet-taglib in /META-INF/formatter.taglib.xml:

<?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://example.com/el/formatter</namespace>
    <function>
        <function-name>formatDate</function-name>
        <function-class>com.example.el.Formatter</function-class>
        <function-signature>String formatDate(java.util.Date, java.lang.String)</function-signature>
    </function>    
</facelet-taglib>

Then familarize Facelets with the new taglib in the existing /WEB-INF/web.xml:

<context-param>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>/META-INF/formatter.taglib.xml</param-value>
</context-param>

(note: if you already have the facelets.LIBRARIES definied, then you can just add the new path commaseparated)

Then define it in the Facelets XHTML file as new XML namespace:

<html 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:fmt="http://example.com/el/formatter"
    ...
>

Finally you can use it as intended:

<ice:graphicImage ... title="#{fmt:formatDate(bean.date, 'yyyy-MM-dd')}" />

Hope this helps.

Leave a Comment