Typed Templates (views) in Stripes ?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Typed Templates (views) in Stripes ?

VANKEISBELCK Remi
Hi folks,

I'm trying out something quite cool, I though I'd share with you. 

Pretty long email, but I think this could be a killer feature for our favourite fwk.

For some of you who don't know Play2, they have (amongst very good other stuff) a neat feature called Scala Templates.

The idea is to have statically typed templates, just like everything else. The template defines a signature (named arguments), and it ends up as a actual function. You write the template in Scala, using a mix of html and code, and you must define the template's signature. You then call the function to render the template, passing any required argument. Simple, and safe.

This is not so common in MVCs. I don't know any pure Java fwk doing this.

It has great advantages, I won't explain the benefits of Type Safety here, but it's definitely a killer feature. Type safety applied to web page templates ! 

To be honest, this almost got me. For a moment I thought, damn, we're f*cking laaate with Stripes. I was about to switch to Play for good.

But before this, and using a few days off I had, I wanted to figure out how this would work in pure Java. Play is written in Scala which is a completely different language, allowing for those neat templates. But how can we do this in good old Java ?

So I started by creating a "typed text templating framework" that allows to write templates using a subset of the JSP syntax, and to compile them to strong-typed Java code. 

The name is TTT, which stands for Typed Text Templates.

Here's how a simple template looks like (MyTemplate.ttt) :

<%!
  String foo;
%>
<div class="my">
  <%= foo %>
</div>

The JSP declaration ( "<%!" ) is used to define the signature of the template. This one takes a single argument "foo" of type String. Then, it has some text (html actually) and an expression. As you imagine, the expression is replaced by its value when the template gets rendered. 

The TTT compiler can be invoked in order to generate a fully-functional Java class, that you can use in your code to render the template :

// somewhere in my code
Writer out = ...;
new MyTemplate("hey there !").render(out);

As you see, the signature of the template maps to constructor arguments, and you have a render(out) method to spit out the template to a Writer. You can also compose templates, but I won't explain this here for the sake of brevity (really ?).

So far so good. I can :
1/ write my templates almost like a JSP
2/ compile the templates to Java code
3/ invoke the generated code and render the templates to a Writer

Now, how does this integrate with Stripes ? Can we remove JSPs and use TTT templates instead ? Well, yes, we can ! 

Rendering a template from an Action looks like :

public Resolution doSomething() {
  // do stuff
  ...
  return new TemplateResolution( new MyTemplate("hello there") );
}

Very easy : the class TemplateResolution (implements Resolution) does the job. All you need to do is pass a template to its sole constructor.

Let's try a to apply our good old "pre-action" pattern to this, with a simple action+template :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new TemplateResolution( new MyTemplate(this) );
  }
}

And now the template (MyTemplate.ttt) :

<%!
  // template needs the action
  MyAction myAction;
%>
<html>
...
<div>
  <%= myAction.getStuff() %>
</div>
...
</html>

Again, very easy :
1/ The action bean returns a TemplateResolution, passing itself to MyTemplate's constructor
2/ The template uses the bean, declated as an argument, as any other Java object.

The big (huge) difference here with the current approach using JSP is that everything is statically typed. 

Let's compare this to the "regular" JSP approach :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new ForwardResolution("/WEB-INF/jsp/my.jsp");
  }
}

And the JSP :

<%@ page ... %>
<html>
...
<div>
  ${actionBean.stuff}
</div>
...
</html>

Several problems here :
* in the controller, the forward is... a plain string. The JSP could even not be there at runtime, who knows...
* no args are passed to the JSP when forwarding. The context is usually the request scope, which acts as a loose-typed hashmap...
* in the JSP, what is "actionBean" ? you need to assume somebody has tossed an object that has a "stuff" property into some scope (request ? session ? app ? ...). Again, no compile-time help. Ok you could use a scriplet and cast, but still : do you have a guarantee it's there, and it's what you want ?

The TTT approach removes all those issues, and "fills the blank" between the Controller and the View layers. Using this technique, it's all statically typed. No more expectations about the presence of an attribute or anything. 

