You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by Obinna <ob...@gmail.com> on 2009/02/04 08:24:31 UTC

Pluggable themes for JavaTemplates plugin

Hi,

I'd like to know if there's a 'recommended' way of extending the
javatemplates theme.
I've been using the default freemarker templates and have developed a few
custom tag templates for some custom tags. I'm eager to port to
javatemplates.

I noticed that the SimpleTheme is 'hard-coded' in the JavaTemplateEngine
like:

 private Themes themes = new Themes() {{
        add(new SimpleTheme());
    }};

which doesn't really allow for registering new themes. I can suggest a theme
plugin/registry but wondered if it's already been considered. There should
also be a pluggable way of  adding Handlers to a theme.


- Eric

Re: Pluggable themes for JavaTemplates plugin

Posted by Philip Luppens <ph...@gmail.com>.
On Wed, Feb 4, 2009 at 4:45 PM, Musachy Barroso <mu...@gmail.com> wrote:
> Do you want to implement the plugin using Java instead of FreeMarker?
> Unless the output is very simple, generating javascript from java will
> be a pain to write and maintain.

JQuery/MooTools/Prototype/.. + external S2 libraries added via the
head tag, to the rescue ! ;-)

Other than that, I agree: a nice extension tutorial for extending or
overriding the Java templates would be a good idea.

Phil

