Dec 6, 2012

Thinking about creating an new Java Web framework

Why: I love playframework v1 but not v2. However play team moves their attention away from v1.

What should be kept from v1:

  • Bytecode enhancement. This is a great stuff that enable framework and plugin developer to inject logic into Application code
  • A full stack framework. This should like Play which runs on itself instead of inside a servlet container
  • Support plugins. Though API might changed
  • Handy utility libraries for application developer, like IO, Codec, Images etc.
  • Built in simple Secure framework
  • The DB layer enable plugin different implementations, JPA, EBean, Morphia etc.
  • Built in validation
  • Easy to use asynchronous handling API, like Promise and Controller.await
  • Before, After, Final, Catch intecepters to plugin logic into request handling chain
  • Render with different template based on request.format
  • JavaExtension to template
  • And most important is Simple, Simple and Simple to application developers

What needs to be improved or changed:
  • Routing mechanism. Improve the routing performance for big routing table with more than 100 routes. This might involve code generator to generate routing source code dynamically
  • Action invocation mechanism. Reduce the use of reflection, static methods and Exception. But needs to keep the API still simple though
  • Plugin API. Support partitioned plugin API set instead of all-in-one big facade
  • Replace python stuff with pure script plus Java
  • CRUD
  • Replace default Groovy template engine with Rythm
  • Replace default JPA with Ebean ???
  • JSON support

Proposed Controller API:

public class Orders extends Controller {

  // --- Parameters used in action handling methods
  @Bind(method = Bind.ByID)
  protected Order order; // will bind to http request params with Order.findById(params.get("orderId"))
  
  @Bind(method = Bind.ById)
  protected User user;
  // -- eof Parameters
  
  // this use new return style API
  @Required("orderId")
  public Result show() {
    return new Render(order);
  }

  // this use old style API
  @Required("orderId")
  public void saveUpdate() {
    notFoundIfNull(user);
    order.save();
    render(order, user);
  }
  
  // this action method will be executed in a separate thread
  @Async
  public Result report() {
    order.save();
    List orders = ...
    return new RenderPDF(orders);
  }
  
}

Sample route file:

GET /orders/{orderId} Orders.show
POST /orders/{orderId} Orders.saveUpdate
GET /orderReport Orders.report

What do you think?

Aug 17, 2012

ToString Mode and Auto ToString Mode of Rythm template engine

In a recent blog I've introduced SIM (String Interpolation Mode) of Rythm. This blog introduces another two new feature named TSM (ToString Mode) and ATSM (Auto ToString Mode) of Rythm

ToString Mode

This feature allows developers to create String toString() method for their class easily:

public class Address {
    public String unitNo;
    public String streetNo;
    public String street;
    public String suburb;
    public String state;
    public String postCode;
    // use Rythm.toString() API call
    @Override public String toString() {
        return Rythm.toString("@_.unitNo @_.streetNo @_.street, @_.suburb, @_.state, @_.postCode", this);
    }
}

As a comparison, previously you need to write toString() method in the following way:

    @Override public String toString() {
        return Rythm.render("@args Address _;@_.unitNo @_.streetNo @_.street, @_.suburb, @_.state, @_.postCode", this);
    }

So here are several facts about TSM:

  1. the sign "_" is used to refer to this object instance in the template
  2. You don't need to declare "_" use @args statement in TSM
  3. You must use Rythm.toString() interface instead of the normal Rythm.render() in order to use TSM

Auto ToString Mode

If TSM makes writting toString() easy, ATSM makes it even easier because you don't need to write the template:

public class Address {
    public String unitNo;
    public String streetNo;
    public String street;
    public String suburb;
    public String state;
    public String postCode;
    @com.greenlaw110.rythm.toString.NoExpose
    public String accessCode;
    @Override public String toString() {
        return Rythm.toString(this);
    }
}

And you can pass in parameters to configure the style and output fields:

@Override public String toString() {
    return Rythm.toString(this,
        com.greenlaw110.rythm.toString.ToStringOption.defaultOption.setAppendTransient(true),
        com.greenlaw110.rythm.toString.ToStringStyle.MULTI_LINE_STYLE);
}

The above code indicate that output transient fields which is not output by default. It also indicate that output should be in multiple lines. Refer to here for more details out the option and styling configuration.

You can use the following annotation to mark the fields that you don't want to output with Rythm's ATSM:

  • com.greenlaw110.rythm.toString.NoExpose
  • org.codehaus.jackson.annotate.JsonIgnore

Compare to Apache Commons Lang's StringBuilder

Like ATSM, org.apache.commons.lang3.builder.ReflectionToStringBuilder also allows to generate toString() output automatically. ATSM is slightly (around 20%) faster than ReflectionToStringBuilder. As a comparison, TSM is 2 times faster than it.