It also brings lots of other benefits :
* more reusable views 
* container-independent : same technology for serving web pages or spitting out emails or anything
* support for composite templates (nested) - think "typed Stripes layouts"
* ...

Of course, the Stripes taglib doesn't work in .ttt templates, so it has to be reimplemented as pure Java APIs, useable directly from the templates. It's a bit long, there's a lot of them, and the mapping ain't necessarily 1:1. But it's a good opportunity to rethink the tags, and craft a nice, fluent API.

An example of s:form. The classic one, JSP+tags :

<%@ taglib prefix="s" ... %>
...
<s:form beanclass="<%=MyAction.class%>">
  Fill me 
  <s:text name="myProp"/> 
  and 
  <s:submit name="doIt" value="Click Me"/>
</s:form>

And the TTT equivalent :

<%! ... %>
<%
  StripesTags stripes = new StripesTags(out);
  try ( Form f = stripes.form(MyAction.class).build() ) {
%>
    Fill me 
    <%= f.text( "myProp" ) %>
    and
    <%= f.submit( "doIt", "Click Me" ) %>
<% } %>

As you see, it's using standard Java code in order to call the Stripes "tags". I'm trying various approaches, like the try-resource for tags that have a body. Again, it's a good opportunity to review the existing tags, and design clean APIs for those.

It is a pretty ambitious project : there are many domains involved (compilation, IDE, etc). But it is challenging, and I think it really provides added value. 

Stripes is getting old, and without such kind of new features, it'll probably die slowly in favor of Spring or any other MVC.

I looked at Spring to see if I could integrate in there. Could be done too, and would work just fine. But I think SpringMVC is a beast, it's too big, and I like the programming model and simplicity of Stripes.

The project is open and free for anyone to try out / contribute :

For the moment I have :
* template compiler : creates Java source code from .ttt files
* maven mojo : compiles templates when building the app (generate-sources phase)
* IntelliJ IDEA plugin : compile on save

It's still mostly a POC and needs some work to make it production-grade, but it's functional enough to play with.

What do you think folks ? 

Cheers

Rémi



------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development
Reply | Threaded
Open this post in threaded view
|

Re: Typed Templates (views) in Stripes ?

guillaume besse
Hi rémi,


Your arguments are very good and TTT looks simple and powerfull...  

And personally I am not a big fan of JSTL : I prefer java code in my template !

Do you think classic stripes templating and TTT could live together side by side ?

Is it possible to have a fragment template used by multiple templates ? Example welcome..


Regards
Guillaume




On Mon, Aug 3, 2015 at 2:52 PM, VANKEISBELCK Remi <[hidden email]> wrote:
Hi folks,

I'm trying out something quite cool, I though I'd share with you. 

Pretty long email, but I think this could be a killer feature for our favourite fwk.

For some of you who don't know Play2, they have (amongst very good other stuff) a neat feature called Scala Templates.

The idea is to have statically typed templates, just like everything else. The template defines a signature (named arguments), and it ends up as a actual function. You write the template in Scala, using a mix of html and code, and you must define the template's signature. You then call the function to render the template, passing any required argument. Simple, and safe.

This is not so common in MVCs. I don't know any pure Java fwk doing this.

It has great advantages, I won't explain the benefits of Type Safety here, but it's definitely a killer feature. Type safety applied to web page templates ! 

To be honest, this almost got me. For a moment I thought, damn, we're f*cking laaate with Stripes. I was about to switch to Play for good.

But before this, and using a few days off I had, I wanted to figure out how this would work in pure Java. Play is written in Scala which is a completely different language, allowing for those neat templates. But how can we do this in good old Java ?

So I started by creating a "typed text templating framework" that allows to write templates using a subset of the JSP syntax, and to compile them to strong-typed Java code. 

The name is TTT, which stands for Typed Text Templates.

Here's how a simple template looks like (MyTemplate.ttt) :

<%!
  String foo;
