You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Leonardo Uribe <lu...@gmail.com> on 2007/06/13 04:49:37 UTC

[TRINIDAD and TOMAHAWK] Extending Trinidad Skinning support to Tomahawk components

Hi everybody.

I'm working on extends skinning capabilities found in Trinidad, for use with
non Trinidad components
(Tomahawk or base html components). This is the main objective of my Google
Summer of Code proposal,
and finally I finnish my first aproximation of the final source code.

The link to the project is here: http://code.google.com/p/myfaces-csi/
the source code is here:
http://myfaces-csi.googlecode.com/svn/trunk/myfaces-csi/myfaces-skins/
I'm skinning some myfaces examples but for now only home.jsp,
sample1.jspand 2 works with it. In the next
days I planned to add skins to other examples.
Note that in this moment, it works well, but I want to work at best as I can
do.

I have some questions about it, but first I have to explain what i have done
at this time.
The big trick is implement a decorator pattern. I have tabbed the questions
for an easy reading.

NOTE: Feel free to answer one of all questions. I will appreciate a lot your
efford in help with
this proyect. Note that this work is a donation sponsored for Google Inc.
for Apache Software Foundation.

I created a SkinRenderKit that decorate the HTML_BASIC_RENDER_KIT, but it
implements
ExtendedRenderKitService (see trinidad) . The objective is that trinidad
ViewHandler
recognize this and create a RenderingContext for the view (necesary for
skins).

Then, I set the default render kit as SkinRenderKit.

<application>
    <!-- Use the Skin RenderKit -->
    <default-render-kit-id>SkinRenderKit</default-render-kit-id>
</application>

<!-- Optional at now -->
<factory>
    <render-kit-factory>org.apache.myfaces.custom.skin.SkinRenderKitFactory
</render-kit-factory>
</factory>


In the faces-config.xml I register the component that I want to skin like
this:

<render-kit>
    <render-kit-id>SkinRenderKit</render-kit-id>
    <render-kit-class>
        org.apache.myfaces.trinidadinternal.renderkit.core.SkinRenderKit
    </render-kit-class>
    <renderer>
        <component-family>javax.faces.Command</component-family> <!-- THE
SAME FAMILY THAN THE ORIGINAL -->
        <renderer-type>javax.faces.Button</renderer-type> <!-- THE SAME
RENDERER TYPE THAN THE ORIGINAL -->
        <renderer-class>
            org.apache.myfaces.custom.skin.GenericSkinRenderer
        </renderer-class>
    </renderer>

    ....... Other components ........

</render-kit>

The renderer should extends form SkinRenderer class. When the renderer is
added in
SkinRenderKit, it finds its HTML_BASIC renderer counterpart (based on his
component family and
renderer type), and set this as if SkinRenderKit was
a decorator of the counterpart.

    1. QUESTION: Here is the first question: What if I want to skin other
component that make use
    of some RenderKit different that HTML_BASIC? My first solution should be
something like this:

    <renderer>
        <component-family>other.component.Command</component-family>
        <renderer-type>other.renderer.Button</renderer-type>
        <renderer-class>
            org.apache.myfaces.custom.skin.GenericSkinRenderer
        </renderer-class>

        <renderer-extension>
            <property>
                <property-name>renderKit</property-name>
                <property-class>java.lang.String</property-class>
                <default-value>other.renderkit.OtherRenderKit
</default-value>
            </property>
        </renderer-extension>
    </renderer>

    But I'm not have found any information about how to make this work.
Looking, if I could override
    the FacesConfigurator class with my custom implementation I feel that
this should be possible.
    The sub-question is ¿is possible to override a FacesConfigurator? How?

A SkinRenderer override the styleClass parameters (Ex: styleClass,
headerClass, ....) of the component,
and delegate this info to the real HTML_BASIC renderer. I do this with code
like this:

    //....some stuff getting, checking and getting the class .....
    component.getAttributes().put("styleClass",styleClass);

    2. QUESTION: I have done this and this works. But is this clean?.