>
> musachy
>
> On Wed, Feb 4, 2009 at 10:30 AM, Obinna <ob...@gmail.com> wrote:
>> Hi James, Thanks for getting back so quickly.
>>
>> I see two major areas of extensibility required:
>> 1) Allow plugging in of custom themes
>> 2) Allow for easy extensibility/re-use of existing themes (currently
>> SimpleTheme or DefaultTheme)
>>
>> 1) We need a way of specifying custom themes to the JavaTemplateEngine via
>> configuration. For now, the best I can come up with is a new struts
>> configuration constant that takes a comma-delimited list of theme names
>>   as its value.
>>
>>    So lets add something like the following constant to StrutsConstants:
>>
>>            /** Custom theme classes for the javatemplates rendering engine
>> */
>>            public static final String STRUTS_JAVATEMPLATES_CUSTOM_THEMES =
>> "struts.javatemplates.customThemes";
>>
>>    We can then specify in our struts.xml
>>
>>            <constant name="struts.javatemplates.customThemes"
>> value="com.example.ui.struts2.MyCustomJavaTheme" />
>>
>>    and add to the JavaTemplateEngine class
>>
>>            /**
>>             * Allows for providing custom theme classes (implementations of
>> the org.apache.struts2.views.java.Theme) interface
>>             * for custom rendering of tags using the javatemplates engine
>>             * @param themeClasses a comma delimited list of custom theme
>> class names
>>             */
>>            @Inject(StrutsConstants.STRUTS_JAVATEMPLATES_CUSTOM_THEMES)
>>            public void setThemeClasses(String themeClasses) {
>>
>>                StringTokenizer customThemes = new
>> StringTokenizer(themeClasses, ",");
>>
>>                while (customThemes.hasMoreTokens()) {
>>                    String themeClass = customThemes.nextToken().trim();
>>                    try {
>>                        LOG.info("Registering custom theme '" + themeClass +
>> "' to javatemplates engine");
>>
>>
>>                        //FIXME: This means Themes must have no-arg
>> constructor - should use object factory here
>>
>> //ObjectFactory.getObjectFactory().buildBean(ClassLoaderUtil.loadClass(themeClass,
>> getClass()), null);
>>
>> themes.add((Theme)ClassLoaderUtil.loadClass(themeClass,
>> getClass()).newInstance());
>>
>>                    } catch (ClassCastException cce) {
>>                        LOG.error("Invalid java them class '" + themeClass +
>> "'. Class does not implement 'org.apache.struts2.views.java.Theme'
>> interface");
>>                    } catch (ClassNotFoundException cnf) {
>>                        LOG.error("Invalid java theme class '" + themeClass
>> + "'. Class not found");
>>                    } catch (Exception e) {
>>                        LOG.error("Could not find messages file " +
>> themeClass + ".properties. Skipping");
>>                    }
>>                }
>>            }
>>
>>
>>    For the custom theme implemetations, most will probably extend
>> SimpleTheme/DefaultTheme and simply insert/remove component handlers in
>> their desired sequence and perhaps provide
>>    a different (or additional) serializer.
>>    so it would be nice to:
>>
>>        - lower the  protection level on some of the methods/members to
>> protected
>>
>>            (eg. make DefaultTheme.handlerFactories protected, make
>> FactoryList inner-class protected or a separate public class)
>>
>>        - provide some utility methods. For example:
>>
>>                Add to DefaultTheme class:
>>
>>                     /**
>>                     * Set (replace if exists) the tag handler factories for
>> specific tag
>>                     * @param tagName
>>                     * @param handlers
>>                     */
>>                    protected void setTagHandlerFactories(String tagName,
>> List<TagHandlerFactory> handlers) {
>>                        if(tagName != null && handlers != null &&
>> this.handlerFactories != null) {
>>
>>                            handlerFactories.put(tagName,handlers);
>>                        }
>>                    }
>>
>>                    /**
>>                     * Insert a new tag handler into a sequence of tag
>> handlers for a specific tag
>>                     * TODO: Need to take care of serializers, if handler
>> specified is not a TagSerializer it should never
>>                     * be placed after the serializer, but if it is not a
>> TagSerializer, it should never
>>                     * @param tagName
>>                     * @param sequence
>>                     * @param factory
>>                     */
>>                    protected void insertTagHandlerFactory(String tagName,
>> int sequence, TagHandlerFactory factory) {
>>
>>                        if(tagName != null && factory != null  &&
>> this.handlerFactories != null) {
>>
>>                            List<TagHandlerFactory> tagHandlerFactories =
>> handlerFactories.get(tagName);
>>
>>                            if(tagHandlerFactories == null) {
>>                                    tagHandlerFactories = new
>> ArrayList<TagHandlerFactory>(); //TODO: Could use public FactoryList here
>>                            }
>>
>>                            if(sequence > tagHandlerFactories.size()) {
>>                                sequence = tagHandlerFactories.size();
>>                            }
>>
>>                            //TODO, need to account for TagHandlers vs.
>> TagSerializers here
>>                            tagHandlerFactories.add(sequence, factory);
>>                        }
>>                }
>>
>>        - Allow multiple TagSerializers (make sure framework supports
>> chaining serizliers). For example, in my application I'd like to add a
>> serializer which writes some javascript (think Ajax event binding)
>>            after
>>
>>        - The way the serializers are registered simply as the last handler
>> is neat, but it may cause some trouble when developers extend the themes and
>> iject their own handlers, perhaps
>>            I like the chaining, so perhaps this should simply be accounted
>> for carefully in the utiolity methods (such as the insertTagHandlerFactory()
>> method i suggested above) and in the
>>            renderTag() method of the DefaultTheme.
>>
>>        - DefaultTheme could probably be an abstract class and maybe called
>> somehting like AbstractTheme or AbstractThemeSupport
>>
>>
>> Incidentally, the reason I am looking into this is because I am starting to
>> write a jQuery Ajax plugin (given the imminent deprecation of dojo, which I
>> never really liked so much anyway - too large and clunky)
>> I'm not sure how far I'll get on this, but I'm currently optimistic.
>>
>> Best,
>> Eric
>>
>> On Wed, Feb 4, 2009 at 4:26 PM, James Holmes <ja...@jamesholmes.com> wrote:
>>
>>> I don't know if any plugging mechanism for themes has been discussed.
>>> Please
>>> send us your thoughts.
>>>
>>> On Wed, Feb 4, 2009 at 2:24 AM, Obinna <ob...@gmail.com> wrote:
>>>
>>> > Hi,
>>> >
>>> > I'd like to know if there's a 'recommended' way of extending the
>>> > javatemplates theme.
>>> > I've been using the default freemarker templates and have developed a few
>>> > custom tag templates for some custom tags. I'm eager to port to
>>> > javatemplates.
>>> >
>>> > I noticed that the SimpleTheme is 'hard-coded' in the JavaTemplateEngine
>>> > like:
>>> >
>>> >  private Themes themes = new Themes() {{
>>> >        add(new SimpleTheme());
>>> >    }};
>>> >
>>> > which doesn't really allow for registering new themes. I can suggest a
>>> > theme
>>> > plugin/registry but wondered if it's already been considered. There
>>> should
>>> > also be a pluggable way of  adding Handlers to a theme.
>>> >
>>> >
>>> > - Eric
>>> >
>>>
>>
>
>
>
> --
> "Hey you! Would you help me to carry the stone?" Pink Floyd
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
> For additional commands, e-mail: dev-help@struts.apache.org
>
>



