tags:

views:

470

answers:

1

I need to convert a Date to a String within a page (I dont want to add loads of toStrings to my domain model so adding to the bean is not an option).

<ice:graphicImage value="bean.image" title="#{bean.date}"/>

The above code works but formats the Date in the default format...I would like to change the format.

I have tried using JSTL fmt but this doesnt seem to be compatible with Facelets http://stackoverflow.com/questions/2371329/jsf-convert-dates-for-title-attribute . Is there a workaround for this (doesnt have to use JSTL)?

Thanks.

+4  A: 

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"&gt;

<facelet-taglib>
    <namespace>http://example.com/el/formatter&lt;/namespace&gt;
    <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.

BalusC
Which versions of Facelets does this work for?
Drew
@Drew: The answer was targeted on JSF 1.2 + Facelets 1.x, but should work for JSF 2.0 as well. The `param-name` of `facelets.LIBRARIES` is deprecated in 2.0 (but should still work) and needs to be replaced by `javax.faces.FACELETS_LIBRARIES`. If you have any problems, ask a new question and include the errors.
BalusC
@BalusC Will do, thanks.
Drew