Differences between revisions 95 and 96
Revision 95 as of 2009-01-25 10:07:41
Size: 40008
Editor: RogerKeays
Comment: add tag for selectItems component
Revision 96 as of 2009-09-20 23:01:29
Size: 40030
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
For Tomahawk 1.1.6 and earlier with [https://facelets.dev.java.net/ Facelets], you must follow the instructions below. Facelets requires a taglib.xml (best call it tomahawk.taglib.xml) file describing each component, and special facelets TagHandler classes for several tomahawk components. For Tomahawk 1.1.6 and earlier with [[https://facelets.dev.java.net/|Facelets]], you must follow the instructions below. Facelets requires a taglib.xml (best call it tomahawk.taglib.xml) file describing each component, and special facelets TagHandler classes for several tomahawk components.
Line 13: Line 13:
There exist an already created library in the [http://code.google.com/p/tomahawk-facelets "Tomahawk Facelets"] project, which has been creating using the information below and from other sources. You can just put the tomahawk-facelets.jar in your WEB-INF lib and you will get facelets support for tomahawk and the sandbox. When using this jar you won't need to do any of the steps defined below.

The [http://wiki.java.net/bin/view/Projects/FaceletsTaglibsMyfacesSandbox taglib file for Myfaces Sandbox] is on the Facelets Wiki.
There exist an already created library in the [[http://code.google.com/p/tomahawk-facelets|"Tomahawk Facelets"]] project, which has been creating using the information below and from other sources. You can just put the tomahawk-facelets.jar in your WEB-INF lib and you will get facelets support for tomahawk and the sandbox. When using this jar you won't need to do any of the steps defined below.

The [[http://wiki.java.net/bin/view/Projects/FaceletsTaglibsMyfacesSandbox|taglib file for Myfaces Sandbox]] is on the Facelets Wiki.
Line 503: Line 503:
I just added an [attachment:tomahawk.taglib.xml attachment] that contains the full facelets taglib definition for tomahawk as of myfaces 1.1.0. I extracted this from tomahawk.tld (thus the non-alphabetical order) and included a custom renderer whenever the JSP tag specified a different renderer than the default renderer for the JSF component. Not all components are tested, though - my primary goal was completeness... I just added an [[attachment:tomahawk.taglib.xml|attachment]] that contains the full facelets taglib definition for tomahawk as of myfaces 1.1.0. I extracted this from tomahawk.tld (thus the non-alphabetical order) and included a custom renderer whenever the JSP tag specified a different renderer than the default renderer for the JSF component. Not all components are tested, though - my primary goal was completeness...
Line 592: Line 592:
[http://jsf-comp.sourceforge.net jsf-comp]. I will probably add this to that project (tagHandlers.jar). There [[http://jsf-comp.sourceforge.net|jsf-comp]]. I will probably add this to that project (tagHandlers.jar). There
Line 628: Line 628:
[http://jsf-comp.sourceforge.net jsf-comp]. I will probably add this to that project (tagHandlers.jar). There [[http://jsf-comp.sourceforge.net|jsf-comp]]. I will probably add this to that project (tagHandlers.jar). There
Line 894: Line 894:
It can be obtained from [http://satva.skalasoft.com/~martin/dl/tomahawk-facelets.jar here] It can be obtained from [[http://satva.skalasoft.com/~martin/dl/tomahawk-facelets.jar|here]]
Line 907: Line 907:
[attachment:tomahawk-facelets.jar This attachment] is the patched jar. [[attachment:tomahawk-facelets.jar|This attachment]] is the patched jar.
Line 988: Line 988:
[[Anchor(updateActionListener)]]
If you want to use {{{<t:updateActionListener/>}}} or {{{<s:valueChangeNotifier/>}}}, first get the [http://sourceforge.net/project/showfiles.php?group_id=137466&package_id=188954 TagHandlers] library from [http://jsf-comp.sourceforge.net jsf-comp]. With this library, you'll be able to use the {{{updateActionListener}}} and {{{valueChangeNotifier}}} tag with the {{{http://jsf-comp.sourceforge.net/tomahawk-taghandlers}}} namespace.
<<Anchor(updateActionListener)>>
If you want to use {{{<t:updateActionListener/>}}} or {{{<s:valueChangeNotifier/>}}}, first get the [[http://sourceforge.net/project/showfiles.php?group_id=137466&package_id=188954|TagHandlers]] library from [[http://jsf-comp.sourceforge.net|jsf-comp]]. With this library, you'll be able to use the {{{updateActionListener}}} and {{{valueChangeNotifier}}} tag with the {{{http://jsf-comp.sourceforge.net/tomahawk-taghandlers}}} namespace.
Line 1035: Line 1035:
Use {{{t:document}}}, {{{t:documentHead}}} and {{{t:documentBody}}} instead of {{{html}}}, {{{head}}} and {{{body}}} tags to enhance [http://wiki.apache.org/myfaces/Performance performance]: Use {{{t:document}}}, {{{t:documentHead}}} and {{{t:documentBody}}} instead of {{{html}}}, {{{head}}} and {{{body}}} tags to enhance [[http://wiki.apache.org/myfaces/Performance|performance]]:

When This Information Is Needed

Tomahawk releases starting from version 1.1.7 (released September 2008) automatically support Facelets. No special actions are required to use Tomahawk components in a Facelets page, and the information in this page is not relevant.

For Tomahawk 1.1.6 and earlier with Facelets, you must follow the instructions below. Facelets requires a taglib.xml (best call it tomahawk.taglib.xml) file describing each component, and special facelets TagHandler classes for several tomahawk components.

Required Steps

There exist an already created library in the "Tomahawk Facelets" project, which has been creating using the information below and from other sources. You can just put the tomahawk-facelets.jar in your WEB-INF lib and you will get facelets support for tomahawk and the sandbox. When using this jar you won't need to do any of the steps defined below.

The taglib file for Myfaces Sandbox is on the Facelets Wiki.

Then declare the taglib in your web.xml file:

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

Here is an example file that defines some of the available components.

Please add additional component definitions to this example as you use them (in alphabetical order). To find the component and renderer types, look at the getComponentType() and getRendererType() methods in the Tag class for the component. If the Tag class does anything other than providing pass-through getters and setters, you will need to write a facelets TagHandler or submit patches to MyFaces to "standardize" the tag handler.

Example

<?xml version="1.0"?>
<!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://myfaces.apache.org/tomahawk</namespace>

    <tag>
        <tag-name>aliasBean</tag-name>
        <component>
            <component-type>org.apache.myfaces.AliasBean</component-type>
            <renderer-type>org.apache.myfaces.AliasBean</renderer-type>
            <handler-class>your.package.AliasBeanHandler</handler-class>
        </component>
    </tag>
    <tag>
        <tag-name>buffer</tag-name>
        <component>
            <component-type>org.apache.myfaces.Buffer</component-type>
            <renderer-type>org.apache.myfaces.Buffer</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>checkbox</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlCheckbox</component-type>
            <renderer-type>org.apache.myfaces.Checkbox</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>columns</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlColumns</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>column</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlColumn</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>commandButton</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlCommandButton</component-type>   
        </component>
    </tag>
    <tag>
        <tag-name>commandLink</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlCommandLink</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>commandNavigation</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlCommandNavigation</component-type>
            <renderer-type>org.apache.myfaces.Navigation</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>commandNavigation2</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlCommandNavigationItem</component-type>
            <renderer-type>org.apache.myfaces.NavigationMenu</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>commandSortHeader</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlCommandSortHeader</component-type>
            <renderer-type>org.apache.myfaces.SortHeader</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>dataList</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlDataList</component-type>
            <renderer-type>org.apache.myfaces.List</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>dataScroller</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlDataScroller</component-type>
            <renderer-type>org.apache.myfaces.DataScroller</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>dataTable</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlDataTable</component-type>
            <renderer-type>org.apache.myfaces.Table</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>div</tag-name>
        <component>
            <component-type>org.apache.myfaces.Div</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>document</tag-name>
        <component>
            <component-type>org.apache.myfaces.Document</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>documentBody</tag-name>
        <component>
            <component-type>org.apache.myfaces.DocumentBody</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>documentHead</tag-name>
        <component>
            <component-type>org.apache.myfaces.DocumentHead</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>dojoInitializer</tag-name>
        <component>
            <component-type>org.apache.myfaces.DojoInitializer</component-type>
            <renderer-type>org.apache.myfaces.DojoInitializerRenderer</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>graphicImage</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlGraphicImage</component-type>
            <renderer-type>javax.faces.Image</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>htmlTag</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlTag</component-type>
            <renderer-type>org.apache.myfaces.HtmlTagRenderer</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputFileUpload</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputFileUpload</component-type>
            <renderer-type>org.apache.myfaces.FileUpload</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputCalendar</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputCalendar</component-type>
            <renderer-type>org.apache.myfaces.Calendar</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputDate</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputDate</component-type>
            <renderer-type>org.apache.myfaces.Date</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputHidden</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputHidden</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputHtml</tag-name>
        <component>
            <component-type>org.apache.myfaces.InputHtml</component-type>
            <renderer-type>org.apache.myfaces.InputHtml</renderer-type>
        </component>
    </tag>    
    <tag>
        <tag-name>inputSecret</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputSecret</component-type>
            <renderer-type>org.apache.myfaces.Secret</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputText</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputText</component-type>
            <renderer-type>org.apache.myfaces.Text</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputTextarea</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputTextarea</component-type>
            <renderer-type>org.apache.myfaces.Textarea</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>inputTextHelp</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlInputTextHelp</component-type>
            <renderer-type>org.apache.myfaces.TextHelp</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>jscookMenu</tag-name>
                <!--
                <![CDATA[
Requires "<input type="hidden" name="jscook_action" />" to be manually added to the form
                ]]>
                -->
        <component>
            <component-type>org.apache.myfaces.JSCookMenu</component-type>
            <renderer-type>org.apache.myfaces.JSCookMenu</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>message</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlMessage</component-type>
            <renderer-type>org.apache.myfaces.Message</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>messages</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlMessages</component-type>
            <renderer-type>org.apache.myfaces.Messages</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>navigationMenuItem</tag-name>
        <component>
            <component-type>org.apache.myfaces.NavigationMenuItem</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>navigationMenuItems</tag-name>
        <component>
            <component-type>javax.faces.SelectItems</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>newspaperTable</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlNewspaperTable</component-type>
            <renderer-type>org.apache.myfaces.HtmlNewspaperTable</renderer-type>
        </component>                
    </tag>
    <tag>
        <tag-name>outputText</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlOutputText</component-type>
            <renderer-type>org.apache.myfaces.Text</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelGrid</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelGrid</component-type>
            <renderer-type>org.apache.myfaces.Grid</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelGroup</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelGroup</component-type>
            <renderer-type>org.apache.myfaces.Group</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelNavigation</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelNavigation</component-type>
            <renderer-type>org.apache.myfaces.Navigation</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelNavigation2</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelNavigationMenu</component-type>
            <renderer-type>org.apache.myfaces.NavigationMenu</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelStack</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelStack</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelTab</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelTab</component-type>
            <renderer-type>javax.faces.Group</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>panelTabbedPane</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelTabbedPane</component-type>
            <renderer-type>org.apache.myfaces.TabbedPane</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>popup</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPopup</component-type>
            <renderer-type>org.apache.myfaces.Popup</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>radio</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlRadio</component-type>
            <renderer-type>org.apache.myfaces.Radio</renderer-type>
        </component>
    </tag> 
    <tag>
        <tag-name>saveState</tag-name>
        <component>
            <component-type>org.apache.myfaces.SaveState</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>schedule</tag-name>
        <component>
            <component-type>org.apache.myfaces.Schedule</component-type>
            <renderer-type>org.apache.myfaces.Schedule</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectBooleanCheckbox</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectBooleanCheckbox</component-type>
            <renderer-type>org.apache.myfaces.Checkbox</renderer-type>
        </component>
    </tag>    
    <tag>
        <tag-name>selectItems</tag-name>
        <component>
            <component-type>org.apache.myfaces.UISelectItems</component-type>
        </component>
    </tag
    <tag>
        <tag-name>selectManyCheckbox</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectManyCheckbox</component-type>
            <renderer-type>org.apache.myfaces.Checkbox</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectManyListbox</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectManyListbox</component-type>
            <renderer-type>org.apache.myfaces.Listbox</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectManyMenu</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectManyMenu</component-type>
            <renderer-type>org.apache.myfaces.Menu</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectOneCountry</tag-name>
        <component>
            <component-type>org.apache.myfaces.SelectOneCountry</component-type>
            <renderer-type>org.apache.myfaces.SelectOneCountryRenderer</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectOneLanguage</tag-name>
        <component>
            <component-type>org.apache.myfaces.SelectOneLanguage</component-type>
            <renderer-type>org.apache.myfaces.SelectOneLanguageRenderer</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectOneListbox</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectOneListbox</component-type>
            <renderer-type>org.apache.myfaces.Listbox</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectOneMenu</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectOneMenu</component-type>
            <renderer-type>org.apache.myfaces.Menu</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectOneRadio</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectOneRadio</component-type>
            <renderer-type>org.apache.myfaces.Radio</renderer-type>
        </component>
    </tag> 
    <tag>
        <tag-name>stylesheet</tag-name>
        <component>
            <component-type>org.apache.myfaces.Stylesheet</component-type>
        </component>
    </tag>
    <!-- Note that "tree" will not work as-is.  Tree either needs a facelets 
         TagHandler, or a refactoring of
         org.apache.myfaces.custom.tree.taglib.TreeTag
         and org.apache.myfaces.custom.tree.HtmlTree
         to remove non-standard internal "model" attribute usage. -->
    <tag>
        <tag-name>tree</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlTree</component-type>
            <renderer-type>org.apache.myfaces.HtmlTree</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>tree2</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlTree2</component-type>
            <renderer-type>org.apache.myfaces.HtmlTree2</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>treeColumn</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlTreeColumn</component-type>
        </component>
    </tag>
    <!--
        <tag-name>updateActionListener</tag-name> requires a Facelets TagHandler.   Use the functionality-equivalent JSF 1.2 f:setPropertyActionListener instead.  f:setPropertyActionListener has been backported as of facelets 1.1.11.  Note that the jsf-comp updateActionListener does not handle setting values on ui:include parameters while setPropertyActionListener will correctly propagate these values.
    -->
    <tag>
        <tag-name>validateEmail</tag-name>
        <validator>
            <validator-id>org.apache.myfaces.validator.Email</validator-id>
        </validator>
    </tag>
    <tag>
        <tag-name>validateEqual</tag-name>
        <validator>
            <validator-id>org.apache.myfaces.validator.Equal</validator-id>
        </validator>
    </tag>
    <tag>
        <tag-name>validateRegExpr</tag-name>
        <validator>
            <validator-id>org.apache.myfaces.validator.RegExpr</validator-id>
        </validator>
    </tag>

</facelet-taglib>

Here's a code snippet of how you would then use an inputDate control from the MyFaces extensions library in your facelet .xhtml file:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:t="http://myfaces.apache.org/tomahawk">
...
           <t:inputDate popupCalendar="true"/>


I just added an attachment that contains the full facelets taglib definition for tomahawk as of myfaces 1.1.0. I extracted this from tomahawk.tld (thus the non-alphabetical order) and included a custom renderer whenever the JSP tag specified a different renderer than the default renderer for the JSF component. Not all components are tested, though - my primary goal was completeness...

Thomas Jachmann


It turns out that tree2 does not work seamlessly with Facelets. The attributes 'showNav', 'showLines' etc require a Facelets Tag Handler as they are not handled in the manner anticipated by Facelets. However, you use the following workaround:

<t:tree2 
id="menuTree" 
value="#{menu.treeModel}" var="node" varNodeToggler="t" 
org.apache.myfaces.tree2.CLIENT_SIDE_TOGGLE="#{menu.booleanFalse}"
org.apache.myfaces.tree2.SHOW_ROOT_NODE="#{menu.booleanFalse}"
org.apache.myfaces.tree2.SHOW_LINES="#{menu.booleanFalse}"
org.apache.myfaces.tree2.SHOW_NAV="#{menu.booleanFalse}"
>
...
</t:tree2>

Where 'org.apache.myfaces.tree2.SHOW_ROOT_NODE' is the internal name (as a String) of the showRootNde attribute. These must be bound to Boolean values as that is the datatype expected internally by MyFaces code.

I'm not sure if the above is easier than writing a Facelet Tag Handler or not ... for me (with the (ahem) documentation I have) it was easier.

Aaron Aston


In reference to the above "Facelet Tag Handler" for the tree2. Here is a component handler (tag handler) that works for tree2:

import java.util.Map;

import javax.faces.component.UIComponent;

import org.apache.myfaces.custom.tree2.HtmlTree;
import org.apache.myfaces.renderkit.JSFAttr;

import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.MetaRuleset;
import com.sun.facelets.tag.jsf.ComponentConfig;
import com.sun.facelets.tag.jsf.ComponentHandler;

public class Tree2TagHandler
  extends ComponentHandler
{
  public Tree2TagHandler(ComponentConfig cfg)
  {
    super(cfg);
  }
  
  @Override
  @SuppressWarnings("unchecked")
  protected void onComponentCreated(FaceletContext ctx, UIComponent c, UIComponent parent)
  {
    super.onComponentCreated(ctx, c, parent);
    
    HtmlTree component = (HtmlTree)c;
    
    Map attrs = component.getAttributes();
    ensureBoolean(attrs, JSFAttr.SHOW_NAV);
    ensureBoolean(attrs, JSFAttr.SHOW_LINES);
    ensureBoolean(attrs, JSFAttr.CLIENT_SIDE_TOGGLE);
    ensureBoolean(attrs, JSFAttr.SHOW_ROOT_NODE);
    ensureBoolean(attrs, JSFAttr.PRESERVE_TOGGLE);
  }
  
  @SuppressWarnings("unchecked")
  private void ensureBoolean(Map attributes, String attrName)
  {
    Object value = attributes.get(attrName);
    if (value == null || !(value instanceof String)) return;
    attributes.put(attrName, Boolean.valueOf((String)value));
  }
  
  @Override
  protected MetaRuleset createMetaRuleset(Class type)
  {
    return super.createMetaRuleset(type)
      .alias("showNav", JSFAttr.SHOW_NAV)
      .alias("showLines", JSFAttr.SHOW_LINES)
      .alias("clientSideToggle", JSFAttr.CLIENT_SIDE_TOGGLE)
      .alias("showRootNode", JSFAttr.SHOW_ROOT_NODE)
      .alias("preserveToggle", JSFAttr.PRESERVE_TOGGLE);      
  }
}

Also please node that you are welcome to use and contribute to the "tagHandlers" release of jsf-comp. I will probably add this to that project (tagHandlers.jar). There is already one for <t:updateActionListener />

Andrew Robinson


Like the tree2, the extended tomahawk data table uses "non-standard" attribute names for some of the properties and without the tag, the attributes are not set correctly. The following code can be used as a tag handler to make sure these row attributes are set correctly on the data table component:

import org.apache.myfaces.renderkit.JSFAttr;

import com.sun.facelets.tag.MetaRuleset;
import com.sun.facelets.tag.jsf.ComponentConfig;
import com.sun.facelets.tag.jsf.ComponentHandler;

public class DataTableExTagHandler
  extends ComponentHandler
{
  public DataTableExTagHandler(ComponentConfig cfg)
  {
    super(cfg);
  }
    
  @Override
  protected MetaRuleset createMetaRuleset(Class type)
  {
    return super.createMetaRuleset(type)
      .alias("rowId", JSFAttr.ROW_ID)
      .alias("rowStyleClass", JSFAttr.ROW_STYLECLASS_ATTR)
      .alias("rowStyle", JSFAttr.ROW_STYLE_ATTR);      
  }
}

Also please node that you are welcome to use and contribute to the "tagHandlers" release of jsf-comp. I will probably add this to that project (tagHandlers.jar). There is already one for <t:updateActionListener />

Andrew Robinson


Here is a custom tag handler for the schedule class which is needed if you want to use the mouseListener binding:

   <tag>
        <tag-name>schedule</tag-name>
        <component>
            <component-type>org.apache.myfaces.Schedule</component-type>
            <handler-class>>ui.control.ScheduleTagHandler</handler-class>
        </component>
    </tag>

package ui.control;
public class ScheduleTagHandler extends HtmlComponentHandler {

 
    private static final String MOUSE_LISTENER = "mouseListener";
    private static Logger _logger = Logger.getLogger(HtmlSchedule.class.getName());

    public ScheduleTagHandler(ComponentConfig tagConfig) {
        super(tagConfig);
        _logger.info("HtmlSchedule: " + tagConfig);
    }

    protected MetaRuleset createMetaRuleset(Class type)
    {
       
        MetaRuleset m = super.createMetaRuleset(type);
         
    
        m.addRule(getMouseListenerMetaRule());

        return m;
    }

    private MetaRule getMouseListenerMetaRule() {
          Class[] paramList = new Class[]{ScheduleMouseEvent.class};
          _logger.info("MouseListenerMetaRule");
          return new MethodRule(MOUSE_LISTENER, String.class, paramList);
    }
    
 }

This rule only adds the mouseListener methid binding, other bindings might be needed for various cases and should be added here on a case by case base.


I also created custom tag handler for tomahawk panelTabedPane component to add support of tabChangeListener attribute.

Below is example of how to define this custom tag handler in facelets-taglib:

    <tag>
        <tag-name>panelTabbedPane</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlPanelTabbedPane</component-type>
                <handler-class>ui.control.TabbedPaneComponentHandler</handler-class>
        </component>
    </tag>

Here's example of tag usage:

<m:panelTabbedPane 
                                binding="#{tabPaneController.tabbedPane}"
                                tabChangeListener="#{tabPaneController.processTabChange}"
                                serverSideTabSwitch="true" 
                                styleClass="tabbedPane"
                                activeTabStyleClass="activeTab"
                                inactiveTabStyleClass="inactiveTab"
                                disabledTabStyleClass="disabledTab"
                                tabContentStyleClass="tabContent"
                >
                        <t:panelTab id="tab1" label="#{msgs.tab1}">
                                <ui:include src="/tab1.xhtml" />
                        </t:panelTab>
                        <t:panelTab id="tab2" label="#{msgs.tab2}" >
                                <ui:include src="/tab2.xhtml" />
                        </t:panelTab>
</m:panelTabbedPane>

and here's tag handler source code:

package ui.control;

import javax.faces.el.MethodBinding;

import org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPane;
import org.apache.myfaces.custom.tabbedpane.TabChangeEvent;

import com.sun.facelets.FaceletContext;
import com.sun.facelets.el.LegacyMethodBinding;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagException;
import com.sun.facelets.tag.jsf.ComponentConfig;
import com.sun.facelets.tag.jsf.ComponentHandler;

public class TabbedPaneComponentHandler extends ComponentHandler {

        static final String METHOD_BINDING_ATTR_NAME = "tabChangeListener";
        static final Class[] METHOD_BINDING_SIGNATURE = {TabChangeEvent.class};
        
        public TabbedPaneComponentHandler(ComponentConfig config) {
                super(config);
        }

        @Override
        protected void setAttributes(FaceletContext ctx, Object instance) {
                super.setAttributes(ctx, instance);
        try {
                        final HtmlPanelTabbedPane component = (HtmlPanelTabbedPane) instance;
                        final TagAttribute tagAttribute = TabbedPaneComponentHandler.this.getAttribute(METHOD_BINDING_ATTR_NAME);
                        if (null != tagAttribute) {
                                final MethodBinding methodBinding = new LegacyMethodBinding(tagAttribute.getMethodExpression(ctx, null, METHOD_BINDING_SIGNATURE));
                                component.setTabChangeListener(methodBinding);
                        }
        } catch (Exception e) {
            throw new TagException(TabbedPaneComponentHandler.this.tag, e);
        }
        }

}

Dmitry Zemnitskiy


Or it can be implemented as

package ui.control;

import com.sun.facelets.tag.MetaRuleset;
import com.sun.facelets.tag.MethodRule;
import com.sun.facelets.tag.jsf.ComponentConfig;
import com.sun.facelets.tag.jsf.ComponentHandler;
import org.apache.myfaces.custom.tabbedpane.TabChangeEvent;

public class TabbedPaneComponentHandler extends ComponentHandler {
 static final String METHOD_BINDING_ATTR_NAME = "tabChangeListener";
 static final Class[] METHOD_BINDING_SIGNATURE = {TabChangeEvent.class};
 
 protected final static MethodRule actionListenerTagRule = new MethodRule(
   METHOD_BINDING_ATTR_NAME, void.class, METHOD_BINDING_SIGNATURE );

 public TabbedPaneComponentHandler(ComponentConfig config) {
         super(config);
 }


 protected MetaRuleset createMetaRuleset(Class type) {

  return super.createMetaRuleset(type).addRule( actionListenerTagRule );

 }

}

Sagar


For direct use <f:setPropertyActionListener/>

Define custom tag handler in facelets-taglib

  <tag>
     <tag-name>tabChangeListener</tag-name>
     <handler-class>ui.handler.TabChangeListenerHandler</handler-class>
  </tag>

Tag usage

<m:panelTabbedPane 
                                binding="#{tabPaneController.tabbedPane}"
                                serverSideTabSwitch="true">
<t:tabChangeListener type="ui.handler.TableTabChangeListener"  />       
                        <t:panelTab id="tab1" label="#{msgs.tab1}">
                                <ui:include src="/tab1.xhtml" />
                        </t:panelTab>
                        <t:panelTab id="tab2" label="#{msgs.tab2}" >
                                <ui:include src="/tab2.xhtml" />
                        </t:panelTab>
</m:panelTabbedPane>

tag handler source code:

package ui.handler;

import com.sun.facelets.tag.TagHandler;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;
import com.sun.facelets.FaceletContext;
import com.sun.facelets.FaceletException;

import java.io.IOException;

import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.el.ELException;

import org.apache.myfaces.custom.tabbedpane.HtmlPanelTabbedPane;
import org.apache.myfaces.custom.tabbedpane.TabChangeListener;
import org.apache.myfaces.shared_tomahawk.util.ClassUtils;

public class TabChangeListenerHandler extends TagHandler {

 private final TagAttribute type;

 public TabChangeListenerHandler(TagConfig config) {

  super(config);
  type = getRequiredAttribute("type");
 }

 /*
  * (non-Javadoc)
  * 
  * @see com.sun.facelets.FaceletHandler#apply(com.sun.facelets.FaceletContext,
  *      javax.faces.component.UIComponent)
  */
 public void apply(FaceletContext faceletContext, UIComponent parent)
   throws IOException, FacesException, FaceletException, ELException {

  // only process if parent was just created
  if (parent.getParent() == null) {
   if (parent instanceof HtmlPanelTabbedPane) {
    String className;
    if (!type.isLiteral()) {
     className = type.getValue();
    }
    else {
     className = type.getValue(faceletContext);
    }
    TabChangeListener listener = (TabChangeListener) ClassUtils
      .newInstance(className);
    ((HtmlPanelTabbedPane) parent).addTabChangeListener(listener);
   }
   else {
    throw new FacesException("Component is not HtmlPanelTabbedPane children");
   }
  }
 }

}

Sagar


I've put together a tomahawk-facelets library, that provides custom tag handlers for components that have 'special' attributes, requiring Boolean or Integer options. It includes a modified facelets library description XML.

It can be obtained from here

It works for me, but it hasn't been quite thoroughly tested. It was built for MyFaces 1.1.0.

I have also attached a source only version, licensed Apache 2.0, with the hope that it can be included in the distribution of either tomahawk or facelets.

Martin Mavrov


I've added a few little things to Martin's library in order to make the displayValueOnly attribute work.

In the tomahawk.taglib.xml I added and changed a few renderer-types from the javax.faces... ones to the org.apache... ones. I also changed BooleanMetadata.java a little so that it also supports EL valuebindings and not only literal boolean values. Martin's disclaimer goes for my patch as well. It works for me, but I haven't tested it thoroughly either.

This attachment is the patched jar.

Jan Van Lysebeth


Sandbox Facelet taglib for s:planner, s:focus and others

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://myfaces.apache.org/sandbox</namespace>

    <tag>
        <tag-name>convertBoolean</tag-name>
        <converter>
            <converter-id>org.apache.myfaces.custom.convertboolean.BooleanConverter</converter-id>
        </converter>
    </tag>
    <tag>
        <tag-name>convertDateTime</tag-name>
        <converter>
            <converter-id>org.apache.myfaces.custom.convertDateTime.DateTimeConverter</converter-id>
        </converter>
    </tag>
    <tag>
        <tag-name>convertNumber</tag-name>
        <converter>
            <converter-id>org.apache.myfaces.custom.convertNumber.TypedNumberConverter</converter-id>
        </converter>
    </tag>
    <tag>
        <tag-name>effect</tag-name>
        <component>
            <component-type>org.apache.myfaces.Div</component-type>
            <renderer-type>org.apache.myfaces.effect.EffectRenderer</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>focus</tag-name>
        <component>
            <component-type>org.apache.myfaces.Focus</component-type>
            <renderer-type>org.apache.myfaces.Focus</renderer-type>
        </component>
    </tag>
    <tag>
        <tag-name>planner</tag-name>
        <component>
            <component-type>org.apache.myfaces.Planner</component-type>
        </component>
    </tag>
    <tag>
        <tag-name>selectItems</tag-name>
        <component>
            <component-type>org.apache.myfaces.UISelectItems</component-type>
        </component>
    </tag>  
    <tag>
        <tag-name>selectManyPicklist</tag-name>
        <component>
            <component-type>org.apache.myfaces.HtmlSelectManyPicklist</component-type>
            <renderer-type>org.apache.myfaces.PicklistRenderer</renderer-type>
        </component>
    </tag>
</facelet-taglib>

The sandbox-taglib definition for the graphicimageDynamic has been changed to:

<tag>
    <tag-name>graphicImageDynamic</tag-name>
    <component>
        <component-type>org.apache.myfaces.custom.graphicimagedynamic.GraphicImageDynamic</component-type>
        <renderer-type>org.apache.myfaces.custom.graphicimagedynamic.GraphicImageDynamicRenderer</renderer-type>
        <handler-class>facelets.GraphicImageDynamicComponentHandler</handler-class>
    </component>
</tag>

Use as standalone or add these to the taglib that is posted on Facelets wiki(link at the top of the page).


If you want to use <t:updateActionListener/> or <s:valueChangeNotifier/>, first get the TagHandlers library from jsf-comp. With this library, you'll be able to use the updateActionListener and valueChangeNotifier tag with the http://jsf-comp.sourceforge.net/tomahawk-taghandlers namespace. If you want to use the good old http://myfaces.apache.org/tomahawk namespace, add the following tag definition to your tomahawk.taglib.xml (for <t:updateActionListener/>):

<tag>
        <tag-name>updateActionListener</tag-name>
        <handler-class>net.sf.jsfcomp.facelets.taghandlers.tomahawk.UpdateActionListenerHandler</handler-class>
</tag>

and this definition to your sandbox.taglib.xml (for <s:valueChangeNotifier/>):

<tag>
        <tag-name>valueChangeNotifier</tag-name>
        <handler-class>net.sf.jsfcomp.facelets.taghandlers.tomahawk.ValueChangeNotifierHandler</handler-class>
</tag>  

Here's an example of using the tag:

<html 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:t="http://myfaces.apache.org/tomahawk"
        xmlns:c="http://java.sun.com/jstl/core">

...

        <ui:repeat value="#{recordTemplateBrowserBean.recordTemplateDao.recordTemplateDescriptions}" 
                var="recordTemplateDescription">
                <li>
                        <h:commandLink 
                                value="#{recordTemplateDescription.name}" 
                                action="#{recordTemplateActionBean.loadRecordTemplate}">
                                <t:updateActionListener property="#{recordTemplateActionBean.id}" value="#{recordTemplateDescription.id}" />
                        </h:commandLink>
                </li>
        </ui:repeat>
...
</html>

Aleksei Valikov


Use t:document, t:documentHead and t:documentBody instead of html, head and body tags to enhance performance:

{{{<t:document

</t:document>}}}

Aleksei Valikov


Tag-Handler for AliasBean

import com.sun.facelets.FaceletContext;
import com.sun.facelets.FaceletException;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagHandler;
import com.sun.facelets.tag.jsf.ComponentConfig;
import org.apache.myfaces.custom.aliasbean.AliasBean;

import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;
import java.io.IOException;

public class AliasBeanHandler extends TagHandler
{
        private TagAttribute valueAttr;
        private TagAttribute aliasAttr;

        public AliasBeanHandler(ComponentConfig tagConfig)
        {
                super(tagConfig);

                valueAttr = getRequiredAttribute("value");
                aliasAttr = getRequiredAttribute("alias");
        }


        public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException, ELException
        {
        Application app = ctx.getFacesContext().getApplication();

                AliasBean aliasBean = new AliasBean();

                String value = valueAttr.getValue();
                if (UIComponentTag.isValueReference(value))
                {
                        aliasBean.setValueBinding("value", app.createValueBinding(valueAttr.getValue()));
                }
                else
                {
                        aliasBean.setValue(value);
                }

                String alias = aliasAttr.getValue();
                if (UIComponentTag.isValueReference(alias))
                {
                        aliasBean.setValueBinding("alias", app.createValueBinding(aliasAttr.getValue()));
                }
                else
                {
                        aliasBean.setAlias(alias);
                }

                parent.getChildren().add(aliasBean);
        }

}

Mario Ivankovits


Tag handler for inputCalendar

public class InputCalendarTagHandler 
    extends ComponentHandler

    {
        /**
         * @param config
         */
        public InputCalendarTagHandler(ComponentConfig config)
        {
            super(config);
        }
        
      

        
        protected MetaRuleset createMetaRuleset(Class type)
        {
          return super.createMetaRuleset(type)
            .alias("imageLocation", JSFAttr.IMAGE_LOCATION);
              
        }
        
}

Werner Punz

Use_Facelets_with_Tomahawk (last edited 2009-09-20 23:01:29 by localhost)