%>
<div class="my">
  <%= foo %>
</div>

The JSP declaration ( "<%!" ) is used to define the signature of the template. This one takes a single argument "foo" of type String. Then, it has some text (html actually) and an expression. As you imagine, the expression is replaced by its value when the template gets rendered. 

The TTT compiler can be invoked in order to generate a fully-functional Java class, that you can use in your code to render the template :

// somewhere in my code
Writer out = ...;
new MyTemplate("hey there !").render(out);

As you see, the signature of the template maps to constructor arguments, and you have a render(out) method to spit out the template to a Writer. You can also compose templates, but I won't explain this here for the sake of brevity (really ?).

So far so good. I can :
1/ write my templates almost like a JSP
2/ compile the templates to Java code
3/ invoke the generated code and render the templates to a Writer

Now, how does this integrate with Stripes ? Can we remove JSPs and use TTT templates instead ? Well, yes, we can ! 

Rendering a template from an Action looks like :

public Resolution doSomething() {
  // do stuff
  ...
  return new TemplateResolution( new MyTemplate("hello there") );
}

Very easy : the class TemplateResolution (implements Resolution) does the job. All you need to do is pass a template to its sole constructor.

Let's try a to apply our good old "pre-action" pattern to this, with a simple action+template :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new TemplateResolution( new MyTemplate(this) );
  }
}

And now the template (MyTemplate.ttt) :

<%!
  // template needs the action
  MyAction myAction;
%>
<html>
...
<div>
  <%= myAction.getStuff() %>
</div>
...
</html>

Again, very easy :
1/ The action bean returns a TemplateResolution, passing itself to MyTemplate's constructor
2/ The template uses the bean, declated as an argument, as any other Java object.

The big (huge) difference here with the current approach using JSP is that everything is statically typed. 

Let's compare this to the "regular" JSP approach :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new ForwardResolution("/WEB-INF/jsp/my.jsp");
  }
}

And the JSP :

<%@ page ... %>
<html>
...
<div>
  ${actionBean.stuff}
</div>
...
</html>

Several problems here :
* in the controller, the forward is... a plain string. The JSP could even not be there at runtime, who knows...
* no args are passed to the JSP when forwarding. The context is usually the request scope, which acts as a loose-typed hashmap...
* in the JSP, what is "actionBean" ? you need to assume somebody has tossed an object that has a "stuff" property into some scope (request ? session ? app ? ...). Again, no compile-time help. Ok you could use a scriplet and cast, but still : do you have a guarantee it's there, and it's what you want ?

The TTT approach removes all those issues, and "fills the blank" between the Controller and the View layers. Using this technique, it's all statically typed. No more expectations about the presence of an attribute or anything. 

It also brings lots of other benefits :
* more reusable views 
* container-independent : same technology for serving web pages or spitting out emails or anything
* support for composite templates (nested) - think "typed Stripes layouts"
* ...

Of course, the Stripes taglib doesn't work in .ttt templates, so it has to be reimplemented as pure Java APIs, useable directly from the templates. It's a bit long, there's a lot of them, and the mapping ain't necessarily 1:1. But it's a good opportunity to rethink the tags, and craft a nice, fluent API.

An example of s:form. The classic one, JSP+tags :

<%@ taglib prefix="s" ... %>
...
<s:form beanclass="<%=MyAction.class%>">
  Fill me 
  <s:text name="myProp"/> 
  and 
  <s:submit name="doIt" value="Click Me"/>
</s:form>

And the TTT equivalent :

<%! ... %>
<%
  StripesTags stripes = new StripesTags(out);
  try ( Form f = stripes.form(MyAction.class).build() ) {
%>
    Fill me 
    <%= f.text( "myProp" ) %>
    and
    <%= f.submit( "doIt", "Click Me" ) %>
<% } %>

As you see, it's using standard Java code in order to call the Stripes "tags". I'm trying various approaches, like the try-resource for tags that have a body. Again, it's a good opportunity to review the existing tags, and design clean APIs for those.