-- 
"We cannot change the cards we are dealt, just how we play the hand."
- Randy Pausch

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Pluggable themes for JavaTemplates plugin

Posted by Musachy Barroso <mu...@gmail.com>.
> Nonethess, it makes sense to  make the java templates extensible. I can see plently of developers using
> them especially if they provide a performance boost as implied in the
> documentation. The way the chaining handlers are set up should make the
> implementation/maintenance manageable (I hope).

Yup, I agree.

>
> BTW, the trajectory for the dojo ajax tags was to use a different tag
> library (sx) for ajax enabled tags rather than triggering 'ajaxness' with a
> theme attribute (was 'ajax'). I assume this is still preferable for any
> other ajax library?

IMO Themes are better if we think that enough people will overwrite
them, if that is not the case, it is easier for users to just use a
different taglib (they can still overwrite the templates)

musachy

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Pluggable themes for JavaTemplates plugin

Posted by Obinna <ob...@gmail.com>.
Ultimately, I'd like to implement in both. I've already done some custom
themes for the ftl templates, so I know that will work but I'd like to use
the java templates as well, at least initially. Nonethess, it makes sense to

make the java templates extensible. I can see plently of developers using
them especially if they provide a performance boost as implied in the
documentation. The way the chaining handlers are set up should make the
implementation/maintenance manageable (I hope).

BTW, the trajectory for the dojo ajax tags was to use a different tag
library (sx) for ajax enabled tags rather than triggering 'ajaxness' with a
theme attribute (was 'ajax'). I assume this is still preferable for any
other ajax library?
What about the use of binding tags as opposed to ajax-enabled tags? Without
giving it too much thought it feels like binding tags cuold be used as the
ONLY way to specify ajaxness to struts tags, thereby decoupling the ajax
choice from the
plain-html even more. This wouldn't be true for the 'widget' tags though.
Taking this 'binding' to the extreme, a sort-of specification for binding
ajax features to standard struts tags (including perhaps standardized widget
tags - which may not be functional without the ) could be specified which
would allow for a relaly 'pluggable' implementation and use of different
ajax tags. Anyway, first things first...

- Eric


On Wed, Feb 4, 2009 at 6:45 PM, Musachy Barroso <mu...@gmail.com> wrote:

> Do you want to implement the plugin using Java instead of FreeMarker?
> Unless the output is very simple, generating javascript from java will
> be a pain to write and maintain.
>
> musachy
>
> On Wed, Feb 4, 2009 at 10:30 AM, Obinna <ob...@gmail.com> wrote:
> > Hi James, Thanks for getting back so quickly.
> >
> > I see two major areas of extensibility required:
> > 1) Allow plugging in of custom themes
> > 2) Allow for easy extensibility/re-use of existing themes (currently
> > SimpleTheme or DefaultTheme)
> >
> > 1) We need a way of specifying custom themes to the JavaTemplateEngine
> via
> > configuration. For now, the best I can come up with is a new struts
> > configuration constant that takes a comma-delimited list of theme names
> >   as its value.
> >
> >    So lets add something like the following constant to StrutsConstants:
> >
> >            /** Custom theme classes for the javatemplates rendering
> engine
> > */
> >            public static final String STRUTS_JAVATEMPLATES_CUSTOM_THEMES
> =
> > "struts.javatemplates.customThemes";
> >
> >    We can then specify in our struts.xml
> >
> >            <constant name="struts.javatemplates.customThemes"
> > value="com.example.ui.struts2.MyCustomJavaTheme" />
> >
> >    and add to the JavaTemplateEngine class
> >
> >            /**
> >             * Allows for providing custom theme classes (implementations
> of
> > the org.apache.struts2.views.java.Theme) interface
> >             * for custom rendering of tags using the javatemplates engine
> >             * @param themeClasses a comma delimited list of custom theme
> > class names
> >             */
> >            @Inject(StrutsConstants.STRUTS_JAVATEMPLATES_CUSTOM_THEMES)
> >            public void setThemeClasses(String themeClasses) {
> >
> >                StringTokenizer customThemes = new
> > StringTokenizer(themeClasses, ",");
> >
> >                while (customThemes.hasMoreTokens()) {
> >                    String themeClass = customThemes.nextToken().trim();
> >                    try {
> >                        LOG.info("Registering custom theme '" + themeClass
> +
> > "' to javatemplates engine");
> >
> >
> >                        //FIXME: This means Themes must have no-arg
> > constructor - should use object factory here
> >
> >
> //ObjectFactory.getObjectFactory().buildBean(ClassLoaderUtil.loadClass(themeClass,
> > getClass()), null);
> >
> > themes.add((Theme)ClassLoaderUtil.loadClass(themeClass,
> > getClass()).newInstance());
> >
> >                    } catch (ClassCastException cce) {
> >                        LOG.error("Invalid java them class '" + themeClass
> +
> > "'. Class does not implement 'org.apache.struts2.views.java.Theme'
> > interface");
> >                    } catch (ClassNotFoundException cnf) {
> >                        LOG.error("Invalid java theme class '" +
> themeClass
> > + "'. Class not found");
> >                    } catch (Exception e) {
> >                        LOG.error("Could not find messages file " +
> > themeClass + ".properties. Skipping");
> >                    }
> >                }
> >            }
> >
> >
> >    For the custom theme implemetations, most will probably extend
> > SimpleTheme/DefaultTheme and simply insert/remove component handlers in
> > their desired sequence and perhaps provide
> >    a different (or additional) serializer.
> >    so it would be nice to:
> >
> >        - lower the  protection level on some of the methods/members to
> > protected
> >
> >            (eg. make DefaultTheme.handlerFactories protected, make
> > FactoryList inner-class protected or a separate public class)
> >
> >        - provide some utility methods. For example:
> >
> >                Add to DefaultTheme class:
> >
> >                     /**
> >                     * Set (replace if exists) the tag handler factories
> for
> > specific tag
> >                     * @param tagName
> >                     * @param handlers
> >                     */
> >                    protected void setTagHandlerFactories(String tagName,
> > List<TagHandlerFactory> handlers) {
> >                        if(tagName != null && handlers != null &&
> > this.handlerFactories != null) {
> >
> >                            handlerFactories.put(tagName,handlers);
> >                        }
> >                    }
> >
> >                    /**
> >                     * Insert a new tag handler into a sequence of tag
> > handlers for a specific tag
> >                     * TODO: Need to take care of serializers, if handler
> > specified is not a TagSerializer it should never
> >                     * be placed after the serializer, but if it is not a
> > TagSerializer, it should never
> >                     * @param tagName
> >                     * @param sequence
> >                     * @param factory
> >                     */
> >                    protected void insertTagHandlerFactory(String tagName,
> > int sequence, TagHandlerFactory factory) {
> >
> >                        if(tagName != null && factory != null  &&
> > this.handlerFactories != null) {
> >
> >                            List<TagHandlerFactory> tagHandlerFactories =
> > handlerFactories.get(tagName);
> >
> >                            if(tagHandlerFactories == null) {
> >                                    tagHandlerFactories = new
> > ArrayList<TagHandlerFactory>(); //TODO: Could use public FactoryList here
> >                            }
> >
> >                            if(sequence > tagHandlerFactories.size()) {
> >                                sequence = tagHandlerFactories.size();
> >                            }
> >
> >                            //TODO, need to account for TagHandlers vs.
> > TagSerializers here
> >                            tagHandlerFactories.add(sequence, factory);
> >                        }
> >                }
> >
> >        - Allow multiple TagSerializers (make sure framework supports
> > chaining serizliers). For example, in my application I'd like to add a
> > serializer which writes some javascript (think Ajax event binding)
> >            after
> >
> >        - The way the serializers are registered simply as the last
> handler
> > is neat, but it may cause some trouble when developers extend the themes
> and
> > iject their own handlers, perhaps
> >            I like the chaining, so perhaps this should simply be
> accounted
> > for carefully in the utiolity methods (such as the
> insertTagHandlerFactory()
> > method i suggested above) and in the
> >            renderTag() method of the DefaultTheme.
> >
> >        - DefaultTheme could probably be an abstract class and maybe
> called
> > somehting like AbstractTheme or AbstractThemeSupport
> >
> >
> > Incidentally, the reason I am looking into this is because I am starting
> to
> > write a jQuery Ajax plugin (given the imminent deprecation of dojo, which
> I
> > never really liked so much anyway - too large and clunky)
> > I'm not sure how far I'll get on this, but I'm currently optimistic.
> >
> > Best,
> > Eric
> >
> > On Wed, Feb 4, 2009 at 4:26 PM, James Holmes <ja...@jamesholmes.com>
> wrote:
> >
> >> I don't know if any plugging mechanism for themes has been discussed.
> >> Please
> >> send us your thoughts.
> >>
> >> On Wed, Feb 4, 2009 at 2:24 AM, Obinna <ob...@gmail.com> wrote:
> >>
> >> > Hi,
> >> >
> >> > I'd like to know if there's a 'recommended' way of extending the
> >> > javatemplates theme.
> >> > I've been using the default freemarker templates and have developed a
> few
> >> > custom tag templates for some custom tags. I'm eager to port to
> >> > javatemplates.
> >> >
> >> > I noticed that the SimpleTheme is 'hard-coded' in the
> JavaTemplateEngine
> >> > like:
> >> >
> >> >  private Themes themes = new Themes() {{
> >> >        add(new SimpleTheme());
> >> >    }};
> >> >
> >> > which doesn't really allow for registering new themes. I can suggest a
> >> > theme
> >> > plugin/registry but wondered if it's already been considered. There
> >> should
> >> > also be a pluggable way of  adding Handlers to a theme.
> >> >
> >> >
> >> > - Eric
> >> >
> >>
> >
>
>
>
> --
> "Hey you! Would you help me to carry the stone?" Pink Floyd
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
> For additional commands, e-mail: dev-help@struts.apache.org
>
>

