tiles-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicolas LE BAS <m...@nlebas.net>
Subject Re: Tiles decoration/run time composition/interaction between tiles
Date Sun, 08 Apr 2012 12:32:52 GMT
So you're basically trying to render a form for generically editing a 
java bean, while looking up the bean properties by reflection. A complex 
situation indeed.

On 12-04-07 10:19 PM, Ken McWilliams wrote:
> I'm not sure how tiles works exactly... each jsp renders its view and then
> is composed into a single document? If so, is it possible to alter the
> template while the JSPs are rendering?

Tiles works like some sort of elaborate jsp:include: a "view" is a tiles 
definition associated with a template (a JSP) and attributes 
(expressions). The template jsp:includes the attributes. Except you can 
define inheritance on the tiles definition and override the attributes 
of the parent, like you would with methods on a java class. Or you can 
override the attributes at runtime.

I'm not sure exactly how much tiles would help in your situation, that 
would depend on how much code can be reused between various "type" editors.

What I would do is:

1. one tile definition for each type / each editing mode. That's where 
Tiles can help you in not duplicating the code. Then you could do 
something like:

<ken:typedefinitions name="basicSet">
     <s:iterator value="#both" var="cur">
        <s:if test="getters.contains(cur) && setters.contains(cur)">
           <tiles:insertDefinition name="editor.${cur.type}.rw">
               <tiles:putAttribute name="value" expression="${cur.value}"/>
           </tiles:insertDefinition>
        </s:if>
        <s:elseif test="getters.contains(cur)">
           <tiles:insertDefinition name="editor.${cur.type}.r"/>
               <tiles:putAttribute name="value" expression="${cur.value}"/>
           </tiles:insertDefinition>
        </s:elseif>
        <s:else>
           <tiles:insertDefinition name="editor.${cur.type}.w"/>
               <tiles:putAttribute name="value" expression="${cur.value}"/>
           </tiles:insertDefinition>
        </s:else>
     </s:iterator>
</ken:>

2. If you feel like optimizing it... the above code looks up the getters 
and setters every time the view is rendered. I guess you're looking up 
other things, too (like validation conditions). But those things depend 
only on the class of the entity being edited, so it could be looked up 
beforehand, at startup time or at compile time.

Then the code could look like:
<tiles:insertDefinition name="form.${model.class}">
    <tiles:putAttribute name="value" expression="${model}" />
</tiles:insertDefinition>

with
<<<tiles.xml>>>
<definition name="abstractform" 
template="jsp-with-iterator-over-editor.jsp">
</definition>
<definition name="form.user" extends="abstractform">
   <put-list-attribute name="get">
      <add-attribute value="login"/>
      <add-attribute value="firstName"/>
      <add-attribute value="lastName"/>
   </put-list-attribute>
   <put-list-attribute name="set">
      <add-attribute value="firstName"/>
      <add-attribute value="lastName"/>
   </put-list-attribute>
   ...
</definition>

Generating the "form.${class}" definitions could be done at startup time 
with a custom DefinitionFactory (actually a wrapper) or at compile time 
with an annotation processor (if you're using java 6).

3. The JS/css part is actually more difficult. There is no way a single 
tag can generate content in both <head> and <body> sections, so you 
would need at least another <tiles:insert> tag, or possibly you could 
use a tiles definition to generate js/css instead of html (although I'd 
advise using freemarker or velocity for that, since JSP can be painful 
with anything not XML).
But what I would do is simply create a JS and a CSS file that deals with 
all possible cases based on a CSS class. That would work the same for 
CSS and jQuery, and would be cacheable by the browser.

Hope this helps,
Nick.

Mime
View raw message