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 <[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 > > 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
