Extending Trinidad’s default renderers

Once in a while there is a question on the MyFaces user/dev list about how to extend the default rendering of the components, like decorating <tr:inputText /> (for instance).

It’s not hard, but it requires some steps, like creating renderer class(es) and registering these new renderers with the Trinidad renderkit. This demonstrates a very simple example on extending the <tr:inputText />. This tag has a attribute for short descriptions (shortDesc=”blah”), now imagine you need to decorate that inside the renderer, so that the page developer can’t change the extra text (for what ever reason…).

For that you need two Java classes (b/c of extending a <tr:inputXyz/> or <tr:selectXzy />). One is for extending the InputTextRenderer class, which is registered with the Trinidad internal RenderKit. The other one is kind of an internal renderer, that is used to render the component’s content.

The extension of the InputTextRenderer looks like this:

package net.wessendorf.trinidad;

import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.component.core.input.CoreInputText;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.FormInputRenderer;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.InputTextRenderer;

public class CustomInputTextRenderer extends InputTextRenderer
{
  public CustomInputTextRenderer()
  {
    super(CoreInputText.TYPE);
  } 

  protected CustomInputTextRenderer(FacesBean.Type type)
  {
    super(type);
  }

  @Override
  protected FormInputRenderer getFormInputRenderer()
  {
    return new CustomSimpleInputTextRenderer();
  }
}

In Trinidad the *layout* of the <tr:inputXyz/> is done by these renderers (those, that extend the InputLabelAndMessageRenderer class). The custom code isn’t really hard. It is only interesting to see how to create the internal renderer (CustomSimpleInputTextRenderer), which actually renders the content (which we want to decorate):

package net.wessendorf.trinidad;

import javax.faces.context.FacesContext;

import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.component.core.input.CoreInputText;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SimpleInputTextRenderer;

public class CustomSimpleInputTextRenderer extends SimpleInputTextRenderer
{
  public CustomSimpleInputTextRenderer()
  {
    this(CoreInputText.TYPE);
  }

  public CustomSimpleInputTextRenderer(FacesBean.Type type)
  {
    super(type);
  }
  @Override
  protected String getShortDesc(FacesBean bean)
  {
    return super.getShortDesc (bean) + " what ever you want to decorate";
  }
}

As you see this adds some (bogus) text to the short description of the component. That’s it from the java side. If you really want to change the entire rendering of the <tr:inputText /> your custom “content” renderer (CustomSimpleInputTextRenderer) could also override the protected encodeAllAsElement() method.The last step is to register the new renderer in your project’s faces-config.xml file:

...
<render-kit>
  <render-kit-id>
    org.apache.myfaces.trinidadinternal.core
  </render-kit-id>
  <renderer>
    <component-family>
      org.apache.myfaces.trinidad.Input
    </component-family>
    <renderer-type>
      org.apache.myfaces.trinidad.Text
    </renderer-type>
    <renderer-class>
      net.wessendorf.trinidad.CustomInputTextRenderer
    </renderer-class>
  </renderer>
</render-kit>
...

As you see, you register the CustomInputTextRenderer and not the renderer that renders the content (CustomSimpleInputTextRenderer).Now using the <tr:inputText> in your XHTML page will decorate the short description:

<tr:inputText label="Blah" shortDesc="foo bar" ... />

It is important to note, that these classes extend internal features of Trinidad. None of these classes is part of the Trinidad API. This means that anyone subclassing the renderers has to know their code can very well break any time they move to a newer version. Another example of extending a Trinidad renderer (for <tr:message/>), I posted here.

Howdy!

Posted in apache, java, jsf, myfaces, trinidad
5 comments on “Extending Trinidad’s default renderers
  1. Jeff W says:

    Hi, I got this example to work in my environment, but I am missing one bit of logic. FYI, I am attempting to customize the CommandButton renderer. How did you know that you needed to override the InputTextRenderer and SimpleInputTextRenderer classes for the tr:inputXYZ tag? I am a bit of a noob, but I don’t see how you made that leap, other than that you have a large amount of knowledge of the internal workings of the framework.

  2. Christian Hall says:

    This was hard for me to find too…Not sure you’ll ever see this response, but you have to dig into the Trinidad jar to look at its faces-config file and look at the custom components. That and a bunch of source code reading got me there (or close…nothing working yet).

    Everything in Trinidad is in HTML tables which is not helpful for styling w/ CSS, so I’m investigating removing some of that.

  3. alexndre says:

    Well i followed the process but from the desktopTableRenderer and it don’t seems to render the CustomDesktopTableRenderer i have created. Could you help me?

  4. Paul says:

    getting Trinidad to work is a hit and miss affair. A perfect functioning webapp in Glassfish simply falls apart in Weblogic.

    One webapp working in Weblogic, copied and with idetnical faces-config and web-xml (but for new servlets etc.) simply falls apart.

    Trinidad is great but it’s a stern and fragile master

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: