# 1
I think it works like this:
It all starts with your web.xml, where you define your taglib for your app. something like:
<taglib>
<taglib-uri>http://mycompany.com</taglib-uri>
<taglib-location>/WEB-INF/mytags.tld</taglib-location>
</taglib>
now you need to invent some tag and tie it to a tag class in your mytags.tld. let's say you wanted to inherit from datatable:
<tag>
<name>myDataTable</name>
<tag-class>mypackage.MyDataTableTag</tag-class>
<body-content>JSP</body-content>
<!-- all standard attributes of the dataTable tag -->
<!-- UIPanel attributes -->
<!-- UIComponent attributes -->
<attribute><name>id</name><required>false</required><rtexprvalue>false</rtexprvalue><type>java.lang.String</type>
<description>Every component may have an unique id. Automatically created if omitted.</description>
</attribute>
<attribute><name>rendered</name><required>false</required><rtexprvalue>false</rtexprvalue><type>java.lang.String</type>
<description>If false, this component will not be rendered.</description>
</attribute>
<attribute><name>binding</name><required>false</required><rtexprvalue>false</rtexprvalue><type>java.lang.String</type>
<description>Component binding.</description>
</attribute>
<!-- HTML 4.0 universal attributes -->
<attribute><name>dir</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>lang</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>style</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>title</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>styleClass</name><required>false</required><rtexprvalue>false</rtexprvalue>
<description>Corresponds to the HTML class attribute.</description>
</attribute>
<!-- HTML 4.0 event-handler attributes -->
<attribute><name>onclick</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>ondblclick</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onmousedown</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onmouseup</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onmouseover</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onmousemove</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onmouseout</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onkeypress</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onkeydown</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>onkeyup</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<!-- HTML 4.0 table attributes -->
<attribute><name>align</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>border</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>bgcolor</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>cellpadding</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>cellspacing</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>datafld</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>datasrc</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>dataformatas</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>frame</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>rules</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>summary</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>width</name><required>false</required> <rtexprvalue>false</rtexprvalue></attribute>
<!-- UIData attributes -->
<attribute><name>value</name><required>false</required><rtexprvalue>false</rtexprvalue>
<description>Supported types see JSF Spec 4.1.3</description>
</attribute>
<attribute><name>var</name><required>true</required><rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>rows</name><required>false</required><rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>first</name><required>false</required><rtexprvalue>false</rtexprvalue></attribute>
<!-- TableRenderer attributes -->
<attribute><name>columnClasses</name><required>false</required><rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>footerClass</name><required>false</required><rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>headerClass</name><required>false</required><rtexprvalue>false</rtexprvalue></attribute>
<attribute><name>rowClasses</name><required>false</required><rtexprvalue>false</rtexprvalue></attribute>
</tag>
It's worth noting that the tag definition is basicaly a huge copy/paste hack from the MyFaces tld, but, it's xml goo, and we needed a different <tag-class>, and i'm not smart enough to do it differently.
Now in mypackage.MyDataTableTag.java we can start extending some stuff:
public class MyDataTableTag extends org.apache.myfaces.taglib.html.HtmlDataTableTag {
public String getComponentType() {
return "mypackage.MyDataTable";
}
public String getRendererType() {
return "javax.faces.Table";
}
}
This guy is basicaly just another goo layer that ties in to the component class (where most of the work happens), renderers, and so forth.
HtmlDataTableTag is an eventual child of UIComponentBodyTag, but it's a ride to trace it.
Now you need more xml goo in your faces-config.xml to tie that string to a class:
<component>
<component-type>mypackage.MyDataTable</component-type>
<component-class>mypackage.MyDataTable</component-class>
</component>
(If it seems dumb that's because it is. Although if you wanted to override an existing myfaces component, this is where you'd do it. And there's probably good reasons why you might consider that in just this sort of case.) Anyway, now that you know <myDataTable> will end up using MyDataTable.java, you can finally do what you wanted to (I think)
public class MyDataTable extends javax.faces.component.html.HtmlDataTable {
public MyDataTable() {
super();
}
public boolean isRendered() {
return {some custom code};
}
}
The last major concern (that i'll mention) is that you're basicaly being a cheat by extending faces code. It'll work as long as your MyFaces implementation doesn't pull the rug out from under you by changing their class hierarchy and so forth. That's the price you pay for playing in someone else's sandbox. Your other option is to not be so lazy and have your tag class and component class not extend anything and behave entirely independant of (though perhaps similar to) faces classes. That would require kicking over more turds than we have already and require an understanding of the faces lifecycle, which is beyond the scope of this post.
I hope some of that was useful.
# 2
> I think it works like this:
>
> It all starts with your web.xml, where you define
> your taglib for your app. something like:
> > <taglib>
><taglib-uri>http://mycompany.com</taglib-uri>
> <taglib-location>/WEB-INF/mytags.tld</taglib-location>
>
> </taglib>
>
>
> now you need to invent some tag and tie it to a tag
> class in your mytags.tld. let's say you wanted to
> inherit from datatable:
> > <tag>
><name>myDataTable</name>
> <tag-class>mypackage.MyDataTableTag</tag-class>
><body-content>JSP</body-content>
> <!-- all standard attributes of the dataTable tag
> -->
><!-- UIPanel attributes -->
> <!-- UIComponent attributes -->
> <attribute><name>id</name><required>false</required><r
> texprvalue>false</rtexprvalue><type>java.lang.String<> type>
> <description>Every component may have an unique
> id. Automatically created if omitted.</description>
> /attribute>
>
> attribute><name>rendered</name><required>false</requir
> ed><rtexprvalue>false</rtexprvalue><type>java.lang.Str
> ing</type>
> <description>If false, this component will not be
> rendered.</description>
> /attribute>
>
> attribute><name>binding</name><required>false</require
> d><rtexprvalue>false</rtexprvalue><type>java.lang.Stri
> ng</type>
><description>Component binding.</description>
> tribute>
> <!-- HTML 4.0 universal attributes -->
> <attribute><name>dir</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>lang</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>style</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>title</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>styleClass</name><required>false</requ
> ired><rtexprvalue>false</rtexprvalue>
> <description>Corresponds to the HTML class
> attribute.</description>
> /attribute>
> <!-- HTML 4.0 event-handler attributes -->
> <attribute><name>onclick</name><required>false</requir
> ed> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>ondblclick</name><required>false</requ
> ired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onmousedown</name><required>false</req
> uired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onmouseup</name><required>false</requi
> red> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onmouseover</name><required>false</req
> uired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onmousemove</name><required>false</req
> uired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onmouseout</name><required>false</requ
> ired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onkeypress</name><required>false</requ
> ired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onkeydown</name><required>false</requi
> red> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>onkeyup</name><required>false</require
> d> <rtexprvalue>false</rtexprvalue></attribute>
> <!-- HTML 4.0 table attributes -->
> <attribute><name>align</name><required>false</required
> > <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>border</name><required>false</required
> > <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>bgcolor</name><required>false</require
> d> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>cellpadding</name><required>false</req
> uired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>cellspacing</name><required>false</req
> uired> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>datafld</name><required>false</require
> d> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>datasrc</name><required>false</require
> d> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>dataformatas</name><required>false</re
> quired>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>frame</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>rules</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>summary</name><required>false</require
> d> <rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>width</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
><!-- UIData attributes -->
> <attribute><name>value</name><required>false</require
> ><rtexprvalue>false</rtexprvalue>
> <description>Supported types see JSF Spec
> 4.1.3</description>
> /attribute>
>
> attribute><name>var</name><required>true</required><rt
> exprvalue>false</rtexprvalue></attribute>
>
> attribute><name>rows</name><required>false</required><
> rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>first</name><required>false</required>
> <rtexprvalue>false</rtexprvalue></attribute>
> <!-- TableRenderer attributes -->
> <attribute><name>columnClasses</name><required>false<> required><rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>footerClass</name><required>false</req
> uired><rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>headerClass</name><required>false</req
> uired><rtexprvalue>false</rtexprvalue></attribute>
>
> attribute><name>rowClasses</name><required>false</requ
> ired><rtexprvalue>false</rtexprvalue></attribute>
> </tag>
>
>
> It's worth noting that the tag definition is basicaly
> a huge copy/paste hack from the MyFaces tld, but,
> it's xml goo, and we needed a different <tag-class>,
> and i'm not smart enough to do it differently.
>
> Now in mypackage.MyDataTableTag.java we can start
> extending some stuff:
> > public class MyDataTableTag extends
> org.apache.myfaces.taglib.html.HtmlDataTableTag {
>
>public String getComponentType() {
>return "mypackage.MyDataTable";
> }
>
>public String getRendererType() {
>return "javax.faces.Table";
> }
>
> }
>
>
> This guy is basicaly just another goo layer that ties
> in to the component class (where most of the work
> happens), renderers, and so forth.
> HtmlDataTableTag is an eventual child of
> UIComponentBodyTag, but it's a ride to trace it.
>
> Now you need more xml goo in your faces-config.xml to
> tie that string to a class:
> > <component>
> <component-type>mypackage.MyDataTable</component-typ
> e>
> <component-class>mypackage.MyDataTable</component-cl
> ass>
> </component>
>
>
> (If it seems dumb that's because it is. Although if
> you wanted to override an existing myfaces component,
> this is where you'd do it. And there's probably good
> reasons why you might consider that in just this sort
> of case.) Anyway, now that you know <myDataTable>
> will end up using MyDataTable.java, you can finally
> do what you wanted to (I think)
>
> > public class MyDataTable extends
> javax.faces.component.html.HtmlDataTable {
>public MyDataTable() {
>super();
> }
>
>public boolean isRendered() {
>return {some custom code};
>
> }
>
>
> The last major concern (that i'll mention) is that
> you're basicaly being a cheat by extending faces
> code. It'll work as long as your MyFaces
> implementation doesn't pull the rug out from under
> you by changing their class hierarchy and so forth.
> That's the price you pay for playing in someone
> else's sandbox. Your other option is to not be so
> lazy and have your tag class and component class not
> extend anything and behave entirely independant of
> (though perhaps similar to) faces classes. That
> would require kicking over more turds than we have
> already and require an understanding of the faces
> lifecycle, which is beyond the scope of this post.
>
> I hope some of that was useful.
Thanks for this, your email looks very useful. And I will try out the code you have suggested.
You also make a very good point about playing about using code that is not part of the faces API, and the option to create my own components is in an ideal world the best one, but it may come down to time constraints.
Paul