You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Werner Punz <we...@gmail.com> on 2008/10/04 10:57:54 UTC
Another approach to the templating problem
Hello everyone
I have developed another approach to the templating problem.
Most solutions which tried to tackle the approach worked on interepted
template level:
https://issues.apache.org/jira/browse/TOMAHAWK-1327
I did another approach the last few weeks
I made an embedded templating compiler for java
I did it due to the inherent speed hits we have by using existing
templating solutions and due to the fact that I want to parts of the
code in the dojo components project over to templates to increase
readability:
What I did was to develop with antlr some mini velocity which can be
embedded into java via special comments.
The advantage is, that you simply can embed your templates inline via
a comment flag you can work on valid java code while still having your
templating code in one place. It is more or less an inverse scriptlet
system to be usable from java.
I will give an example
public class SimpleTest {
static String helloWorld = "hello world";
private calledMethod() {
System.out.println("called function");
}
public void emitTemplate() {
String [] values = new String[5];
values[0] = "value0";
values[1] = "value1";
values[2] = "value2";
values[3] = "value3";
values[4] = "value4";
/*TPL
#outputop(System.out.println)
This is a test for a simple embedded template
$helloWorld
<table>
<tbody>
#each(String, $values)
</tr><td>$it</td></tr>
#end
calling a method
$this.calledMethod();
this text should follow after table!
TPL*/
}
}
This code is then basically rendered against
the output System.out.println
(other output directives can given via an
#outputop(<output directive>)
command in the template!
I know this approach is not academic due to no MVC
and due to extended control commands like iterations and selections
within the language and the possibility to call external methods
within the template.
The advantage however is, the strings are rendered straight into
output directives almost like handwritten code, by avoiding
introspection I can gain similar speeds
(however with the disadvantage that you have to pass a casting datatype
into the #for and #each loops)
But if the community would like it I would merge it into our
utils project next week. Otherwise I can drop it somewhere else.
Werner
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Another thing, since the code i wrote is not directly JSF related
but is a generic approach of java multiline templating,
should we even host it at MyFaces?
Another option would be to have it as a self hosting project
on sourceforge or java.net
an existing build process in MyFaces still could fetch the
maven plugin (which comes with the compiler) via maven
and a java.net repo reference.
Werner
Andrew Robinson schrieb:
>> But the problem persists, how are we going to improve the readability of the
>> rendered code and how do we maintain the much needed speed on component
>> level?
>
> A very good question. I wonder if there is a way to get JSP-like
> runtime compilation of HTML template code and have that compiled code
> get as close to being inside the renderer as possible. Using XML isn't
> that bad for performance if the DOM is cached, but then that puts a
> nice overhead on the heap. Developing components myself, I find the
> experience very frustrating as maven builds and redeployments tend to
> be very slow. I think this is why most web sites are written in perl,
> php or python, there is no redeployment necessary, just immediate
> gratification.
>
> I wonder if groovy, jython or some other "java script" language could
> be leveraged to be able to author in external files but have it become
> java byte code to be able to go directly into the JIT? I don't have a
> good solution as I don't like JSF renderers for speed and convenience
> of development, but also don't like on-the-fly interpretation for
> speed reasons.
>
> Anyone have a profound thought?
>
>>
>> Werner
>>
>>
>>
>
Re: Another approach to the templating problem
Posted by Leonardo Uribe <lu...@gmail.com>.
On Sun, Oct 19, 2008 at 6:17 PM, Leonardo Uribe <lu...@gmail.com> wrote:
> Hi
>
> Based on the previous discussion, and with the intention of develop other
> alternatives to this problem (if you want it do
> it yourself), I have attached a possible solution for this problem. (code
> available on TOMAHAWK-1327 file
> RendererGenerationUsingXSLT.zip)
>
> The strategy used was generate from a xhtml file a java renderer file
> (*.java), using a xslt transformation. The code is
> integrated with myfaces-builder-plugin to trigger renderer generation,
> using a plugin.
>
> In other words, the idea is generate from this:
>
> <span style="@@style@@" class="@@styleClass@@" content="@@content@@"/>
>
> something like this:
>
> writer.startElement("span", component);
> writer.writeAttribute("style", style, null);
> writer.writeAttribute("class", styleClass, null);
> writer.writeText("content", content, null);
> writer.endElement("span");
>
> The elements that needs to be defined are:
>
> 1. Define a abstract renderer class like this (the class pointed on class
> attribute of @JSFRenderer is the file to generate):
>
> /**
> * @JSFRenderer
> * renderKitId = "HTML_BASIC"
> * family = "javax.faces.Output"
> * type = "org.myorganization.SayHelloRenderer"
> * class = "org.myorganization.component.sayhello.SayHelloRenderer"
> */
> public abstract class AbstractSayHelloRenderer extends Renderer
> {
> .....
>
> //The method to generate, the body is defined on a xhtml file
> public abstract void encodeSomeHtmlOrJavascriptPart(FacesContext
> context, UIComponent component) throws IOException;
>
> }
>
> 2. Define a xhtml file called
> src/main/resources/org/myorganization/component/sayhello/SayHelloRenderer.xhtml
>
> <!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:mbp="http://myfaces.apache.org/mbp">
> <mbp:import>javax.faces.component.UIComponent</mbp:import>
> <mbp:import>javax.faces.context.FacesContext</mbp:import>
> <mbp:import>javax.faces.context.ResponseWriter</mbp:import>
> <mbp:import>javax.faces.render.Renderer</mbp:import>
> <mbp:import>java.io.IOException</mbp:import>
> <body>
> <mbp:renderMethod
> signature="public void void encodeSomeHtmlOrJavascriptPart(FacesContext
> context, SayHelloComponent component) throws IOException"
> writerVar="writer" componentVar="component">
> <mbp:scriptlet>ResponseWriter writer = context.getResponseWriter();
> </mbp:scriptlet>
> <!-- HERE GOES SOME HTML OR JAVASCRIPT CODE TO BE COMPILED TO JAVA
> SOURCE CODE -->
> <span style="@@component.getStyle()@@"
> class="@@component.getStyle()@@">@@component.getContent()@@</span>
> </script>
> </mbp:renderMethod>
> </body>
> </html>
>
> 3. Use myfaces-builder-plugin (see code on TOMAHAWK-1327 for details).
>
> On TOMAHAWK-1327 file RendererGenerationUsingXSLT.zip there is a more
> elaborated example using s:togglePanel as
> base (see directory named "resume" for details about xhtml source file and
> java results).
>
> I'm trying to enhance it with more features and correct some bugs.
>
> If the community would like it I would merge it into
> myfaces-builder-plugin.
>
> Suggestions are welcome
>
If no suggestion I'll add this feature to myfaces-builder-plugin.
regards
Leonardo Uribe
>
> regards
>
> Leonardo Uribe
>
>
>
> On Tue, Oct 7, 2008 at 6:49 AM, Werner Punz <we...@gmail.com> wrote:
>
>> Ok to summarize this thread
>>
>>
>> Generelly the compiler is appreciated, but
>>
>> a) We need a jsp like mechanism for dynamic compilation of the source
>> templates, that should be doable, although it would mean modifications
>> within the source how the templates are called (probably loading them via a
>> utils class from the renderer)
>>
>> b) We need a more precise handling of the JSF APIs, that is much harder
>> than a) but I think it is solvable one way or the other
>> (probably by a second interpretion step which scans for tags and
>> also merges the incoming variable expressions into the mix.
>>
>> Anything else?
>>
>> Besides that one question is open. Do we host it within myfaces
>> or should I put it somewhere else (my preferrence would be java.net
>> outside of myfaces due to its maven support)
>>
>> If we host it within myfaces, I will take care of the codegrant today or
>> tomorrow and will start to work on the additional features after the code
>> drop.
>> If not, I will drop it somewhere else and will keep the mailinglist
>> notified.
>>
>> Either option is fine by me!
>>
>>
>> Werner
>>
>>
>>
>>
>>
>>
>>
>>
>
Re: Another approach to the templating problem
Posted by Leonardo Uribe <lu...@gmail.com>.
Hi
Based on the previous discussion, and with the intention of develop other
alternatives to this problem (if you want it do
it yourself), I have attached a possible solution for this problem. (code
available on TOMAHAWK-1327 file
RendererGenerationUsingXSLT.zip)
The strategy used was generate from a xhtml file a java renderer file
(*.java), using a xslt transformation. The code is
integrated with myfaces-builder-plugin to trigger renderer generation, using
a plugin.
In other words, the idea is generate from this:
<span style="@@style@@" class="@@styleClass@@" content="@@content@@"/>
something like this:
writer.startElement("span", component);
writer.writeAttribute("style", style, null);
writer.writeAttribute("class", styleClass, null);
writer.writeText("content", content, null);
writer.endElement("span");
The elements that needs to be defined are:
1. Define a abstract renderer class like this (the class pointed on class
attribute of @JSFRenderer is the file to generate):
/**
* @JSFRenderer
* renderKitId = "HTML_BASIC"
* family = "javax.faces.Output"
* type = "org.myorganization.SayHelloRenderer"
* class = "org.myorganization.component.sayhello.SayHelloRenderer"
*/
public abstract class AbstractSayHelloRenderer extends Renderer
{
.....
//The method to generate, the body is defined on a xhtml file
public abstract void encodeSomeHtmlOrJavascriptPart(FacesContext
context, UIComponent component) throws IOException;
}
2. Define a xhtml file called
src/main/resources/org/myorganization/component/sayhello/SayHelloRenderer.xhtml
<!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:mbp="http://myfaces.apache.org/mbp">
<mbp:import>javax.faces.component.UIComponent</mbp:import>
<mbp:import>javax.faces.context.FacesContext</mbp:import>
<mbp:import>javax.faces.context.ResponseWriter</mbp:import>
<mbp:import>javax.faces.render.Renderer</mbp:import>
<mbp:import>java.io.IOException</mbp:import>
<body>
<mbp:renderMethod
signature="public void void encodeSomeHtmlOrJavascriptPart(FacesContext
context, SayHelloComponent component) throws IOException"
writerVar="writer" componentVar="component">
<mbp:scriptlet>ResponseWriter writer = context.getResponseWriter();
</mbp:scriptlet>
<!-- HERE GOES SOME HTML OR JAVASCRIPT CODE TO BE COMPILED TO JAVA
SOURCE CODE -->
<span style="@@component.getStyle()@@"
class="@@component.getStyle()@@">@@component.getContent()@@</span>
</script>
</mbp:renderMethod>
</body>
</html>
3. Use myfaces-builder-plugin (see code on TOMAHAWK-1327 for details).
On TOMAHAWK-1327 file RendererGenerationUsingXSLT.zip there is a more
elaborated example using s:togglePanel as
base (see directory named "resume" for details about xhtml source file and
java results).
I'm trying to enhance it with more features and correct some bugs.
If the community would like it I would merge it into myfaces-builder-plugin.
Suggestions are welcome
regards
Leonardo Uribe
On Tue, Oct 7, 2008 at 6:49 AM, Werner Punz <we...@gmail.com> wrote:
> Ok to summarize this thread
>
>
> Generelly the compiler is appreciated, but
>
> a) We need a jsp like mechanism for dynamic compilation of the source
> templates, that should be doable, although it would mean modifications
> within the source how the templates are called (probably loading them via a
> utils class from the renderer)
>
> b) We need a more precise handling of the JSF APIs, that is much harder
> than a) but I think it is solvable one way or the other
> (probably by a second interpretion step which scans for tags and
> also merges the incoming variable expressions into the mix.
>
> Anything else?
>
> Besides that one question is open. Do we host it within myfaces
> or should I put it somewhere else (my preferrence would be java.net
> outside of myfaces due to its maven support)
>
> If we host it within myfaces, I will take care of the codegrant today or
> tomorrow and will start to work on the additional features after the code
> drop.
> If not, I will drop it somewhere else and will keep the mailinglist
> notified.
>
> Either option is fine by me!
>
>
> Werner
>
>
>
>
>
>
>
>
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Ok to summarize this thread
Generelly the compiler is appreciated, but
a) We need a jsp like mechanism for dynamic compilation of the source
templates, that should be doable, although it would mean modifications
within the source how the templates are called (probably loading them
via a utils class from the renderer)
b) We need a more precise handling of the JSF APIs, that is much harder
than a) but I think it is solvable one way or the other
(probably by a second interpretion step which scans for tags and
also merges the incoming variable expressions into the mix.
Anything else?
Besides that one question is open. Do we host it within myfaces
or should I put it somewhere else (my preferrence would be java.net
outside of myfaces due to its maven support)
If we host it within myfaces, I will take care of the codegrant today or
tomorrow and will start to work on the additional features after the
code drop.
If not, I will drop it somewhere else and will keep the mailinglist
notified.
Either option is fine by me!
Werner
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Andrew Robinson schrieb:
>> But the problem persists, how are we going to improve the readability of the
>> rendered code and how do we maintain the much needed speed on component
>> level?
>
> A very good question. I wonder if there is a way to get JSP-like
> runtime compilation of HTML template code and have that compiled code
> get as close to being inside the renderer as possible.
Well it is possible, I did something similar with groovy with dynamic
classloading a while ago.( I basically got the idea of inline templating
from groovy which has such mechanisms on language level.)
But the issue back then was, I had to replace the classloaders on the
fly with realtime classloaders which were able to reload the sourcefiles
and push them through a compiler cascade and weave proxies around it
(well in case of groovy you just had to push the files into the interpreter)
which do the check if the files have changed and then reload their
delegates on the fly if needed.
Howeverl calling methods from this stuff either needs fixed apis or
introspection calls, and you have to mess around with the classloaders!
Re: Another approach to the templating problem
Posted by Andrew Robinson <an...@gmail.com>.
> But the problem persists, how are we going to improve the readability of the
> rendered code and how do we maintain the much needed speed on component
> level?
A very good question. I wonder if there is a way to get JSP-like
runtime compilation of HTML template code and have that compiled code
get as close to being inside the renderer as possible. Using XML isn't
that bad for performance if the DOM is cached, but then that puts a
nice overhead on the heap. Developing components myself, I find the
experience very frustrating as maven builds and redeployments tend to
be very slow. I think this is why most web sites are written in perl,
php or python, there is no redeployment necessary, just immediate
gratification.
I wonder if groovy, jython or some other "java script" language could
be leveraged to be able to author in external files but have it become
java byte code to be able to go directly into the JIT? I don't have a
good solution as I don't like JSF renderers for speed and convenience
of development, but also don't like on-the-fly interpretation for
speed reasons.
Anyone have a profound thought?
>
>
> Werner
>
>
>
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Well I agree here mostly especially since
Tools like Netbeans rely on the startElement
etc... APIs. I just do not want to lose the generic tooling
I have regarding java.
Probably the sanest approach to resolve this would be some
kind of framework interceptor which could intercept
the code emitting stage for doing its own thing.
Then it could scan for tags and split it apart into the JSF APIs.
as for the other case:
> /*BEGIN_TEMPLATE
> <span style="$style" class="$styleClass">
> END_TEMPLATE*/
>
> // encode children
>
> /*BEGIN_TEMPLATE
> </span>
> END_TEMPLATE*/
I don´t think this is a huge problem, after all the interceptor must
parse the tags properly, every correct starting tag must result
in a startElement and a set of writeAttributes commands emitted.
Every endTag in an endElment. A syntax check for correct closure is not
needed, as long as it is a simple rewriter api.
As for closing the template and then open it again, this already is
covered by the compiler.
I purposely left the grammar that way that you at every stage
except for being inside a command (which is usually a #.... construct)
you can intercept the templating by simply closing the template
then doing java code and then reopening it.
Also I added the possibility of method calls from within templates as
long as they have a return value by treating variable calls like
$blabla() as method calls, so in many cases you wont even need
to break out of the template anymore!
Pretty much the same way velocity handles those issues.
And pretty much the opposite of minimalistic approaches like the EL.
For instance a call to encodeChildren at the current stage
could be done the following way:
/*TPL
<span style="$style" class="$styleClass">
TPL*/
this.encodeChildren(facesContext, component)
/*TPL </span>
TPL*/
or the better option because it gives a more precise control
on the layouting!
/*TPL
<span style="$style"
class="$styleClass">$this.encodeChildren($facesContext, $component)</span>
TPL*/
or if you want to have multilines without any carriage returns in the
result code
/*TPL
<span style="$style" class="$styleClass">\
$this.encodeChildren($facesContext, $component)\
</span>
TPL*/
The second and third options however would only work in the current state
if encodeChildren returns something printable. I will add a void
resulting method option in the next days, but for now I am purely
functional, regarding this. (I am still thinking about a good solution
which does not have to revert to introspection)
Werner
Andrew Robinson schrieb:
> -1 on this idea
>
> The problem is that I have seen code, like in Trinidad, where it is
> required an essential to call start & end element. For example,
> Trinidad uses escaping inside of a SCRIPT element to ensure that the
> encoded text does not break the HTML. Removing these calls and
> bypassing the ResponseWriter recommended APIs could easily break
> output that "smart" ResponseWriters depend on.
>
> Perhaps if this were done, the comment would be parsed by the parser
> into XML and then use that XML to extract element names and attribute
> name value pairs.
>
> So:
>
> /*BEGIN_TEMPLATE
> <span style="$style" class="$styleClass">$content</span>
> END_TEMPLATE*/
>
> would become:
>
> responseWriter.startElement("span", component);
> responseWriter.writeAttribute("style", style, null);
> responseWriter.writeAttribute("styleClass", styleClass, null);
> responseWriter.writeText("content", content, null);
> responseWriter.endElement("content", content, null);
>
> the problem here is if this were done, how to treat code java code
> that needs to run inside the content like:
>
> /*BEGIN_TEMPLATE
> <span style="$style" class="$styleClass">
> END_TEMPLATE*/
>
> // encode children
>
> /*BEGIN_TEMPLATE
> </span>
> END_TEMPLATE*/
>
> I don't have a good implementation idea on the creation of the code,
> but I would really hate to see any code bypass the startElement,
> writeAttribute and endElement methods.
>
> On Mon, Oct 6, 2008 at 4:15 PM, Werner Punz <we...@gmail.com> wrote:
>> Actually Simon you just gave me the perfect example
>>
>> Simon Kitching schrieb:
>>
>>> We are not talking about doing away with any existing templates, right?
>>>
>> No, the existing templates are not touched, what we have here is more or
>> less an extension to java which adds multiline strings and string templating
>> in a very generic way without colliding with the java syntax itself.
>>
>>
>>> AIUI we're just talking about replacing a whole bunch of calls to
>>> responseWriter.startElement("span")
>>> responseWriter.write("hello," + planetName);
>>> responseWriter.endElement("span")
>>> etc
>> Actually the new code would look like
>>
>> ... do something in java here
>> /*TPL
>> #outputop(responseWriter.write)
>> <span> hello $planetName </span>
>> TPL*/
>>
>> ... do again something in java here...
>>
>>
>> It would not result in entirely the same code after the compile,
>> but with the current state of affairs more or less in following code:
>>
>> responsewriter.write("<span> hello ");
>> responsewriter.write(planetName);
>> responsewriter.write(" </span>");
>>
>> I do not cover the startElement stopElement, and attribute etc.. apis
>> because I wanted to be as generic as possible (so that it can be covered
>> outside of jsf.
>> Theoretically it would be possible in the long run to cover those as well
>> (by simply parsing the code which has to be printed in a second step for tag
>> constructs). For now I leave it that way.
>>
>>
>> As I said in an earlier mail, I got the idea by groovy which has multiline
>> strings and limited string templating, but I went for the comment syntax
>> because I did not want to break existing java tooling.
>> (Pretty much like the jboss guys did in their compiler, but on the xml side
>> by using CDATA blocks to cover the java code)
>>
>>
>> I hope that clears things a little bit up.
>>
>> Werner
>>
>>
>
Re: Another approach to the templating problem
Posted by Andrew Robinson <an...@gmail.com>.
-1 on this idea
The problem is that I have seen code, like in Trinidad, where it is
required an essential to call start & end element. For example,
Trinidad uses escaping inside of a SCRIPT element to ensure that the
encoded text does not break the HTML. Removing these calls and
bypassing the ResponseWriter recommended APIs could easily break
output that "smart" ResponseWriters depend on.
Perhaps if this were done, the comment would be parsed by the parser
into XML and then use that XML to extract element names and attribute
name value pairs.
So:
/*BEGIN_TEMPLATE
<span style="$style" class="$styleClass">$content</span>
END_TEMPLATE*/
would become:
responseWriter.startElement("span", component);
responseWriter.writeAttribute("style", style, null);
responseWriter.writeAttribute("styleClass", styleClass, null);
responseWriter.writeText("content", content, null);
responseWriter.endElement("content", content, null);
the problem here is if this were done, how to treat code java code
that needs to run inside the content like:
/*BEGIN_TEMPLATE
<span style="$style" class="$styleClass">
END_TEMPLATE*/
// encode children
/*BEGIN_TEMPLATE
</span>
END_TEMPLATE*/
I don't have a good implementation idea on the creation of the code,
but I would really hate to see any code bypass the startElement,
writeAttribute and endElement methods.
On Mon, Oct 6, 2008 at 4:15 PM, Werner Punz <we...@gmail.com> wrote:
> Actually Simon you just gave me the perfect example
>
> Simon Kitching schrieb:
>
>> We are not talking about doing away with any existing templates, right?
>>
> No, the existing templates are not touched, what we have here is more or
> less an extension to java which adds multiline strings and string templating
> in a very generic way without colliding with the java syntax itself.
>
>
>> AIUI we're just talking about replacing a whole bunch of calls to
>> responseWriter.startElement("span")
>> responseWriter.write("hello," + planetName);
>> responseWriter.endElement("span")
>> etc
>
> Actually the new code would look like
>
> ... do something in java here
> /*TPL
> #outputop(responseWriter.write)
> <span> hello $planetName </span>
> TPL*/
>
> ... do again something in java here...
>
>
> It would not result in entirely the same code after the compile,
> but with the current state of affairs more or less in following code:
>
> responsewriter.write("<span> hello ");
> responsewriter.write(planetName);
> responsewriter.write(" </span>");
>
> I do not cover the startElement stopElement, and attribute etc.. apis
> because I wanted to be as generic as possible (so that it can be covered
> outside of jsf.
> Theoretically it would be possible in the long run to cover those as well
> (by simply parsing the code which has to be printed in a second step for tag
> constructs). For now I leave it that way.
>
>
> As I said in an earlier mail, I got the idea by groovy which has multiline
> strings and limited string templating, but I went for the comment syntax
> because I did not want to break existing java tooling.
> (Pretty much like the jboss guys did in their compiler, but on the xml side
> by using CDATA blocks to cover the java code)
>
>
> I hope that clears things a little bit up.
>
> Werner
>
>
Re: Another approach to the templating problem
Posted by Hazem Saleh <ha...@apache.org>.
I think we can add the startElement and endElement later!
Not a difficult job :).
On Tue, Oct 7, 2008 at 12:15 AM, Werner Punz <we...@gmail.com> wrote:
> Actually Simon you just gave me the perfect example
>
> Simon Kitching schrieb:
>
> We are not talking about doing away with any existing templates, right?
>>
>> No, the existing templates are not touched, what we have here is more or
> less an extension to java which adds multiline strings and string templating
> in a very generic way without colliding with the java syntax itself.
>
>
> AIUI we're just talking about replacing a whole bunch of calls to
>> responseWriter.startElement("span")
>> responseWriter.write("hello," + planetName);
>> responseWriter.endElement("span")
>> etc
>>
>
> Actually the new code would look like
>
> ... do something in java here
> /*TPL
> #outputop(responseWriter.write)
> <span> hello $planetName </span>
> TPL*/
>
> ... do again something in java here...
>
>
> It would not result in entirely the same code after the compile,
> but with the current state of affairs more or less in following code:
>
> responsewriter.write("<span> hello ");
> responsewriter.write(planetName);
> responsewriter.write(" </span>");
>
> I do not cover the startElement stopElement, and attribute etc.. apis
> because I wanted to be as generic as possible (so that it can be covered
> outside of jsf.
> Theoretically it would be possible in the long run to cover those as well
> (by simply parsing the code which has to be printed in a second step for tag
> constructs). For now I leave it that way.
>
>
> As I said in an earlier mail, I got the idea by groovy which has multiline
> strings and limited string templating, but I went for the comment syntax
> because I did not want to break existing java tooling.
> (Pretty much like the jboss guys did in their compiler, but on the xml side
> by using CDATA blocks to cover the java code)
>
>
> I hope that clears things a little bit up.
>
> Werner
>
>
--
Hazem Ahmed Saleh Ahmed
Author of (The Definitive Guide to Apache MyFaces and Facelets):
http://www.amazon.com/Definitive-Guide-Apache-MyFaces-Facelets/dp/1590597370
Web blog: http://www.jroller.com/page/HazemBlog
[Web 2.0] Google Maps Integration with JSF:
http://code.google.com/p/gmaps4jsf/
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Actually Simon you just gave me the perfect example
Simon Kitching schrieb:
> We are not talking about doing away with any existing templates, right?
>
No, the existing templates are not touched, what we have here is more or
less an extension to java which adds multiline strings and string
templating in a very generic way without colliding with the java syntax
itself.
> AIUI we're just talking about replacing a whole bunch of calls to
> responseWriter.startElement("span")
> responseWriter.write("hello," + planetName);
> responseWriter.endElement("span")
> etc
Actually the new code would look like
... do something in java here
/*TPL
#outputop(responseWriter.write)
<span> hello $planetName </span>
TPL*/
... do again something in java here...
It would not result in entirely the same code after the compile,
but with the current state of affairs more or less in following code:
responsewriter.write("<span> hello ");
responsewriter.write(planetName);
responsewriter.write(" </span>");
I do not cover the startElement stopElement, and attribute etc.. apis
because I wanted to be as generic as possible (so that it can be covered
outside of jsf.
Theoretically it would be possible in the long run to cover those as
well (by simply parsing the code which has to be printed in a second
step for tag constructs). For now I leave it that way.
As I said in an earlier mail, I got the idea by groovy which has
multiline strings and limited string templating, but I went for the
comment syntax because I did not want to break existing java tooling.
(Pretty much like the jboss guys did in their compiler, but on the xml
side by using CDATA blocks to cover the java code)
I hope that clears things a little bit up.
Werner
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Simon Kitching schrieb:
> Werner Punz schrieb:
>> Andrew Robinson schrieb:
>>> Think I worded this too strongly, as renderers also produce HTML via
>>> Java. I just think that if you are going to have templates, it would
>>> be great to keep them in separate files, be it *.vm for velocity or
>>> xhtml/xml for facelets/JSF2 or what have you. These files can not only
>>> be edited by some tools (at least facelets can, not so sure about
>>> velocity), but they can also be changed on the fly without any java
>>> recompilation. Java went away from servlets building HTML for this
>>> reason and adopted JSP. I personally do not feel that going back to
>>> more Java built HTML is going to be a great direction, but maybe that
>>> is just me.
>>>
>> Actually I am not harsh about myfaces not adopting my solution,
>> it was just an effort to improve readability on the source from my side.
>> No harm is done if we do not adopt it.
>>
>> Problem is as I see it, everything is better for jsf 1.x than the
>> current printwriter API.
>> Even my, and I agree from an academic standpoint dirty, solution.
>>
>> If anyone could provide a decent backport of the JSF2 templating
>> compiler to JSF1 I would be happy as well.
>> (My compiler building knowledge is way too limited to pull this off in
>> a limited time myself)
>>
>> But the problem persists, how are we going to improve the readability
>> of the rendered code and how do we maintain the much needed speed on
>> component level?
>>
> We are not talking about doing away with any existing templates, right?
>
> AIUI we're just talking about replacing a whole bunch of calls to
> responseWriter.startElement("span")
> responseWriter.write("hello," + planetName);
> responseWriter.endElement("span")
> etc
> with some kind of in-class templating that compiles down to exactly the
> same code, but has a more readable syntax. The performance will clearly
> be exactly the same as the current code, because it results in exactly
> the same code in the end. Whether it is actually easier to work with is
> up for debate, but I've spent hours looking at code for the Calendar
> control trying to figure out exactly what it generates; all those
> StringBuffer manipulations are really nasty. The current approach sucks
> for readability.
>
> So Werner's proposal is not terribly radical (though clever). It's
> equivalent to SQLJ, but compiles direct to bytecode rather than java
> source.
>
> Refactoring all the components to use external templating interpreted at
> runtime is certainly more flexible and elegant but Werner seems to have
> proved that this is just a no-go from the performance point of view.
> Pages do often have dozens of components, and rendering dozens of
> Velocity templates doesn't seem to be feasable. Any template-based
> approach would have to be one with very high performance.
>
> JSP2.0 does support "tag files", ie jsp files with suffix ".tag" that
> can then be referenced via jsp tags in a page. I would presume that
> these do get precompiled like other jsp files do, but cannot see how we
> could hook into that. Same with Facelets; I don't know of a way to have
> a template processed into an optimised form that the renderer can pass
> data to; facelets pages are used at build-time to create a view-tree,
> not at render time when the view-tree is being walked to generate output.
>
> I suppose that Werner's templating approach could be applied to
> *external* templates rather than ones embedded in the class.
> For example, a "HtmlCalendar.tmpl" file could exist next to the .java
> file, and could generate a HtmlCalendarTmpl.class file at compiletime
> with a static render(Map args) method and a bunch of print statements.
> This could then be invoked from the calendar component. That does feel
> cleaner to me than embedding the template within the java code, although
> the end result is pretty much the same. This then *is* effectively a
> high-performance template system, although a recompile is required to
> change the template output. What do you think, Werner?
>
> I don't think comparing this to JSP vs hard-coded HTML is fair. Pages
> are expected to be changed on a daily basis; the representation a JSF
> component generates will often not change between releases (ie remains
> untouched for months).
>
> One thing I did try a while ago was to simply define a template string
> in the java class, then use java.text.MessageFormat.format(template,
> args). But I don't think that the performance is really good enough.
>
>
> Regards,
> Simon
>
>
Actually two clarifications,
the first one is I compile to java source not bytecode, it was way
easier to do that, and makes debugging easier afterwards!
I thought about going to external templates, but then went against it.
First of all I wanted to have the code in place because if you look at a
component about 80% is infrastructural code 20% maybe the pure
rendering. But the printwriter api, makes those 20%, 50% of the
resulting codebase, and decreases the readability!
The second issue was simply, that going towards exernal templates means
following
a) You have to use lookup maps for the variables, which I could avoid by
simple doing a rewriting engine.
b) You either have to give the compiler type information to do the
typecasting, or you have to generate introspection code.
I will give an example:
$myVar.helloString
can be expanded into myVar.getHelloString() which is exactly what you
would do in handwritten code.
however if you use param maps then you run into following:
you have to do introspection whether the passed variable has a property
myVar or you additionally have to give the templating compiler the info
of the type of myVar so that internally can do the casting in the
generated code alike
MyVarType _generated_MyVar = (MyVarType) variablesMap.get("myVar");
_generated_MyVar.getHelloString();
The myVarType must be looked up upfront by the compiler in a type map,
probably in the template itself, hence you add the entire variable
declaration into the template!
To avoid introspection I probably would go the second approach, though,
but that still means you have to do a map lookup vor every variable in
the template and you have to add the runtime type information into the
templating code call!
Note you still can introduce a mvc pattern with the plain rewriter by
simply pushing all the templating code in their own classes and pass the
parameters as parameter lists down the methods.
This basically would result in the same but without manual the runtime
type information addition!
Werner
Re: Another approach to the templating problem
Posted by Simon Kitching <sk...@apache.org>.
Werner Punz schrieb:
> Andrew Robinson schrieb:
>> Think I worded this too strongly, as renderers also produce HTML via
>> Java. I just think that if you are going to have templates, it would
>> be great to keep them in separate files, be it *.vm for velocity or
>> xhtml/xml for facelets/JSF2 or what have you. These files can not only
>> be edited by some tools (at least facelets can, not so sure about
>> velocity), but they can also be changed on the fly without any java
>> recompilation. Java went away from servlets building HTML for this
>> reason and adopted JSP. I personally do not feel that going back to
>> more Java built HTML is going to be a great direction, but maybe that
>> is just me.
>>
> Actually I am not harsh about myfaces not adopting my solution,
> it was just an effort to improve readability on the source from my side.
> No harm is done if we do not adopt it.
>
> Problem is as I see it, everything is better for jsf 1.x than the
> current printwriter API.
> Even my, and I agree from an academic standpoint dirty, solution.
>
> If anyone could provide a decent backport of the JSF2 templating
> compiler to JSF1 I would be happy as well.
> (My compiler building knowledge is way too limited to pull this off in
> a limited time myself)
>
> But the problem persists, how are we going to improve the readability
> of the rendered code and how do we maintain the much needed speed on
> component level?
>
We are not talking about doing away with any existing templates, right?
AIUI we're just talking about replacing a whole bunch of calls to
responseWriter.startElement("span")
responseWriter.write("hello," + planetName);
responseWriter.endElement("span")
etc
with some kind of in-class templating that compiles down to exactly the
same code, but has a more readable syntax. The performance will clearly
be exactly the same as the current code, because it results in exactly
the same code in the end. Whether it is actually easier to work with is
up for debate, but I've spent hours looking at code for the Calendar
control trying to figure out exactly what it generates; all those
StringBuffer manipulations are really nasty. The current approach sucks
for readability.
So Werner's proposal is not terribly radical (though clever). It's
equivalent to SQLJ, but compiles direct to bytecode rather than java source.
Refactoring all the components to use external templating interpreted at
runtime is certainly more flexible and elegant but Werner seems to have
proved that this is just a no-go from the performance point of view.
Pages do often have dozens of components, and rendering dozens of
Velocity templates doesn't seem to be feasable. Any template-based
approach would have to be one with very high performance.
JSP2.0 does support "tag files", ie jsp files with suffix ".tag" that
can then be referenced via jsp tags in a page. I would presume that
these do get precompiled like other jsp files do, but cannot see how we
could hook into that. Same with Facelets; I don't know of a way to have
a template processed into an optimised form that the renderer can pass
data to; facelets pages are used at build-time to create a view-tree,
not at render time when the view-tree is being walked to generate output.
I suppose that Werner's templating approach could be applied to
*external* templates rather than ones embedded in the class.
For example, a "HtmlCalendar.tmpl" file could exist next to the .java
file, and could generate a HtmlCalendarTmpl.class file at compiletime
with a static render(Map args) method and a bunch of print statements.
This could then be invoked from the calendar component. That does feel
cleaner to me than embedding the template within the java code, although
the end result is pretty much the same. This then *is* effectively a
high-performance template system, although a recompile is required to
change the template output. What do you think, Werner?
I don't think comparing this to JSP vs hard-coded HTML is fair. Pages
are expected to be changed on a daily basis; the representation a JSF
component generates will often not change between releases (ie remains
untouched for months).
One thing I did try a while ago was to simply define a template string
in the java class, then use java.text.MessageFormat.format(template,
args). But I don't think that the performance is really good enough.
Regards,
Simon
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Andrew Robinson schrieb:
> Think I worded this too strongly, as renderers also produce HTML via
> Java. I just think that if you are going to have templates, it would
> be great to keep them in separate files, be it *.vm for velocity or
> xhtml/xml for facelets/JSF2 or what have you. These files can not only
> be edited by some tools (at least facelets can, not so sure about
> velocity), but they can also be changed on the fly without any java
> recompilation. Java went away from servlets building HTML for this
> reason and adopted JSP. I personally do not feel that going back to
> more Java built HTML is going to be a great direction, but maybe that
> is just me.
>
Actually I am not harsh about myfaces not adopting my solution,
it was just an effort to improve readability on the source from my side.
No harm is done if we do not adopt it.
Problem is as I see it, everything is better for jsf 1.x than the
current printwriter API.
Even my, and I agree from an academic standpoint dirty, solution.
If anyone could provide a decent backport of the JSF2 templating
compiler to JSF1 I would be happy as well.
(My compiler building knowledge is way too limited to pull this off in a
limited time myself)
But the problem persists, how are we going to improve the readability of
the rendered code and how do we maintain the much needed speed on
component level?
Werner
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Andrew Robinson schrieb:
> Think I worded this too strongly, as renderers also produce HTML via
> Java. I just think that if you are going to have templates, it would
> be great to keep them in separate files, be it *.vm for velocity or
> xhtml/xml for facelets/JSF2 or what have you. These files can not only
> be edited by some tools (at least facelets can, not so sure about
> velocity), but they can also be changed on the fly without any java
> recompilation. Java went away from servlets building HTML for this
> reason and adopted JSP. I personally do not feel that going back to
> more Java built HTML is going to be a great direction, but maybe that
> is just me.
>
Well you talk about an interpreter vs compiler approach.
The main issue is here, that we have tried the interpreter approach and
it falls short on the speed on component level due to the set of code
emitted which is not very much. (Most of the code is usually
externalized anyway in javascript and css files)
So if you want to gain the speed you have to achieve on component level
you have to go through the compiler approach, so a recompile step at
least on component -> java level is probably needed.
Facelets works on interpreter level, but it only is as fast as it is,
because it can target huge parts of the page and hence can cache
extensively.
The typical component however has only a handful of lines of generated code.
I have not looked at the latest jsf2 spec in this regard, but I rather
doubt they went the interpreter route. Can anyone clarfy this?
Werner
Re: Another approach to the templating problem
Posted by Andrew Robinson <an...@gmail.com>.
Think I worded this too strongly, as renderers also produce HTML via
Java. I just think that if you are going to have templates, it would
be great to keep them in separate files, be it *.vm for velocity or
xhtml/xml for facelets/JSF2 or what have you. These files can not only
be edited by some tools (at least facelets can, not so sure about
velocity), but they can also be changed on the fly without any java
recompilation. Java went away from servlets building HTML for this
reason and adopted JSP. I personally do not feel that going back to
more Java built HTML is going to be a great direction, but maybe that
is just me.
-Andrew
On Mon, Oct 6, 2008 at 7:07 AM, Andrew Robinson
<an...@gmail.com> wrote:
> OMG, this would produce some insanely unmaintainable code, not to
> mention having to recompile for every little HTML change, and no way
> at all to have HTML authors help code it. Servlets were bad enough,
> but now embedding HTML in Java Comments?
>
> -0.9 for me, keep HTML in HTML maintained files would always be my
> choice. Why not go the JSF2 method for templating?
>
> As for resource handling, components could be made to be able to add
> content to the HEAD. For example, a new tr:resource component could
> communicate with the tr:document or tr:head & add content to it so as
> to ensure that CSS and JS gets added to the HEAD without the overhead
> of buffering.
>
> -Andrew
>
> On Mon, Oct 6, 2008 at 6:53 AM, Werner Punz <we...@gmail.com> wrote:
>> Simon Kitching schrieb:
>>>
>>> Werner Punz schrieb:
>>>>
>>>> Paul Rivera schrieb:
>>>>>
>>>>> Interesting solution :)
>>>>>
>>>>> I agree that the execution time of a compiler level solution will be
>>>>> better than an interpreted template solution. Perhaps the only scenario
>>>>> that our interpreted template solution will yeild significant execution
>>>>> performance gain is when it caches large amounts of javascript code.
>>>>> Browsing through the components, most of our large javascript code are
>>>>> already rendered through AddResource which is already cached. The remaining
>>>>> javascript code embedded into some renderers are just not significantly
>>>>> large enough.
>>>>>
>>>>
>>>>
>>>>> Do we plan to implement the same convention in myfaces-builder-plugin?
>>>>> I.e.
>>>>> An abstract renderer class that c ontains the javascript template
>>>>> comment
>>>>> A concrete subclass of the one above generated by
>>>>> myfaces-builder-plugin that has the template comment from parent abstract
>>>>> class converted into java code
>>>>>
>>>>
>>>> Actually I would go for the concrete implementation approach. The maven
>>>> plugin of the compiler can take care if picking up the correct files.
>>>> It even has package rewriting possibilities (I added such a directive to
>>>> the grammar on thursday)
>>>> So that people can work on the templated java files and have haven
>>>> compile the result into the generated sources (and still can link into those
>>>> if needed, due to being in a different package)...
>>>
>>> This approach to templating is very interesting..and anything that
>>> improves the current StringBuffer-based approach for javascript generation
>>> is very nice to see! That code is really hard to work on..
>>>
>>> What happens with breakpoints etc? This is always a tricky problem with
>>> templates. Generating a subclass does at least mean that breakpoints can be
>>> set in the "real" parent class, and the subclass contains only generated
>>> code (for which breakpoints are not much use). If things get magically
>>> compiled into a different package, then won't breakpoints set in the
>>> original file be ignored?
>>>
>>> I'm also somewhat concerned about the debuggability of classes when
>>> templates and "normal" code are mixed in the same method. Does this work ok?
>>> If not, then is it possible to use the convention of creating a method
>>> containing *just* the magic template-comment, with the method parameters as
>>> the data referenced from the template?
>>>
>>> Regards,
>>> Simon
>>>
>>>
>> Actually the debugability is there, although you have to debug on the
>> generated code.
>> The package rewriting really can help with it, because you can keep
>> the original sources, and then debug into the generated code
>> which is hosted as the same class name in a different package!
>>
>> The goal of my approach was that you can utilize the normal java tooling
>> for everything outside of the template, but you still also should be able to
>> check the generated code and debug into it once it is compiled
>> (hence the package rewriting which is easier for ides and the users)
>>
>>
>> The main issue is however you cannot debug on the templates themselves :-(
>> Is there currently any engine which can do this?
>>
>> It probably could be possible to get debuggability into it, but I am no
>> compiler guy, it was hard enough for me to write the rewriting compiler with
>> antlr (it is nothing more than a straight to the target api rewrite
>> of the more compact template syntax)
>>
>> But in the end I do not think the generated code is so complex that
>> debugging into it is really an issue:
>>
>>
>> I will give you guys a small example how the generated code looks like:
>>
>>
>> /*TPL
>> #destpackage(pac.xxx.yyy)
>> TPL*/
>>
>> package paxxx;
>>
>> import java.util.Collection;
>>
>> public class SimpleTest2 {
>>
>> static String helloWorld = "hello world";
>>
>> private String calledMethod() {
>>
>> System.out.println("called function");
>> return "";
>> }
>>
>> public void emitTemplate() {
>>
>> String [] values = new String[5];
>> values[0] = "value0";
>> values[1] = "value1";
>> values[2] = "value2";
>> values[3] = "value3";
>> values[4] = "value4";
>>
>>
>>
>>
>>
>>
>>
>> /*TPL
>> #outputop(System.out.println)
>> This is a test for a simple embedded template
>>
>> $helloWorld
>>
>> <table>
>> <tbody>
>>
>> #each(String, $values)
>> </tr><td>$it</td></tr>
>> #end
>>
>> calling a method
>>
>> $this.calledMethod();
>>
>> this text should follow after table!
>>
>> TPL*/
>>
>>
>> }
>>
>>
>> is compiled into(please ignore the wraps enforced by the mail client and my
>> added comments!):
>>
>>
>> package pac.xxx.yyy; ---- Please note the changed package here!
>>
>>
>> import java.util.Collection;
>>
>> public class SimpleTest2 {
>>
>> static String helloWorld = "hello world";
>>
>> private String calledMethod() {
>> System.out.println("called function");
>> return "";
>> }
>>
>> public void emitTemplate() {
>> String[] values = new String[5];
>> values[0] = "value0";
>> values[1] = "value1";
>> values[2] = "value2";
>> values[3] = "value3";
>> values[4] = "value4";
>>
>> --- From here the emitted template code starts!
>>
>> System.out.println("\n This is a test for a simple embedded
>> template\n\n ");
>> System.out.println(helloWorld);
>> System.out.println("<table>\n <tbody>\n\n ");
>> Object _coll__it_1 = null;
>> if (!values.getClass().isArray()) {
>> _coll__it_1 = values;
>> } else {
>> _coll__it_1 = java.util.Arrays.asList(values);
>> }
>> java.util.Iterator _iter__it_1 = ((java.util.Collection)
>> _coll__it_1).iterator();
>> while (_iter__it_1.hasNext()) {
>> String _it_1 = (String) _iter__it_1.next();
>> System.out.println("</tr><td>");
>> System.out.println(_it_1);
>> System.out.println("</td></tr>\n ");
>> }
>> System.out.println("calling a method\n\n ");
>> System.out.println(this.calledMethod());
>> System.out.println(";\n\n this text should follow after
>> table!\n\n ");
>> }
>>
>>
>> I dont think debugging the generated code is really that much of an issue as
>> long as it can be done.
>>
>>
>>
>>
>
Re: Another approach to the templating problem
Posted by Andrew Robinson <an...@gmail.com>.
OMG, this would produce some insanely unmaintainable code, not to
mention having to recompile for every little HTML change, and no way
at all to have HTML authors help code it. Servlets were bad enough,
but now embedding HTML in Java Comments?
-0.9 for me, keep HTML in HTML maintained files would always be my
choice. Why not go the JSF2 method for templating?
As for resource handling, components could be made to be able to add
content to the HEAD. For example, a new tr:resource component could
communicate with the tr:document or tr:head & add content to it so as
to ensure that CSS and JS gets added to the HEAD without the overhead
of buffering.
-Andrew
On Mon, Oct 6, 2008 at 6:53 AM, Werner Punz <we...@gmail.com> wrote:
> Simon Kitching schrieb:
>>
>> Werner Punz schrieb:
>>>
>>> Paul Rivera schrieb:
>>>>
>>>> Interesting solution :)
>>>>
>>>> I agree that the execution time of a compiler level solution will be
>>>> better than an interpreted template solution. Perhaps the only scenario
>>>> that our interpreted template solution will yeild significant execution
>>>> performance gain is when it caches large amounts of javascript code.
>>>> Browsing through the components, most of our large javascript code are
>>>> already rendered through AddResource which is already cached. The remaining
>>>> javascript code embedded into some renderers are just not significantly
>>>> large enough.
>>>>
>>>
>>>
>>>> Do we plan to implement the same convention in myfaces-builder-plugin?
>>>> I.e.
>>>> An abstract renderer class that c ontains the javascript template
>>>> comment
>>>> A concrete subclass of the one above generated by
>>>> myfaces-builder-plugin that has the template comment from parent abstract
>>>> class converted into java code
>>>>
>>>
>>> Actually I would go for the concrete implementation approach. The maven
>>> plugin of the compiler can take care if picking up the correct files.
>>> It even has package rewriting possibilities (I added such a directive to
>>> the grammar on thursday)
>>> So that people can work on the templated java files and have haven
>>> compile the result into the generated sources (and still can link into those
>>> if needed, due to being in a different package)...
>>
>> This approach to templating is very interesting..and anything that
>> improves the current StringBuffer-based approach for javascript generation
>> is very nice to see! That code is really hard to work on..
>>
>> What happens with breakpoints etc? This is always a tricky problem with
>> templates. Generating a subclass does at least mean that breakpoints can be
>> set in the "real" parent class, and the subclass contains only generated
>> code (for which breakpoints are not much use). If things get magically
>> compiled into a different package, then won't breakpoints set in the
>> original file be ignored?
>>
>> I'm also somewhat concerned about the debuggability of classes when
>> templates and "normal" code are mixed in the same method. Does this work ok?
>> If not, then is it possible to use the convention of creating a method
>> containing *just* the magic template-comment, with the method parameters as
>> the data referenced from the template?
>>
>> Regards,
>> Simon
>>
>>
> Actually the debugability is there, although you have to debug on the
> generated code.
> The package rewriting really can help with it, because you can keep
> the original sources, and then debug into the generated code
> which is hosted as the same class name in a different package!
>
> The goal of my approach was that you can utilize the normal java tooling
> for everything outside of the template, but you still also should be able to
> check the generated code and debug into it once it is compiled
> (hence the package rewriting which is easier for ides and the users)
>
>
> The main issue is however you cannot debug on the templates themselves :-(
> Is there currently any engine which can do this?
>
> It probably could be possible to get debuggability into it, but I am no
> compiler guy, it was hard enough for me to write the rewriting compiler with
> antlr (it is nothing more than a straight to the target api rewrite
> of the more compact template syntax)
>
> But in the end I do not think the generated code is so complex that
> debugging into it is really an issue:
>
>
> I will give you guys a small example how the generated code looks like:
>
>
> /*TPL
> #destpackage(pac.xxx.yyy)
> TPL*/
>
> package paxxx;
>
> import java.util.Collection;
>
> public class SimpleTest2 {
>
> static String helloWorld = "hello world";
>
> private String calledMethod() {
>
> System.out.println("called function");
> return "";
> }
>
> public void emitTemplate() {
>
> String [] values = new String[5];
> values[0] = "value0";
> values[1] = "value1";
> values[2] = "value2";
> values[3] = "value3";
> values[4] = "value4";
>
>
>
>
>
>
>
> /*TPL
> #outputop(System.out.println)
> This is a test for a simple embedded template
>
> $helloWorld
>
> <table>
> <tbody>
>
> #each(String, $values)
> </tr><td>$it</td></tr>
> #end
>
> calling a method
>
> $this.calledMethod();
>
> this text should follow after table!
>
> TPL*/
>
>
> }
>
>
> is compiled into(please ignore the wraps enforced by the mail client and my
> added comments!):
>
>
> package pac.xxx.yyy; ---- Please note the changed package here!
>
>
> import java.util.Collection;
>
> public class SimpleTest2 {
>
> static String helloWorld = "hello world";
>
> private String calledMethod() {
> System.out.println("called function");
> return "";
> }
>
> public void emitTemplate() {
> String[] values = new String[5];
> values[0] = "value0";
> values[1] = "value1";
> values[2] = "value2";
> values[3] = "value3";
> values[4] = "value4";
>
> --- From here the emitted template code starts!
>
> System.out.println("\n This is a test for a simple embedded
> template\n\n ");
> System.out.println(helloWorld);
> System.out.println("<table>\n <tbody>\n\n ");
> Object _coll__it_1 = null;
> if (!values.getClass().isArray()) {
> _coll__it_1 = values;
> } else {
> _coll__it_1 = java.util.Arrays.asList(values);
> }
> java.util.Iterator _iter__it_1 = ((java.util.Collection)
> _coll__it_1).iterator();
> while (_iter__it_1.hasNext()) {
> String _it_1 = (String) _iter__it_1.next();
> System.out.println("</tr><td>");
> System.out.println(_it_1);
> System.out.println("</td></tr>\n ");
> }
> System.out.println("calling a method\n\n ");
> System.out.println(this.calledMethod());
> System.out.println(";\n\n this text should follow after
> table!\n\n ");
> }
>
>
> I dont think debugging the generated code is really that much of an issue as
> long as it can be done.
>
>
>
>
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Simon Kitching schrieb:
> Werner Punz schrieb:
>> Paul Rivera schrieb:
>>> Interesting solution :)
>>>
>>> I agree that the execution time of a compiler level solution will be
>>> better than an interpreted template solution. Perhaps the only
>>> scenario that our interpreted template solution will yeild
>>> significant execution performance gain is when it caches large
>>> amounts of javascript code. Browsing through the components, most of
>>> our large javascript code are already rendered through AddResource
>>> which is already cached. The remaining javascript code embedded into
>>> some renderers are just not significantly large enough.
>>>
>>
>>
>>> Do we plan to implement the same convention in myfaces-builder-plugin?
>>> I.e.
>>> An abstract renderer class that c ontains the javascript template
>>> comment
>>> A concrete subclass of the one above generated by
>>> myfaces-builder-plugin that has the template comment from parent
>>> abstract class converted into java code
>>>
>>
>> Actually I would go for the concrete implementation approach. The
>> maven plugin of the compiler can take care if picking up the correct
>> files.
>> It even has package rewriting possibilities (I added such a directive
>> to the grammar on thursday)
>> So that people can work on the templated java files and have haven
>> compile the result into the generated sources (and still can link into
>> those if needed, due to being in a different package)...
>
> This approach to templating is very interesting..and anything that
> improves the current StringBuffer-based approach for javascript
> generation is very nice to see! That code is really hard to work on..
>
> What happens with breakpoints etc? This is always a tricky problem with
> templates. Generating a subclass does at least mean that breakpoints can
> be set in the "real" parent class, and the subclass contains only
> generated code (for which breakpoints are not much use). If things get
> magically compiled into a different package, then won't breakpoints set
> in the original file be ignored?
>
> I'm also somewhat concerned about the debuggability of classes when
> templates and "normal" code are mixed in the same method. Does this work
> ok? If not, then is it possible to use the convention of creating a
> method containing *just* the magic template-comment, with the method
> parameters as the data referenced from the template?
>
> Regards,
> Simon
>
>
Actually the debugability is there, although you have to debug on the
generated code.
The package rewriting really can help with it, because you can keep
the original sources, and then debug into the generated code
which is hosted as the same class name in a different package!
The goal of my approach was that you can utilize the normal java tooling
for everything outside of the template, but you still also should be
able to check the generated code and debug into it once it is compiled
(hence the package rewriting which is easier for ides and the users)
The main issue is however you cannot debug on the templates themselves :-(
Is there currently any engine which can do this?
It probably could be possible to get debuggability into it, but I am no
compiler guy, it was hard enough for me to write the rewriting compiler
with antlr (it is nothing more than a straight to the target api rewrite
of the more compact template syntax)
But in the end I do not think the generated code is so complex that
debugging into it is really an issue:
I will give you guys a small example how the generated code looks like:
/*TPL
#destpackage(pac.xxx.yyy)
TPL*/
package paxxx;
import java.util.Collection;
public class SimpleTest2 {
static String helloWorld = "hello world";
private String calledMethod() {
System.out.println("called function");
return "";
}
public void emitTemplate() {
String [] values = new String[5];
values[0] = "value0";
values[1] = "value1";
values[2] = "value2";
values[3] = "value3";
values[4] = "value4";
/*TPL
#outputop(System.out.println)
This is a test for a simple embedded template
$helloWorld
<table>
<tbody>
#each(String, $values)
</tr><td>$it</td></tr>
#end
calling a method
$this.calledMethod();
this text should follow after table!
TPL*/
}
is compiled into(please ignore the wraps enforced by the mail client
and my added comments!):
package pac.xxx.yyy; ---- Please note the changed package here!
import java.util.Collection;
public class SimpleTest2 {
static String helloWorld = "hello world";
private String calledMethod() {
System.out.println("called function");
return "";
}
public void emitTemplate() {
String[] values = new String[5];
values[0] = "value0";
values[1] = "value1";
values[2] = "value2";
values[3] = "value3";
values[4] = "value4";
--- From here the emitted template code starts!
System.out.println("\n This is a test for a simple
embedded template\n\n ");
System.out.println(helloWorld);
System.out.println("<table>\n <tbody>\n\n ");
Object _coll__it_1 = null;
if (!values.getClass().isArray()) {
_coll__it_1 = values;
} else {
_coll__it_1 = java.util.Arrays.asList(values);
}
java.util.Iterator _iter__it_1 = ((java.util.Collection)
_coll__it_1).iterator();
while (_iter__it_1.hasNext()) {
String _it_1 = (String) _iter__it_1.next();
System.out.println("</tr><td>");
System.out.println(_it_1);
System.out.println("</td></tr>\n ");
}
System.out.println("calling a method\n\n ");
System.out.println(this.calledMethod());
System.out.println(";\n\n this text should follow
after table!\n\n ");
}
I dont think debugging the generated code is really that much of an
issue as long as it can be done.
Re: Another approach to the templating problem
Posted by Simon Kitching <sk...@apache.org>.
Werner Punz schrieb:
> Paul Rivera schrieb:
>> Interesting solution :)
>>
>> I agree that the execution time of a compiler level solution will be
>> better than an interpreted template solution. Perhaps the only
>> scenario that our interpreted template solution will yeild
>> significant execution performance gain is when it caches large
>> amounts of javascript code. Browsing through the components, most of
>> our large javascript code are already rendered through AddResource
>> which is already cached. The remaining javascript code embedded into
>> some renderers are just not significantly large enough.
>>
>
>
>> Do we plan to implement the same convention in myfaces-builder-plugin?
>> I.e.
>> An abstract renderer class that c ontains the javascript template
>> comment
>> A concrete subclass of the one above generated by
>> myfaces-builder-plugin that has the template comment from parent
>> abstract class converted into java code
>>
>
> Actually I would go for the concrete implementation approach. The
> maven plugin of the compiler can take care if picking up the correct
> files.
> It even has package rewriting possibilities (I added such a directive
> to the grammar on thursday)
> So that people can work on the templated java files and have haven
> compile the result into the generated sources (and still can link into
> those if needed, due to being in a different package)...
This approach to templating is very interesting..and anything that
improves the current StringBuffer-based approach for javascript
generation is very nice to see! That code is really hard to work on..
What happens with breakpoints etc? This is always a tricky problem with
templates. Generating a subclass does at least mean that breakpoints can
be set in the "real" parent class, and the subclass contains only
generated code (for which breakpoints are not much use). If things get
magically compiled into a different package, then won't breakpoints set
in the original file be ignored?
I'm also somewhat concerned about the debuggability of classes when
templates and "normal" code are mixed in the same method. Does this work
ok? If not, then is it possible to use the convention of creating a
method containing *just* the magic template-comment, with the method
parameters as the data referenced from the template?
Regards,
Simon
Re: Another approach to the templating problem
Posted by Werner Punz <we...@gmail.com>.
Paul Rivera schrieb:
> Interesting solution :)
>
> I agree that the execution time of a compiler level solution will be
> better than an interpreted template solution. Perhaps the only scenario
> that our interpreted template solution will yeild significant execution
> performance gain is when it caches large amounts of javascript code.
> Browsing through the components, most of our large javascript code are
> already rendered through AddResource which is already cached. The
> remaining javascript code embedded into some renderers are just not
> significantly large enough.
>
> Do we plan to implement the same convention in myfaces-builder-plugin?
> I.e.
> An abstract renderer class that c ontains the javascript template
> comment
> A concrete subclass of the one above generated by
> myfaces-builder-plugin that has the template comment from parent
> abstract class converted into java code
>
Actually I would go for the concrete implementation approach. The maven
plugin of the compiler can take care if picking up the correct files.
It even has package rewriting possibilities (I added such a directive to
the grammar on thursday)
So that people can work on the templated java files and have haven
compile the result into the generated sources (and still can link into
those if needed, due to being in a different package)...
Re: Another approach to the templating problem
Posted by Paul Rivera <pa...@yahoo.com>.
Interesting solution :)
I agree that the execution time of a compiler level solution will be better than an interpreted template solution.� Perhaps the only scenario that our interpreted template solution will yeild significant execution performance gain is when it caches large amounts of javascript code.� Browsing through the components, most of our large javascript code are already rendered through AddResource which is already cached.� The remaining javascript code embedded into some renderers are just not significantly large enough.
Do we plan to implement the same convention in myfaces-builder-plugin?
I.e.
��� An abstract renderer class that contains the javascript template comment
��� A concrete subclass of the one above generated by myfaces-builder-plugin that has the template comment from parent abstract class converted into java code
Best Regards,
Paul Rivera
--- On Sun, 10/5/08, Leonardo Uribe <lu...@gmail.com> wrote:
From: Leonardo Uribe <lu...@gmail.com>
Subject: Re: Another approach to the templating problem
To: "MyFaces Development" <de...@myfaces.apache.org>
Date: Sunday, October 5, 2008, 9:09 AM
On Sat, Oct 4, 2008 at 3:57 AM, Werner Punz <we...@gmail.com> wrote:
Hello everyone
I have developed another approach to the templating problem.
Most solutions which tried to tackle the approach worked on interepted template level:
https://issues.apache.org/jira/browse/TOMAHAWK-1327
I did another approach the last few weeks
I made an embedded templating compiler for java
I did it due to the inherent speed hits we have by using existing templating solutions and due to the fact that I want to parts of the code in the dojo components project over to templates to increase readability:
What I did was to develop with antlr some mini velocity which can be embedded into java via special comments.
The advantage is, that you simply can embed your templates inline via
a comment flag you can work on valid java code while still having your templating code in one place. It is more or less an inverse scriptlet system to be usable from java.
I will give an example
public class SimpleTest {
� �static String helloWorld = "hello world";
� �private calledMethod() {
� � � �System.out.println("called function");
� �}
� �public void emitTemplate() {
� � � �String [] values = new String[5];
� � � �values[0] = "value0";
� � � �values[1] = "value1";
� � � �values[2] = "value2";
� � � �values[3] = "value3";
� � � �values[4] = "value4";
� � � �/*TPL
� � � � � #outputop(System.out.println)
� � � � � This is a test for a simple embedded template
� � � � � $helloWorld
� � � � � <table>
� � � � � <tbody>
� � � � � #each(String, $values)
� � � � � </tr><td>$it</td></tr>
� � � � � #end
� � � � � calling a method
� � � � � $this.calledMethod();
� � � � � this text should follow after table!
� � � �TPL*/
� �}
}
This code is then basically rendered against
the output System.out.println
(other output directives can given via an
#outputop(<output directive>)
command in the template!
I know this approach is not academic due to no MVC
and due to extended control commands like iterations and selections
within the language and the possibility to call external methods
within the template.
The advantage however is, the strings are rendered straight into
output directives almost like handwritten code, by avoiding introspection I can gain similar speeds
(however with the disadvantage that you have to pass a casting datatype
into the #for and #each loops)
But if the community would like it I would merge it into our
utils project next week. Otherwise I can drop it somewhere else.
I would like to see this in myfaces-builder-plugin, so this feature can be extended properly in the future.
This could improve the way we write some component parts, so it is most welcome.
�
Werner
Re: Another approach to the templating problem
Posted by Leonardo Uribe <lu...@gmail.com>.
On Sat, Oct 4, 2008 at 3:57 AM, Werner Punz <we...@gmail.com> wrote:
> Hello everyone
>
> I have developed another approach to the templating problem.
> Most solutions which tried to tackle the approach worked on interepted
> template level:
>
> https://issues.apache.org/jira/browse/TOMAHAWK-1327
>
> I did another approach the last few weeks
> I made an embedded templating compiler for java
>
> I did it due to the inherent speed hits we have by using existing
> templating solutions and due to the fact that I want to parts of the code in
> the dojo components project over to templates to increase readability:
>
>
> What I did was to develop with antlr some mini velocity which can be
> embedded into java via special comments.
> The advantage is, that you simply can embed your templates inline via
> a comment flag you can work on valid java code while still having your
> templating code in one place. It is more or less an inverse scriptlet system
> to be usable from java.
>
>
> I will give an example
>
> public class SimpleTest {
>
> static String helloWorld = "hello world";
>
> private calledMethod() {
>
> System.out.println("called function");
> }
>
> public void emitTemplate() {
>
> String [] values = new String[5];
> values[0] = "value0";
> values[1] = "value1";
> values[2] = "value2";
> values[3] = "value3";
> values[4] = "value4";
>
>
>
> /*TPL
> #outputop(System.out.println)
> This is a test for a simple embedded template
>
> $helloWorld
>
> <table>
> <tbody>
>
> #each(String, $values)
> </tr><td>$it</td></tr>
> #end
>
> calling a method
>
> $this.calledMethod();
>
> this text should follow after table!
>
> TPL*/
>
>
> }
>
> }
>
>
> This code is then basically rendered against
> the output System.out.println
>
> (other output directives can given via an
> #outputop(<output directive>)
> command in the template!
>
> I know this approach is not academic due to no MVC
> and due to extended control commands like iterations and selections
> within the language and the possibility to call external methods
> within the template.
>
> The advantage however is, the strings are rendered straight into
> output directives almost like handwritten code, by avoiding introspection I
> can gain similar speeds
>
> (however with the disadvantage that you have to pass a casting datatype
> into the #for and #each loops)
>
> But if the community would like it I would merge it into our
> utils project next week. Otherwise I can drop it somewhere else.
>
I would like to see this in myfaces-builder-plugin, so this feature can be
extended properly in the future.
This could improve the way we write some component parts, so it is most
welcome.
>
> Werner
>
>
>
>