Re: Pluggable themes for JavaTemplates plugin

Posted by Musachy Barroso <mu...@gmail.com>.
Do you want to implement the plugin using Java instead of FreeMarker?
Unless the output is very simple, generating javascript from java will
be a pain to write and maintain.

musachy

On Wed, Feb 4, 2009 at 10:30 AM, Obinna <ob...@gmail.com> wrote:
> Hi James, Thanks for getting back so quickly.
>
> I see two major areas of extensibility required:
> 1) Allow plugging in of custom themes
> 2) Allow for easy extensibility/re-use of existing themes (currently
> SimpleTheme or DefaultTheme)
>
> 1) We need a way of specifying custom themes to the JavaTemplateEngine via
> configuration. For now, the best I can come up with is a new struts
> configuration constant that takes a comma-delimited list of theme names
>   as its value.
>
>    So lets add something like the following constant to StrutsConstants:
>
>            /** Custom theme classes for the javatemplates rendering engine
> */
>            public static final String STRUTS_JAVATEMPLATES_CUSTOM_THEMES =
> "struts.javatemplates.customThemes";
>
>    We can then specify in our struts.xml
>
>            <constant name="struts.javatemplates.customThemes"
> value="com.example.ui.struts2.MyCustomJavaTheme" />
>
>    and add to the JavaTemplateEngine class
>
>            /**
>             * Allows for providing custom theme classes (implementations of
> the org.apache.struts2.views.java.Theme) interface
>             * for custom rendering of tags using the javatemplates engine
>             * @param themeClasses a comma delimited list of custom theme
> class names
>             */
>            @Inject(StrutsConstants.STRUTS_JAVATEMPLATES_CUSTOM_THEMES)
>            public void setThemeClasses(String themeClasses) {
>
>                StringTokenizer customThemes = new
> StringTokenizer(themeClasses, ",");
>
>                while (customThemes.hasMoreTokens()) {
>                    String themeClass = customThemes.nextToken().trim();
>                    try {
>                        LOG.info("Registering custom theme '" + themeClass +
> "' to javatemplates engine");
>
>
>                        //FIXME: This means Themes must have no-arg
> constructor - should use object factory here
>
> //ObjectFactory.getObjectFactory().buildBean(ClassLoaderUtil.loadClass(themeClass,
> getClass()), null);
>
> themes.add((Theme)ClassLoaderUtil.loadClass(themeClass,
> getClass()).newInstance());
>
>                    } catch (ClassCastException cce) {
>                        LOG.error("Invalid java them class '" + themeClass +
> "'. Class does not implement 'org.apache.struts2.views.java.Theme'
> interface");
>                    } catch (ClassNotFoundException cnf) {
>                        LOG.error("Invalid java theme class '" + themeClass
> + "'. Class not found");
>                    } catch (Exception e) {
>                        LOG.error("Could not find messages file " +
> themeClass + ".properties. Skipping");
>                    }
>                }
>            }
>
>
>    For the custom theme implemetations, most will probably extend
> SimpleTheme/DefaultTheme and simply insert/remove component handlers in
> their desired sequence and perhaps provide
>    a different (or additional) serializer.
>    so it would be nice to:
>
>        - lower the  protection level on some of the methods/members to
> protected
>
>            (eg. make DefaultTheme.handlerFactories protected, make
> FactoryList inner-class protected or a separate public class)
>
>        - provide some utility methods. For example:
>
>                Add to DefaultTheme class:
>
>                     /**
>                     * Set (replace if exists) the tag handler factories for
> specific tag
>                     * @param tagName
>                     * @param handlers
>                     */
>                    protected void setTagHandlerFactories(String tagName,
> List<TagHandlerFactory> handlers) {
>                        if(tagName != null && handlers != null &&
> this.handlerFactories != null) {
>
>                            handlerFactories.put(tagName,handlers);
>                        }
>                    }
>
>                    /**
>                     * Insert a new tag handler into a sequence of tag
> handlers for a specific tag
>                     * TODO: Need to take care of serializers, if handler
> specified is not a TagSerializer it should never
>                     * be placed after the serializer, but if it is not a
> TagSerializer, it should never
>                     * @param tagName
>                     * @param sequence
>                     * @param factory
>                     */
>                    protected void insertTagHandlerFactory(String tagName,
> int sequence, TagHandlerFactory factory) {
>
>                        if(tagName != null && factory != null  &&
> this.handlerFactories != null) {
>
>                            List<TagHandlerFactory> tagHandlerFactories =
> handlerFactories.get(tagName);
>
>                            if(tagHandlerFactories == null) {
>                                    tagHandlerFactories = new
> ArrayList<TagHandlerFactory>(); //TODO: Could use public FactoryList here
>                            }
>
>                            if(sequence > tagHandlerFactories.size()) {
>                                sequence = tagHandlerFactories.size();
>                            }
>
>                            //TODO, need to account for TagHandlers vs.
> TagSerializers here
>                            tagHandlerFactories.add(sequence, factory);
>                        }
>                }
>
>        - Allow multiple TagSerializers (make sure framework supports
> chaining serizliers). For example, in my application I'd like to add a
> serializer which writes some javascript (think Ajax event binding)
>            after
>
>        - The way the serializers are registered simply as the last handler
> is neat, but it may cause some trouble when developers extend the themes and
> iject their own handlers, perhaps
>            I like the chaining, so perhaps this should simply be accounted
> for carefully in the utiolity methods (such as the insertTagHandlerFactory()
> method i suggested above) and in the
>            renderTag() method of the DefaultTheme.
>
>        - DefaultTheme could probably be an abstract class and maybe called
> somehting like AbstractTheme or AbstractThemeSupport
>
>
> Incidentally, the reason I am looking into this is because I am starting to
> write a jQuery Ajax plugin (given the imminent deprecation of dojo, which I
> never really liked so much anyway - too large and clunky)
> I'm not sure how far I'll get on this, but I'm currently optimistic.
>
> Best,
> Eric
>
> On Wed, Feb 4, 2009 at 4:26 PM, James Holmes <ja...@jamesholmes.com> wrote:
>
>> I don't know if any plugging mechanism for themes has been discussed.
>> Please
>> send us your thoughts.
>>
>> On Wed, Feb 4, 2009 at 2:24 AM, Obinna <ob...@gmail.com> wrote:
>>
>> > Hi,
>> >
>> > I'd like to know if there's a 'recommended' way of extending the
>> > javatemplates theme.
>> > I've been using the default freemarker templates and have developed a few
>> > custom tag templates for some custom tags. I'm eager to port to
>> > javatemplates.
>> >
>> > I noticed that the SimpleTheme is 'hard-coded' in the JavaTemplateEngine
>> > like:
>> >
>> >  private Themes themes = new Themes() {{
>> >        add(new SimpleTheme());
>> >    }};
>> >
>> > which doesn't really allow for registering new themes. I can suggest a
>> > theme
>> > plugin/registry but wondered if it's already been considered. There
>> should
>> > also be a pluggable way of  adding Handlers to a theme.
>> >
>> >
>> > - Eric
>> >
>>
>



