Pesquisa personalizada

2009/11/07

Icefaces+Facelets: Customizing the basic html (XHTML) tags using a simple Render Kit extension

Alright, the life, at least my life, isn't easy. But after fourteen hours, finally, I know how to do a simple task: insert the xmlns attribute into the final code of the html tag generated by Icefaces+Facelets couple.

I know that are several ways to insert this attribute, but I just want to play it using the JSF Render Kit. I don't want to filter the stream, or output the tag, or anything else. The render kit should be the way.

I just want to write:
   1:<?xml version='1.0' encoding='UTF-8' ?> 
   2:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   3:<html xmlns="http://www.w3.org/1999/xhtml"
   4:      xmlns:ui="http://java.sun.com/jsf/facelets"
   5:      xmlns:c="http://java.sun.com/jstl/core"
   6:      xmlns:h="http://java.sun.com/jsf/html"
   7:      xmlns:ice="http://www.icesoft.com/icefaces/component"
   8:      >
   9:    <body>
  10:
  11:        <ui:composition template="/WEB-INF/tmp/template.xhtml">
  12:
  13:            <ui:param name="hasLeftSection" value="false"/>
  14:            <ui:param name="pageDescription" value="${ArtistPage.pageDescription}"/>
  15:
  16:            <ui:define name="pageTitle">${ArtistPage.pageTitle}</ui:define>
  17:            <ui:define name="extraHeader">
  18:                <link rel="canonical" href="${ArtistPage.canonicalUrl}" />
  19:            </ui:define>
  20:
  21:            <ui:define name="body">
But the xmlns="http://www.w3.org/1999/xhtml" attribute is always trimmed by icefaces/facelets (maybe it's a simple thing to configure using com.icesoft.faces.facelets.D2DFaceletViewHandler or com.sun.facelets.compiler.Compiler - But I didn't investigate them to know).

I inspected the Icefaces code and I saw that it uses the renderer from com.icesoft.faces.renderkit.dom_html_basic.XMLRenderer to write out (to render) the most xhtml tags, like html, body, head, title etc. So, after a little test, was easy to write my own render to add the attribute that I need (or any other, also). The render code is:

   1:package com.solvoj.sondaletra.faces;
   2:
   3:import com.icesoft.faces.component.UIXhtmlComponent;
   4:import com.icesoft.faces.renderkit.dom_html_basic.XMLRenderer;
   5:import java.io.IOException;
   6:import java.util.Iterator;
   7:import java.util.Map;
   8:import javax.faces.component.UIComponent;
   9:import javax.faces.context.FacesContext;
  10:import javax.faces.context.ResponseWriter;
  11:
  12:/**
  13: * 
  14: * @author Marcio Wesley Borges
  15: */
  16:public class MyXMLRenderer extends XMLRenderer {
  17:
  18:    @Override
  19:    public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
  20:        final UIXhtmlComponent xhtmlComponent = (UIXhtmlComponent) uiComponent;
  21:        final ResponseWriter writer = facesContext.getResponseWriter();
  22:        final String tag = xhtmlComponent.getTag();
  23:        writer.startElement(tag, xhtmlComponent);
  24:
25: if ("html".equals(tag)) { 26: writer.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml", null); 27: }
28: 29: final Iterator attributeIterator = xhtmlComponent.getTagAttributes().entrySet().iterator(); 30: while (attributeIterator.hasNext()) { 31: Map.Entry attribute = (Map.Entry) attributeIterator.next(); 32: writer.writeAttribute((String) attribute.getKey(), attribute.getValue(), null); 33: } 34: } 35: 36:} 37:
Also, we need to configure the application to use this render above while Icefaces will be playing with xhtml tags, so just add the following lines at the faces-config.xml file of your web application:
   1:<?xml version='1.0' encoding='UTF-8'?>
   2:<faces-config version="1.2"  xmlns="http://java.sun.com/xml/ns/javaee"
   3: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_1_2.xsd">
   4:    <application>
   5:        <locale-config>
   6:            <default-locale>pt_BR</default-locale>
   7:            <supported-locale>pt_BR</supported-locale>
   8:            <supported-locale>en</supported-locale>
   9:        </locale-config>
  10:        <message-bundle>com.solvoj.sondaletra.web.Bundle</message-bundle>
  11:        <view-handler>com.icesoft.faces.facelets.D2DFaceletViewHandler</view-handler>
  12:    </application>
13: <render-kit> 14: <render-kit-id>ICEfacesRenderKit</render-kit-id> 15: <render-kit-class>com.icesoft.faces.renderkit.D2DRenderKit</render-kit-class> 16: <renderer> 17: <component-family>com.icesoft.faces.XhtmlComponent</component-family> 18: <renderer-type>com.icesoft.domXhtml</renderer-type> 19: <renderer-class>com.solvoj.sondaletra.faces.MyXMLRenderer</renderer-class> 20: </renderer> 21: <renderer> 22: <component-family>com.icesoft.faces.XhtmlComponent</component-family> 23: <renderer-type>com.icesoft.faces.Xhtml</renderer-type> 24: <renderer-class>com.solvoj.sondaletra.faces.MyXMLRenderer</renderer-class> 25: </renderer> 26: </render-kit>
It's enough to produce the resultant html page that I expect:
   1:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   2:<html id="document:html" lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
   3:<head>
The same principe can be used to add or change any attribute that you need to any xhtml tag using Icefaces/Facelets.

Labels: , , , , , ,