Foot notes: Rythm Template Engine is a static typed Java template engine using Razor like syntax. There is a full feature set demo hosted on GAE. The source code is hosted on github

Jun 30, 2012

Rythm now has SIM (String Interpolation Mode)

In the latest release of Rythm Template Engine you can use String Interpolation Mode (short to SIM later) for simple template, where simple template means something you can do with String.format().
String result = Rythm.render("Hello @who!", "Rythm");
As a comparison, previously you need the following code:
String result = Rythm.render("@args String who;Hello @who!", "Rythm");
It's really annoy to declare render argument types for such a simple template because we could treat the argument used in the expression as an Object. Yes, this is exactly what SIM did for you, automatically declare the argument reference to java.lang.Object type, and save your typing. Looks not a big deal, but it literally make Rythm.render() an replacement of String.format() for most cases. You get two benefit from Rythm SIM over String format:
  1. performance: Rythm.render is 2 times faster than String.format except the first call
  2. You can pass in arguments not only by position, but also by name
    Map<String, Object> args = new HashMap<String, Object>();
    args.put("who", "world");
    String result = Rythm.render("Hello @who!", args);
    

SIM Limitation

So as mentioned above SIM only applies to simple templates. The question is what defines a simple template?
  • First you can only have single variables in an expression, reference to class fields or method or any combination of two or more variables is not allowed. If you want to use these advanced expression, you must declare the type of the render arguments explicitly

    Rythm.render("the name is @user.username", user); // bad
    Rythm.render("the name is @name", user.username); // good
    Rythm.render("@args User user;the name is @user.username", user); // good
    
    Rythm.render("the sum is @(left + right)", left, right); // bad
    Rythm.render("the sum is @sum", left + right); // good
    Rythm.render("@args int left, int right;the sum is @(left + right)", left, right); // good
    
  • You cannot use some keywords. In other words, some Rythm template features are not available to SIM. Here is a list of Rythm keywords you should avoid to use in SIM:

    1. @args, declare template argument variables
    2. @extends, extends a layout template
    3. @section, define a template part to be inserted in the layout template
    4. @render, used in layout template to render a template section defined in sub template
    5. @doLayout, same as @render
    6. @doBody, call back tag body
    7. @include, include another template content in place
    8. @set, set template variable to be fetched by layout template
    9. @get, get the template variable set in the sub template
    10. @expand, execute/expand an macro
    11. @exec, same as expand
    12. @macro, define an macro
    13. @def, define an inline tag
    14. @tag, same as @def
    15. All extended keywords including the following defined in PlayRythm plugin
      1. @url, reverse url lookup
      2. @fullUrl, absolute reverse url lookup
      3. @msg, message lookup

How to render with SIM

Now the question is how to specify Rythm to render with SIM instead of ordinary rendering mode. The answer is simple, if your template does not contains the keywords listed above, Rythm will render the template in SIM.

Foot notes: Rythm Template Engine is a static typed Java template engine using Razor like syntax. There is a full feature set demo hosted on GAE. The source code is hosted on github

May 24, 2012

Step by step migrate your Groovy template to Rythm template - Part Two

In the Step by step migrate your Groovy template to Rythm - Part One I have introduced how to import Rythm module and the overview steps to do the migrate. I have also inspect the Rythm template essentials including expression, flow control, scripting and comment. Now let's take a look at page layout management.

Groovy use #{extends} tag to specify the layout template you want to apply to the current template. On the layout template side, you can use #{doLayout} tag to load the content from sub template. Here is the typical scenario you met on Groovy template:

1. views/Application/index.html:
#{extends "main.html"/}

Home

...

2. views/main.html:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
#{doLayout/}
... </body> </html>

Rythm use pretty much the same thing (@extends and @doLayout tag). Here is what they look like in Rythm:

1. rythm/Application/index.html:
@extends(main)

Home

...

2. rythm/main.html:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
@doLayout()
... </body> </html>

Pretty simple, isn't it? One place worth attention. I use @extends(main) instead of @extends("main.html"). Actually I could use the latter notation, but it is redundant:
  • template inheritance is static, which happen at parsing time, so the quotation mark is redundant
  • template file extension is deduct using the current template format, thus ".html" is redundant
In addition, suppose your layout template are not put into the view root, e.g. you have a layout template file app/views/themes/blueSky/main.html, to reference it in extends tag you do it this way in groovy:
#{extends "themes/blueSky/main.html"/}
In Rythm you can copy the groovy notation:
@extends("themes/blueSky/main.html")
But I recommend you to use the simple Java package notation:
@extends(themes.blueSky.main)
Note, you are free to use relative path and import path shortcuts when you reference the layout template in extends tag, click here to understand relative and import path shortcut.