It is a pretty ambitious project : there are many domains involved (compilation, IDE, etc). But it is challenging, and I think it really provides added value. 

Stripes is getting old, and without such kind of new features, it'll probably die slowly in favor of Spring or any other MVC.

I looked at Spring to see if I could integrate in there. Could be done too, and would work just fine. But I think SpringMVC is a beast, it's too big, and I like the programming model and simplicity of Stripes.

The project is open and free for anyone to try out / contribute :

For the moment I have :
* template compiler : creates Java source code from .ttt files
* maven mojo : compiles templates when building the app (generate-sources phase)
* IntelliJ IDEA plugin : compile on save

It's still mostly a POC and needs some work to make it production-grade, but it's functional enough to play with.

What do you think folks ? 

Cheers

Rémi



------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development



------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development
Reply | Threaded
Open this post in threaded view
|

Re: Typed Templates (views) in Stripes ?

Joaquin Valdez-2
In reply to this post by VANKEISBELCK Remi
Love this idea! I too have been trying out Play2 and I would love to see this TTT feature added to Stripes.

Joaquin Valdez
[hidden email]


On Aug 3, 2015, at 6:52 AM, VANKEISBELCK Remi <[hidden email]> wrote:

Hi folks,

I'm trying out something quite cool, I though I'd share with you. 

Pretty long email, but I think this could be a killer feature for our favourite fwk.

For some of you who don't know Play2, they have (amongst very good other stuff) a neat feature called Scala Templates.

The idea is to have statically typed templates, just like everything else. The template defines a signature (named arguments), and it ends up as a actual function. You write the template in Scala, using a mix of html and code, and you must define the template's signature. You then call the function to render the template, passing any required argument. Simple, and safe.

This is not so common in MVCs. I don't know any pure Java fwk doing this.

It has great advantages, I won't explain the benefits of Type Safety here, but it's definitely a killer feature. Type safety applied to web page templates ! 

To be honest, this almost got me. For a moment I thought, damn, we're f*cking laaate with Stripes. I was about to switch to Play for good.

But before this, and using a few days off I had, I wanted to figure out how this would work in pure Java. Play is written in Scala which is a completely different language, allowing for those neat templates. But how can we do this in good old Java ?

So I started by creating a "typed text templating framework" that allows to write templates using a subset of the JSP syntax, and to compile them to strong-typed Java code. 

The name is TTT, which stands for Typed Text Templates.

Here's how a simple template looks like (MyTemplate.ttt) :

<%!
  String foo;
%>
<div class="my">
  <%= foo %>
</div>

The JSP declaration ( "<%!" ) is used to define the signature of the template. This one takes a single argument "foo" of type String. Then, it has some text (html actually) and an expression. As you imagine, the expression is replaced by its value when the template gets rendered. 

The TTT compiler can be invoked in order to generate a fully-functional Java class, that you can use in your code to render the template :

// somewhere in my code
Writer out = ...;
new MyTemplate("hey there !").render(out);

As you see, the signature of the template maps to constructor arguments, and you have a render(out) method to spit out the template to a Writer. You can also compose templates, but I won't explain this here for the sake of brevity (really ?).

So far so good. I can :
1/ write my templates almost like a JSP
2/ compile the templates to Java code
3/ invoke the generated code and render the templates to a Writer

Now, how does this integrate with Stripes ? Can we remove JSPs and use TTT templates instead ? Well, yes, we can ! 

Rendering a template from an Action looks like :

public Resolution doSomething() {
  // do stuff
  ...
  return new TemplateResolution( new MyTemplate("hello there") );
}

Very easy : the class TemplateResolution (implements Resolution) does the job. All you need to do is pass a template to its sole constructor.

Let's try a to apply our good old "pre-action" pattern to this, with a simple action+template :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new TemplateResolution( new MyTemplate(this) );
  }
}

And now the template (MyTemplate.ttt) :

<%!
  // template needs the action
  MyAction myAction;
%>
<html>
...
<div>
  <%= myAction.getStuff() %>
