Love this idea! I too have been trying out Play2 and I would love to see this 
TTT feature added to Stripes.

Joaquin Valdez
[email protected] <mailto:[email protected]>


> On Aug 3, 2015, at 6:52 AM, VANKEISBELCK Remi <[email protected]> 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 <https://www.playframework.com/>, they 
> have (amongst very good other stuff) a neat feature called Scala Templates 
> <https://www.playframework.com/documentation/2.0/ScalaTemplates>.
> 
> 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 :
> https://github.com/pojosontheweb/ttt <https://github.com/pojosontheweb/ttt>
> 
> 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
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/stripes-development

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

Reply via email to