-- 
"Hey you! Would you help me to carry the stone?" Pink Floyd

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Pluggable themes for JavaTemplates plugin

Posted by Obinna <ob...@gmail.com>.
Hi James, Thanks for getting back so quickly.

I see two major areas of extensibility required:
1) Allow plugging in of custom themes
2) Allow for easy extensibility/re-use of existing themes (currently
SimpleTheme or DefaultTheme)

1) We need a way of specifying custom themes to the JavaTemplateEngine via
configuration. For now, the best I can come up with is a new struts
configuration constant that takes a comma-delimited list of theme names
   as its value.

    So lets add something like the following constant to StrutsConstants:

            /** Custom theme classes for the javatemplates rendering engine
*/
            public static final String STRUTS_JAVATEMPLATES_CUSTOM_THEMES =
"struts.javatemplates.customThemes";

    We can then specify in our struts.xml

            <constant name="struts.javatemplates.customThemes"
value="com.example.ui.struts2.MyCustomJavaTheme" />

    and add to the JavaTemplateEngine class

            /**
             * Allows for providing custom theme classes (implementations of
the org.apache.struts2.views.java.Theme) interface
             * for custom rendering of tags using the javatemplates engine
             * @param themeClasses a comma delimited list of custom theme
class names
             */
            @Inject(StrutsConstants.STRUTS_JAVATEMPLATES_CUSTOM_THEMES)
            public void setThemeClasses(String themeClasses) {

                StringTokenizer customThemes = new
StringTokenizer(themeClasses, ",");

                while (customThemes.hasMoreTokens()) {
                    String themeClass = customThemes.nextToken().trim();
                    try {
                        LOG.info("Registering custom theme '" + themeClass +
"' to javatemplates engine");


                        //FIXME: This means Themes must have no-arg
constructor - should use object factory here

//ObjectFactory.getObjectFactory().buildBean(ClassLoaderUtil.loadClass(themeClass,
getClass()), null);

themes.add((Theme)ClassLoaderUtil.loadClass(themeClass,
getClass()).newInstance());

                    } catch (ClassCastException cce) {
                        LOG.error("Invalid java them class '" + themeClass +
"'. Class does not implement 'org.apache.struts2.views.java.Theme'
interface");
                    } catch (ClassNotFoundException cnf) {
                        LOG.error("Invalid java theme class '" + themeClass
+ "'. Class not found");
                    } catch (Exception e) {
                        LOG.error("Could not find messages file " +
themeClass + ".properties. Skipping");
                    }
                }
            }


    For the custom theme implemetations, most will probably extend