</div>
...
</html>

Again, very easy :
1/ The action bean returns a TemplateResolution, passing itself to MyTemplate's constructor
2/ The template uses the bean, declated as an argument, as any other Java object.

The big (huge) difference here with the current approach using JSP is that everything is statically typed. 

Let's compare this to the "regular" JSP approach :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new ForwardResolution("/WEB-INF/jsp/my.jsp");
  }
}

And the JSP :

<%@ page ... %>
<html>
...
<div>
  ${actionBean.stuff}
</div>
...
</html>

Several problems here :
* in the controller, the forward is... a plain string. The JSP could even not be there at runtime, who knows...
* no args are passed to the JSP when forwarding. The context is usually the request scope, which acts as a loose-typed hashmap...
* in the JSP, what is "actionBean" ? you need to assume somebody has tossed an object that has a "stuff" property into some scope (request ? session ? app ? ...). Again, no compile-time help. Ok you could use a scriplet and cast, but still : do you have a guarantee it's there, and it's what you want ?

The TTT approach removes all those issues, and "fills the blank" between the Controller and the View layers. Using this technique, it's all statically typed. No more expectations about the presence of an attribute or anything. 

It also brings lots of other benefits :
* more reusable views 
* container-independent : same technology for serving web pages or spitting out emails or anything
* support for composite templates (nested) - think "typed Stripes layouts"
* ...

Of course, the Stripes taglib doesn't work in .ttt templates, so it has to be reimplemented as pure Java APIs, useable directly from the templates. It's a bit long, there's a lot of them, and the mapping ain't necessarily 1:1. But it's a good opportunity to rethink the tags, and craft a nice, fluent API.

An example of s:form. The classic one, JSP+tags :

<%@ taglib prefix="s" ... %>
...
<s:form beanclass="<%=MyAction.class%>">
  Fill me 
  <s:text name="myProp"/> 
  and 
  <s:submit name="doIt" value="Click Me"/>
</s:form>

And the TTT equivalent :

<%! ... %>
<%
  StripesTags stripes = new StripesTags(out);
  try ( Form f = stripes.form(MyAction.class).build() ) {
%>
    Fill me 
    <%= f.text( "myProp" ) %>
    and
    <%= f.submit( "doIt", "Click Me" ) %>
<% } %>

As you see, it's using standard Java code in order to call the Stripes "tags". I'm trying various approaches, like the try-resource for tags that have a body. Again, it's a good opportunity to review the existing tags, and design clean APIs for those.

It is a pretty ambitious project : there are many domains involved (compilation, IDE, etc). But it is challenging, and I think it really provides added value. 

Stripes is getting old, and without such kind of new features, it'll probably die slowly in favor of Spring or any other MVC.

I looked at Spring to see if I could integrate in there. Could be done too, and would work just fine. But I think SpringMVC is a beast, it's too big, and I like the programming model and simplicity of Stripes.

The project is open and free for anyone to try out / contribute :

For the moment I have :
* template compiler : creates Java source code from .ttt files
* maven mojo : compiles templates when building the app (generate-sources phase)
* IntelliJ IDEA plugin : compile on save

It's still mostly a POC and needs some work to make it production-grade, but it's functional enough to play with.

What do you think folks ? 

Cheers

Rémi


------------------------------------------------------------------------------
_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development


------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development
Reply | Threaded
Open this post in threaded view
|

Re: Typed Templates (views) in Stripes ?

VANKEISBELCK Remi
In reply to this post by guillaume besse
Hi Guillaume,

Answers inlined 

And personally I am not a big fan of JSTL : I prefer java code in my template !

I used to like JSTL when I wasn't bothered by loose typing. Looked like it was good then. But when I look back at it, I think it's crap... anyway.
 
Do you think classic stripes templating and TTT could live together side by side ?

Nope. TTT is pure Java, JSP-less. 

Good new is, it actually removes the requirement for Stripes layouts. I mean, TTT templates can be composed and nested, which what stripes-layouts basically do. 