In addition, @render() is an alias of @doLayout(). They are two identical tags, and it's up to you to decide which one fit your taste.

Now let's see something interesting.

Passing parameter to layout template


So you can pass parameter from content template to layout template via the #set and #get. Let's say you have a layout template main.html:
...
#{doLayout/}
And in your content template, say index.html:
#{extends "main.html"/}
...
#{set theme:"blueSky"/}
...
You can basically follow the same pattern in Rythm. Here is the main.html:
...
@doLayout()
And the content template:
@extends(main)
...
@set(theme:"blueSky")
...
Every thing looks good. However you have more than one way to achieve it in Rythm. Now let's define main.html like the follows:
@args String theme
...
@doLayout()
And the content template changed accordingly:
@extends(main, "blueSky")
...
It's more clean and simple than the clumsy @set and @get, isn't it?

Render sections


So what if you want the content template provides section contents to be inject into different places in the layout template? Groovy templates comes to get/set again. Let's see the main.html in Groovy:
...

#{doLayout/}
...
And the content template:
#{extends "main.html/}
...
#{set "sidebar"}
  • menu-1
  • ...
#{/set} ... #{set "footer"} copyright ... #{/set}
Now let's see how Rythm handle it. First, main.html:
...

@render()
@// as we said before @render() is an alias of @doLayout() ...
And the content template in rythm version:
@extends(main)
...
@section("sidebar") {
  
  • menu-1
  • ...
} ... @section("footer") { copyright ... } ...
So which style do you prefer? No double it's Rythm to me because it's simpler, cleaner, more consistent, and did I mention that Rythm has one feature that's not found in Groovy at all? Let's take a look at the new version of main.html with default content for "footer" section:
...

@render()
@// as we said before @render() is an alias of @doLayout() ...
Now you can omit the footer section from your content template, Rythm will pick up default content automatically!

In this article we introduced the differences and similarity between Groovy and Rythm on template layout management. We see how Rythm use @extends and @doLayout or @render tag to support layout reuse in template authoring. In the next post I am going to introduce you to another powerful feature of Rythm template engine: tags. See you soon!

See also: Step by step migrate your Groovy template to Rythm template - Part One

May 21, 2012

Step by step migrate your Groovy template to Rythm template - Part One

The content of this blog applies to PlayFramework 1.2.x

I've just release Rythm-1.0RC4 with new features including precompile support, null-safe expression and template class properties enhancement, I feel it's time to write this post as there is nearly nothing you can do with Groovy but not with Rythm. Yes you can leverage all your experiences gained from Play's Groovy template engine and apply them immediately to Rythm and gain a 3 to 20 times faster rendering speed with even more clean Razor like syntax.

So first of all, you are safe to do the migration, meaning you keep your system working at all time through out the whole process. Thanks to PlayFramework's rendering process and the plugin architecture, Rythm could implement an unobtrusive template engine plugin to playframework that co-exists with other template engines following the same convention.

To start using Rythm you need to add the following statement into your conf/dependencies.yml file:

    - play -> rythm 1.0.0-RC4 # 1.0.0-RC4 is the current version but you might change it accordingly

And then you go back to your console and type

play deps --sync
mkdir app/rythm

Congratulation! you got Rythm installed and rythm view root folder created, and it's time to take off. And here is what's going to be happened for each of your template files under app/views folder:

step1. copy the file to corresponding folder under app/rythm, e.g.
app/views/main.html -> app/rythm/main.html
app/views/Application/index.html -> app/rythm/Application/index.html

step2. update the file with Rythm syntax. (No worries, we will come back to this point very soon, I promise!)

step3. Type play run and go to your browser press F5 to check the result. You might rewind back to step2 if it needs to adjust here and there, but trust me it's not difficult to do. Once you are okay with this template, move to the next template file and repeat step 1, 2 and 3.

Remember that all the rest part of your entire application works except the template file you are updating. And by the end of each step 3, your whole application works like before. So don't be scared, it's not a big bung migration.

Now let's take our magnifier to inspect what is happening in step 2: update the groovy file with Rythm syntax.

1. Expression


In your groovy template, expressions are enclosed by "${}", E,g.
Hello ${who}

Rythm use "@" sign to mark an expression:
Hello @who

Smart guy will ask how to write the following expression in Rythm:
Jack is a ${vice}maniac.

Ok, here is how it looks like in Rythm:
Jack is a @(vice)maniac.

And similar for compound expressions:
@(foo.bar().numbers[5] + 16)

Note, to output the "@" sign, just put two "@" together:
John

1.1 Null-Safe Expression


I was impressed by the null-safe notation when I first read it and I found it's so handy to use, especially in the form html:
You don't need to say good-bye to null-safe expression, as Rythm brings you the same thing:

1.2 Expression escape