SimpleTheme/DefaultTheme and simply insert/remove component handlers in
their desired sequence and perhaps provide
    a different (or additional) serializer.
    so it would be nice to:

        - lower the  protection level on some of the methods/members to
protected

            (eg. make DefaultTheme.handlerFactories protected, make
FactoryList inner-class protected or a separate public class)

        - provide some utility methods. For example:

                Add to DefaultTheme class:

                     /**
                     * Set (replace if exists) the tag handler factories for
specific tag
                     * @param tagName
                     * @param handlers
                     */
                    protected void setTagHandlerFactories(String tagName,
List<TagHandlerFactory> handlers) {
                        if(tagName != null && handlers != null &&
this.handlerFactories != null) {

                            handlerFactories.put(tagName,handlers);
                        }
                    }

                    /**
                     * Insert a new tag handler into a sequence of tag
handlers for a specific tag
                     * TODO: Need to take care of serializers, if handler
specified is not a TagSerializer it should never
                     * be placed after the serializer, but if it is not a
TagSerializer, it should never
                     * @param tagName
                     * @param sequence
                     * @param factory
                     */
                    protected void insertTagHandlerFactory(String tagName,
int sequence, TagHandlerFactory factory) {

                        if(tagName != null && factory != null  &&
this.handlerFactories != null) {

                            List<TagHandlerFactory> tagHandlerFactories =
handlerFactories.get(tagName);

                            if(tagHandlerFactories == null) {
                                    tagHandlerFactories = new
ArrayList<TagHandlerFactory>(); //TODO: Could use public FactoryList here
                            }

                            if(sequence > tagHandlerFactories.size()) {
                                sequence = tagHandlerFactories.size();
                            }

                            //TODO, need to account for TagHandlers vs.
TagSerializers here
                            tagHandlerFactories.add(sequence, factory);
                        }
                }

        - Allow multiple TagSerializers (make sure framework supports
chaining serizliers). For example, in my application I'd like to add a
serializer which writes some javascript (think Ajax event binding)
            after

        - The way the serializers are registered simply as the last handler