Here's an example (PageTemplate.ttt) :

<%!
  String title;
  ITemplate body;
%>
<html>
...
<title>
  <%= title %>
</title>
...
<body>
  <%= body %>
</body>
</html>

As you see the 2nd arg is... a template. When used in an expression ( <%= tpl %> ), it is rendered inside the wrapping template. 

Your action bean's event handler can do stuff like :

// create inner template for body
MyTemplate body = new MyTemplate( ... );
// create a page that includes body
PageTemplate page = new PageTemplate("hey there", body );
// return a resolution to spit out the whole page
return new TemplateResolution( page );

As you see, it's plain old Java. No fuss. 

 

Is it possible to have a fragment template used by multiple templates ? Example welcome..

Yep. As said above, any kind of nesting is possible. Let's try another example : a template that renders a table, which itself uses another template to render rows :

<%-- TableTemplate.ttt --%>
<%!
  List<Foo> foos;
%>
<table>
<tbody>
<% for (Foo f : foos) { %>
  <%= new RowTemplate(f) %>
<% } %>
</tbody>
</table>

And the Row template :

<%-- RowTemplate.ttt --%>
<%!
  Foo foo;
%>
<tr>
<td><%= foo.getProp1() %></td>
<td><%= foo.getProp2() %></td>
<td><%= foo.getProp3() %></td>
</tr>

Rendering the whole table goes like 

List<Foo> foos = ... ;
return new TemplateResolution( new TableTemplate( foos ) );

Looks far better to me than a dumb <jsp:include/>... The only approaching stuff is JSP tags. Unfortunately you still need JSPs to use them...

Cheers

Rémi

 


Regards
Guillaume




On Mon, Aug 3, 2015 at 2:52 PM, VANKEISBELCK Remi <[hidden email]> wrote:
Hi folks,

I'm trying out something quite cool, I though I'd share with you. 

Pretty long email, but I think this could be a killer feature for our favourite fwk.

For some of you who don't know Play2, they have (amongst very good other stuff) a neat feature called Scala Templates.

The idea is to have statically typed templates, just like everything else. The template defines a signature (named arguments), and it ends up as a actual function. You write the template in Scala, using a mix of html and code, and you must define the template's signature. You then call the function to render the template, passing any required argument. Simple, and safe.

This is not so common in MVCs. I don't know any pure Java fwk doing this.

It has great advantages, I won't explain the benefits of Type Safety here, but it's definitely a killer feature. Type safety applied to web page templates ! 

To be honest, this almost got me. For a moment I thought, damn, we're f*cking laaate with Stripes. I was about to switch to Play for good.

But before this, and using a few days off I had, I wanted to figure out how this would work in pure Java. Play is written in Scala which is a completely different language, allowing for those neat templates. But how can we do this in good old Java ?

So I started by creating a "typed text templating framework" that allows to write templates using a subset of the JSP syntax, and to compile them to strong-typed Java code. 

The name is TTT, which stands for Typed Text Templates.

Here's how a simple template looks like (MyTemplate.ttt) :

<%!
  String foo;
%>
<div class="my">
  <%= foo %>
</div>

The JSP declaration ( "<%!" ) is used to define the signature of the template. This one takes a single argument "foo" of type String. Then, it has some text (html actually) and an expression. As you imagine, the expression is replaced by its value when the template gets rendered. 

The TTT compiler can be invoked in order to generate a fully-functional Java class, that you can use in your code to render the template :

// somewhere in my code
Writer out = ...;
new MyTemplate("hey there !").render(out);

As you see, the signature of the template maps to constructor arguments, and you have a render(out) method to spit out the template to a Writer. You can also compose templates, but I won't explain this here for the sake of brevity (really ?).

So far so good. I can :
1/ write my templates almost like a JSP
2/ compile the templates to Java code
3/ invoke the generated code and render the templates to a Writer

Now, how does this integrate with Stripes ? Can we remove JSPs and use TTT templates instead ? Well, yes, we can ! 

Rendering a template from an Action looks like :