Apparently, yes, but....
    Any suggestions? Maybe casting the component class and setting directly
.....

Then you have to configure your skins like in trinidad

trinidad-config.xml

<trinidad-config xmlns="http://myfaces.apache.org/trinidad/config">
  <debug-output>true</debug-output>
  <client-validation>INLINE</client-validation>
  <skin-family>example</skin-family>
</trinidad-config>

and trinidad-skins.xml

<skins xmlns="http://myfaces.apache.org/trinidad/skin">
    <skin>
        <id>
            example.desktop
        </id>
        <family>
            example
        </family>
        <render-kit-id>
            org.apache.myfaces.trinidad.desktop
        </render-kit-id>
        <style-sheet-name>
            skins/example/exampleSkin.css
        </style-sheet-name>
    </skin>
</skins>

Configure your application like say in the wiki of Trinidad.
Then stylize your component writing in exampleSkin.css something like this:

af|<component_package_name_replace_point_with_underscore>::<property_or_string>
{
.....
}

Example

(easy to map if you are the programmer)

af|javax_faces_component_html_HtmlOutputLabel::class
{
    font-family: verdana,arial,helvetica,sans-serif;
}

af|javax_faces_component_html_HtmlOutputLink::class:hover
{
    font-family: verdana,arial,helvetica,sans-serif;
     text-decoration: underline overline;
     color: red;
}

    3. QUESTION: I don't now if it was better to do something like this

    (Its more simple to the designer to stylize if the component style looks
like this)

    h|outputLink::class:hover
    {
        font-family: verdana,arial,helvetica,sans-serif;
         text-decoration: underline overline;
         color: red;
    }

    The big problem is if I want to do this, I have to burn the outputLink
    String inside the code of the renderer (Difficulting reuse of code).
    I would like to do something like this:

    <renderer>
        <component-family>other.component.Command</component-family>
        <renderer-type>other.renderer.Button</renderer-type>
        <renderer-class>
            org.apache.myfaces.custom.skin.GenericSkinRenderer
        </renderer-class>

        <renderer-extension>
            <property>
                <property-name>componentBaseName</property-name>
                <property-class>java.util.List</property-class>
                    <list-entries>
                <value>javax.faces.component.html.HtmlOutputLink
,h|outputLink</value>
                </list-entries>
            </property>
        </renderer-extension>
    </renderer>

    But the same that in the first question. How i can personalize this?

    4. QUESTION: What happen if I change the af prefix with other? (I read
something about namespaces,
    but I'm not found info about this topic)

At last, if you want to use all this, in your page you should do something
like this:


<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t"%>
<%@ taglib uri="http://myfaces.apache.org/trinidad/html" prefix="trh"%>

<html>
    <f:view>
    <head>
    <trh:styleSheet/> <!-- I only enabled this component and <tr:document>
tag -->
    </head>
    <body>

    ......
    </body>
</html>


    5. QUESTION: I have seen the following message in the log file of Jboss

    19:32:42,765 ERROR [HtmlResponseStateManager] No component states to be
saved in
     client response!

    I think that this is because I'm not using trinidad components.
    ¿It is a real error?

    6. QUESTION: If I want to combine javascript + css, ¿Does trinidad have
a mechanism to
    do this?. or i have to mix tomahawk mechanism?

    7. FINAL QUESTION: My intention is to add skinning capabilities to non
trinidad
    components. But I ignore if you can o want to use trinidad and
non-trinidad components mixed
    (example: tomahawk + trinidad). With the decorator pattern I think that
it's possible
    to do this operation: [[html_base + tomahawk + trinidad] * skins]. And
with some much more work
    do crazy things like (here I'm speculating and I'm dreaming a lot)
    [[html_base + tomahawk + trinidad + tobago] * skins] (combining tobago
skins).

    It is desirable to get this operation [[html_base + tomahawk + trinidad]
* skins]?

Well, that is all I want to ask to the community about this for now.

All suggestions are welcome.

Att: Leonardo Uribe