is neat, but it may cause some trouble when developers extend the themes and
iject their own handlers, perhaps
            I like the chaining, so perhaps this should simply be accounted
for carefully in the utiolity methods (such as the insertTagHandlerFactory()
method i suggested above) and in the
            renderTag() method of the DefaultTheme.

        - DefaultTheme could probably be an abstract class and maybe called
somehting like AbstractTheme or AbstractThemeSupport


Incidentally, the reason I am looking into this is because I am starting to
write a jQuery Ajax plugin (given the imminent deprecation of dojo, which I
never really liked so much anyway - too large and clunky)
I'm not sure how far I'll get on this, but I'm currently optimistic.

Best,
Eric

On Wed, Feb 4, 2009 at 4:26 PM, James Holmes <ja...@jamesholmes.com> wrote:

> I don't know if any plugging mechanism for themes has been discussed.
> Please
> send us your thoughts.
>
> On Wed, Feb 4, 2009 at 2:24 AM, Obinna <ob...@gmail.com> wrote:
>
> > Hi,
> >
> > I'd like to know if there's a 'recommended' way of extending the
> > javatemplates theme.
> > I've been using the default freemarker templates and have developed a few
> > custom tag templates for some custom tags. I'm eager to port to
> > javatemplates.
> >
> > I noticed that the SimpleTheme is 'hard-coded' in the JavaTemplateEngine
> > like:
> >
> >  private Themes themes = new Themes() {{
> >        add(new SimpleTheme());
> >    }};
> >
> > which doesn't really allow for registering new themes. I can suggest a
> > theme
> > plugin/registry but wondered if it's already been considered. There
> should
> > also be a pluggable way of  adding Handlers to a theme.
> >
> >
> > - Eric
> >
>

Re: Pluggable themes for JavaTemplates plugin

Posted by James Holmes <ja...@jamesholmes.com>.
I don't know if any plugging mechanism for themes has been discussed. Please
send us your thoughts.

On Wed, Feb 4, 2009 at 2:24 AM, Obinna <ob...@gmail.com> wrote:

> Hi,
>
> I'd like to know if there's a 'recommended' way of extending the
> javatemplates theme.
> I've been using the default freemarker templates and have developed a few
> custom tag templates for some custom tags. I'm eager to port to
> javatemplates.
>
> I noticed that the SimpleTheme is 'hard-coded' in the JavaTemplateEngine
> like:
>
>  private Themes themes = new Themes() {{
>        add(new SimpleTheme());
>    }};
>
> which doesn't really allow for registering new themes. I can suggest a
> theme
> plugin/registry but wondered if it's already been considered. There should
> also be a pluggable way of  adding Handlers to a theme.
>
>
> - Eric
>