public Resolution doSomething() {
  // do stuff
  ...
  return new TemplateResolution( new MyTemplate("hello there") );
}

Very easy : the class TemplateResolution (implements Resolution) does the job. All you need to do is pass a template to its sole constructor.

Let's try a to apply our good old "pre-action" pattern to this, with a simple action+template :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new TemplateResolution( new MyTemplate(this) );
  }
}

And now the template (MyTemplate.ttt) :

<%!
  // template needs the action
  MyAction myAction;
%>
<html>
...
<div>
  <%= myAction.getStuff() %>
</div>
...
</html>

Again, very easy :
1/ The action bean returns a TemplateResolution, passing itself to MyTemplate's constructor
2/ The template uses the bean, declated as an argument, as any other Java object.

The big (huge) difference here with the current approach using JSP is that everything is statically typed. 

Let's compare this to the "regular" JSP approach :

public class MyAction implements ActionBean {
  
  public String getStuff() {
    ...
  }

  @DefaultHandler
  public Resolution doIt() {
    return new ForwardResolution("/WEB-INF/jsp/my.jsp");
  }
}

And the JSP :

<%@ page ... %>
<html>
...
<div>
  ${actionBean.stuff}
</div>
...
</html>

Several problems here :
* in the controller, the forward is... a plain string. The JSP could even not be there at runtime, who knows...
* no args are passed to the JSP when forwarding. The context is usually the request scope, which acts as a loose-typed hashmap...
* in the JSP, what is "actionBean" ? you need to assume somebody has tossed an object that has a "stuff" property into some scope (request ? session ? app ? ...). Again, no compile-time help. Ok you could use a scriplet and cast, but still : do you have a guarantee it's there, and it's what you want ?

The TTT approach removes all those issues, and "fills the blank" between the Controller and the View layers. Using this technique, it's all statically typed. No more expectations about the presence of an attribute or anything. 

It also brings lots of other benefits :
* more reusable views 
* container-independent : same technology for serving web pages or spitting out emails or anything
* support for composite templates (nested) - think "typed Stripes layouts"
* ...

Of course, the Stripes taglib doesn't work in .ttt templates, so it has to be reimplemented as pure Java APIs, useable directly from the templates. It's a bit long, there's a lot of them, and the mapping ain't necessarily 1:1. But it's a good opportunity to rethink the tags, and craft a nice, fluent API.

An example of s:form. The classic one, JSP+tags :

<%@ taglib prefix="s" ... %>
...
<s:form beanclass="<%=MyAction.class%>">
  Fill me 
  <s:text name="myProp"/> 
  and 
  <s:submit name="doIt" value="Click Me"/>
</s:form>

And the TTT equivalent :

<%! ... %>
<%
  StripesTags stripes = new StripesTags(out);
  try ( Form f = stripes.form(MyAction.class).build() ) {
%>
    Fill me 
    <%= f.text( "myProp" ) %>
    and
    <%= f.submit( "doIt", "Click Me" ) %>
<% } %>

As you see, it's using standard Java code in order to call the Stripes "tags". I'm trying various approaches, like the try-resource for tags that have a body. Again, it's a good opportunity to review the existing tags, and design clean APIs for those.

It is a pretty ambitious project : there are many domains involved (compilation, IDE, etc). But it is challenging, and I think it really provides added value. 

Stripes is getting old, and without such kind of new features, it'll probably die slowly in favor of Spring or any other MVC.

I looked at Spring to see if I could integrate in there. Could be done too, and would work just fine. But I think SpringMVC is a beast, it's too big, and I like the programming model and simplicity of Stripes.

The project is open and free for anyone to try out / contribute :

For the moment I have :
* template compiler : creates Java source code from .ttt files
* maven mojo : compiles templates when building the app (generate-sources phase)
* IntelliJ IDEA plugin : compile on save

It's still mostly a POC and needs some work to make it production-grade, but it's functional enough to play with.

What do you think folks ? 

Cheers

Rémi



------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development



------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development



------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development