Like Groovy template engine, Rythm automatically escape expressions using html format. As a comparison, Japid won't automatically escape your expressions and require manually invoke the escape function to safely output expression: ${escape(expr)}.

However expression escape is not free, you sacrifice template rendering performance when you escape the expressions. So it's better for you to stop escaping while you are sure that part of your data is safe or you do what to output the HTML code. For a certain expression, use .raw() extension to stop auto-escape:
@html.raw()

If you want to output raw data for all expression in a segment of your template file, use @raw(){...} tag:
@raw() {
   None of the expression outputs will be escaped 
   including the @foo and @bar
}

2. Control flow


Unlike Groovy which use strange tag to expression control flow, Rythm use pure Java style to do it which makes it a compact, expressive, and more Java programmer friendly template language.

2.1 if condition


Groovy template:
#{if user.countryCode == 'en' }
    Connected user is ${user}
#{/if}

Rythm template:
@if ("en".equals(user.countryCode)) {
    Connected user is @user
}

2.2 if-else


Groovy:
#{if user}
    Connected user is ${user}
#{/if}
#{else}
    Please log in
#{/else}

Rythm:
@if(null != user) {
    Connected user is @user
} else {
    Please log in
}

2.3 if-else-if


Groovy:
#{if tasks.size() > 1}
    Busy tasklist
#{/if}
 
#{elseif tasks}
    One task on the list
#{/elseif}
 
#{else}
    Nothing to do
#{/else}

Rythm:
@if(tasks.size() > 1) {
    Busy tasklist
} else if (tasks.size() > 0) {
    One task on the list
} else{
    Nothing to do
}

2.4 loop


Groovy:
    #{list items:products, as:'product'}
  • ${product}
  • #{/list}
Rythm:
    @for(Product product:products) {
  • @product
  • }

All Groovy loop variables are also available in Rythm loop. For the case of the loop above, they are:
  • @product_index, the item’s index, starting at 1
  • @product_isLast, true for the last element
  • @product_isFirst, true for the first element
  • @product_parity, alternates between odd and even

In addition, Rythm provides one additional loop variable to make the parity identification be more convenient:
  • @product_isOdd, true for the odd order element

And to use those variables in your loop:
    @for(Product product:products) { @product_index. @product @(product_isLast ? "" : "-") }

3. Scripting and Comment


Like Groovy, Rythm provides facility to support inline scripting and comments in your template file, the differences is Groovy template engine use Groovy language to script while Rythm use pure Java lanaguage.

3.1 Comment


Groovy:
*{
    this is a block comment in Groovy template engine
}*

*{this is a line comment in Groovy template engine}*

Rythm:
@*
    This is a block comment in Rythm template engnine
*@

@*******************************************
* This is another block comment in Rythm
*******************************************@

@// this is a line comment in Rythm template engine

3.2 Scripting


Groovy use %{...}% and Groovy language to add dynamic logic into template:
%{
   fullName = client.name.toUpperCase()+' '+client.forname;
}%
 

Client ${fullName}


Rythm use @{...} and Java language to do the same work:
@{
   String fullName = client.name.toUpperCase() + " " + client.forname;
}

@****************************************************************
* Note, Groovy language use @{...} to do reverse url lookup, e.g:
* @{Application.index()}
*
* In Rythm you do reverse URL lookup using:
* @url(Application.index())
****************************************************************@

Client @fullName


In this article we briefly introduce how to migrate Groovy template to Rythm template step by step. We also inspected the essential usage of Rythm template including expression, flow control, scripting and comments.

In the next part I will introduce page layout management with @extend keyword, again it achieves all you have in Groovy and more. Stay tuned!

Apr 29, 2012

PlayRythm 1.0.0-RC1 released

Just released this new big version to Play's module repository. There are lots of improvements in terms of both functionality and documentation, several bug fixes and a few break changes:

break changes

  • @renderBody() does not render layout content now. It’s used to render tag body specifically. To render the layout content, use @doLayout() or @render() without section name parameter
  • Automatic escape expression with html format if the template file name suffix is .html. If your code breaks, try to use @raw() tag to surround relevant template part or export your variable with.raw() extension.
    • Note auto-escape can cause template execution performance up to 3 times slower(still much faster than groovy) depending on how many expressions there are in your template, but we consider it a good trade-off to offer a secure default behavior. For those people who “need for speed”, simply wrap your entire template content in raw block:@raw(){your content comes here}.
  • app/view as template root are no longer supported. All rythm template files must be put intoapp/rythm folder
  • app/view/tags/rythm as tag root are no longer supported. Just put tag files as normal template file into app/rythm folder
  • @section tag usage:
    • previously @section sectionName {...}
    • now @section(“sectionName”) {...}

New features

Small enhancements

Issues closed