tag:blogger.com,1999:blog-25603734268894856312024-03-05T08:51:48.043-08:00Thinking about SoftwareAnonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.comBlogger52125tag:blogger.com,1999:blog-2560373426889485631.post-38134164333511626082016-07-24T16:09:00.003-07:002016-07-24T16:09:37.410-07:00The Evil of "Evil Annotations"<div dir="ltr">
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
This blog is a comment to<span class="inbox-inbox-Apple-converted-space"> </span><a href="https://dzone.com/articles/evil-annotations" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">https://dzone.com/articles/evil-annotations</a></div>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
This is an evil article (Sorry I use the word "evil" which is copied from the article). And below is why</div>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
1) Annotation, like Java source code, is a way to express developer's intention to runtime environment. And it is a very expressive way of doing that. The author's point of "<em style="box-sizing: border-box;">reducing the reusability of class</em>" makes non-sense because:</div>
<ul style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px; padding-left: 2em;">
<li style="box-sizing: border-box;">the code with JEE annotation or other annotation is designed to run into a certain container/application server that follow the standard and understand the semantic of the anntoation as per designed</li>
<li style="margin-top: 0.25em;">you can't blame Java source code reduce the reusabilty because it cannot run by a ruby interpreter, right?</li>
</ul>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
2) In the "Evil Annotations Are Sometimes in the Wrong Place" section, the author point out that<code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; margin: 0px; padding: 0.2em 0px;">@ApplicationScoped</code><span class="inbox-inbox-Apple-converted-space"> </span>does not belong to the class "DocumentFormatter" as shown below:</div>
<div class="inbox-inbox-highlight inbox-inbox-highlight-source-java" style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; overflow: visible;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;">@<span class="inbox-inbox-pl-smi" style="box-sizing: border-box;">ApplicationScoped</span>
<span class="inbox-inbox-pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="inbox-inbox-pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="inbox-inbox-pl-en" style="color: rgb(121 , 93 , 163);">DocumentFormatter</span> {
<span class="inbox-inbox-pl-c1" style="color: rgb(0 , 134 , 179);">...</span>
}</pre>
</div>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
And my view is: the annotation clearly expressed one important factor of the class: it is an application level singleton object, and container/application does not need to instantiate the instance of that class multiple times. Without using that annotation, you probably will go back to the Singleton pattern, which adds couple lines of code without any additional benefit.</div>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
The other example about JPA class is also funny, the point of "<em style="box-sizing: border-box;">which couples the persistence directly to domain objects</em>", should be rephrased into "which reduce the couples between persistence layer and domain object", because any persistence layer that implement the JPA requirement can handle your domain object. I wonder if the author is still thinking of writing his own JDBC code to handle persistence of the domain object. Here I want to mention that "persistence" IS one attribute of a domain object, and it is the system specification of your application, it is unfair to split it out from the domain object just because it doesn't represent the functional specification. If you are doing that, it's kind of like to say a programmer shall not eat because eating is not the domain feature of a programmer, which is just programming.</div>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
3) The author gives out the alternative to annotation: "<em style="box-sizing: border-box;">of course good old Java Code</em>", but I couldn't see any real world project/framework/application support that conclusion. And I want to point out the author's affinity to "<em style="box-sizing: border-box;">the Java Language and its Compiler</em>" is not generic in any way. The reason people relies on Java language and it's compiler is because it ONE of the standard of transfer developer's intention (in Java source code) into instructions to be run in a reliable standard environment (JVM). And there are many other "languages and compilers" could be used to do the same thing. On the flip side of the concern, the author looks like ignored the runtime environment which is also a standard part of the system, JVM is no doubt one of them, and JVM itself is not the only example of it. JEE containers and many other stacks are also good example of standard runtime environment, and they do recognized annotations (standard or even non-standard).</div>
<div style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 16px; margin-top: 0px;">
In conclusion, the problems of the article are:</div>
<ol style="background-color: rgb(255 , 255 , 255); color: rgb(51 , 51 , 51); font-family: , "blinkmacsystemfont" , "segoe ui" , "roboto" , "helvetica" , "arial" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px; line-height: 21px; margin-bottom: 0px; margin-top: 0px; padding-left: 2em;">
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
The author's overlook of system specification while highlighting functional specification. (Found in the JPA and<span class="inbox-inbox-Apple-converted-space"> </span><code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; margin: 0px; padding: 0.2em 0px;">@ApplicationScoped</code><span class="inbox-inbox-Apple-converted-space"> </span>example)</div>
</li>
<li style="margin-top: 0.25em;"><div style="margin-bottom: 16px; margin-top: 16px;">
The author's overlook of Runtime environment while highlighting the language/compiler. (Found in across the whole article)</div>
</li>
</ol>
</div>
Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-16094894432662705562016-03-06T00:34:00.000-08:002016-03-08T02:49:08.951-08:00Introduce to ActFramework - an new MVC/RESTFul service framework in Java<div dir="ltr">
<h1 style="border-bottom-color: rgb(238 , 238 , 238); border-bottom-style: solid; border-bottom-width: 1px; color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 2.25em; line-height: 1.2; margin-bottom: 16px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0.3em;">
</h1>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
<span style="line-height: 25.6px;">I am happy to share my recent Open Source project ActFramework here.</span></div>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
So some events about ActFramework:</div>
<ol style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
Three years ago I was <a href="http://software-lgl.blogspot.com.au/2012/12/thinking-about-creating-new-java-web.html" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">thinking of creating an new Java MVC framework</a>.</div>
</li>
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
About one year ago I start working on <a href="https://github.com/actframework" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">ActFramework</a>.</div>
</li>
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
Three months ago I start using ActFramework to rewrite a commercial project which was written in Jersey originally, and the result is great. We have reduced the lines of code from 8900 to 4500 while keeping the same feature set and functionality.</div>
</li>
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
Last Wednesday I presented ActFramework in the <a href="http://www.meetup.com/Sydney-JVM-Community/events/228633164/" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">first Sydney JVM meetup at FinTech hub in 2016</a>.</div>
</li>
</ol>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
In this blog I will brief major features of ActFramework</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#controller" id="user-content-controller" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Controller</h3>
<div class="highlight highlight-source-java" style="font-family: 'helvetica neue', helvetica, 'segoe ui', arial, freesans, sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol'; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-radius: 3px; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span style="color: #333333;">@GetAction(</span><span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>/<span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="color: #333333;">)
</span><span class="pl-k" style="color: rgb(167 , 29 , 93); font-size: 13.6px; line-height: 1.45;">public</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> </span><span class="pl-k" style="color: rgb(167 , 29 , 93); font-size: 13.6px; line-height: 1.45;">void</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> home() {
} </span></pre>
<pre style="background-color: #f7f7f7; border-radius: 3px; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">@PostAction(</span><span class="pl-s" style="color: #333333; font-size: 13.6px; line-height: 1.45;"><span class="pl-pds" style="box-sizing: border-box;">"</span>/customer<span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">)
</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">public</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> </span><span class="pl-smi" style="box-sizing: border-box; color: #333333; font-size: 13.6px; line-height: 1.45;">String</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> createCustomer(</span><span class="pl-smi" style="box-sizing: border-box; color: #333333; font-size: 13.6px; line-height: 1.45;">Customer</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> customer) {
customerDao</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">.</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">save(customer);
</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">return</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> customer</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">.</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">getId();
} </span></pre>
<pre style="background-color: #f7f7f7; border-radius: 3px; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">@PutAction(</span><span class="pl-s" style="color: #333333; font-size: 13.6px; line-height: 1.45;"><span class="pl-pds" style="box-sizing: border-box;">"</span>/customer/{id}/email<span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">)
</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">public</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> </span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">void</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> updateCustomerEmail(</span><span class="pl-smi" style="box-sizing: border-box; color: #333333; font-size: 13.6px; line-height: 1.45;">String</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> id, </span><span class="pl-smi" style="box-sizing: border-box; color: #333333; font-size: 13.6px; line-height: 1.45;">String</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> email) {
</span><span class="pl-smi" style="box-sizing: border-box; color: #333333; font-size: 13.6px; line-height: 1.45;">Customer</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> customer </span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">=</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;"> customerDao</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">.</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">findById(id);
notFoundIfNull(customer);
customer</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">.</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">setEmail(email);
customerDao</span><span class="pl-k" style="color: #333333; font-size: 13.6px; line-height: 1.45;">.</span><span style="color: #333333; font-size: 13.6px; line-height: 1.45;">save(customer);
}</span></pre>
</div>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
See <a href="https://github.com/actframework/act-doc/blob/master/en/controller.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">the documentation</a> for more about controller and action methods</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#routing" id="user-content-routing" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Routing</h3>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
There are two ways to create routing table:</div>
<ol style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
Through <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">resources/routes</code> file</div>
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 16px; margin-top: 0px; overflow: auto; padding: 16px; word-wrap: normal;"><code style="background: transparent; border-radius: 3px; border: 0px; display: inline; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; line-height: inherit; margin: 0px; padding: 0px; word-break: normal; word-wrap: normal;">GET /customer/{id} any.pkg.CustomerController.get
POST /customer any.pkg.CustomerController.create
... </code></pre>
</li>
<li style="box-sizing: border-box;"><div style="margin-bottom: 16px; margin-top: 16px;">
Through action method annoation as shown above</div>
</li>
</ol>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
See <a href="https://github.com/actframework/act-doc/blob/master/en/routing.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">the documentation</a> for more about routing</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#model-and-dao" id="user-content-model-and-dao" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Model and DAO</h3>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
ActFramework support Morphia for MongoDB and Ebean for SQL. You can declare your Model class as a POJO with proper annotation. <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">MorphiaDao</code> and <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">EbeanDao</code> are provided to support find/save/delete entities:</div>
<div class="highlight highlight-source-java" style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;">@<span class="pl-smi" style="box-sizing: border-box;">Entity</span>
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">Customer</span> {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Id
</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">private</span> <span class="pl-smi" style="box-sizing: border-box;">ObjectId</span> id;
<span class="pl-k" style="color: rgb(167 , 29 , 93);">private</span> <span class="pl-smi" style="box-sizing: border-box;">String</span> name;
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">setId</span>(<span class="pl-smi" style="box-sizing: border-box;">ObjectId</span> <span class="pl-v" style="color: rgb(237 , 106 , 67);">id</span>) {
<span class="pl-v" style="color: rgb(237 , 106 , 67);">this</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>id <span class="pl-k" style="color: rgb(167 , 29 , 93);">=</span> id;
}
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-smi" style="box-sizing: border-box;">ObjectId</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">getId</span>() {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">return</span> <span class="pl-v" style="color: rgb(237 , 106 , 67);">this</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>id;
}
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">setName</span>(<span class="pl-smi" style="box-sizing: border-box;">String</span> <span class="pl-v" style="color: rgb(237 , 106 , 67);">name</span>) {
<span class="pl-v" style="color: rgb(237 , 106 , 67);">this</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>name <span class="pl-k" style="color: rgb(167 , 29 , 93);">=</span> name;
}
<span style="font-size: 13.6px; line-height: 1.45;">
</span><span class="pl-k" style="color: rgb(167 , 29 , 93); font-size: 13.6px; line-height: 1.45;">public</span><span style="font-size: 13.6px; line-height: 1.45;"> </span><span class="pl-smi" style="box-sizing: border-box; font-size: 13.6px; line-height: 1.45;">String</span><span style="font-size: 13.6px; line-height: 1.45;"> </span><span class="pl-en" style="color: rgb(121 , 93 , 163); font-size: 13.6px; line-height: 1.45;">getName</span><span style="font-size: 13.6px; line-height: 1.45;">() {
</span><span class="pl-k" style="color: rgb(167 , 29 , 93); font-size: 13.6px; line-height: 1.45;">return</span><span style="font-size: 13.6px; line-height: 1.45;"> </span><span class="pl-v" style="color: rgb(237 , 106 , 67); font-size: 13.6px; line-height: 1.45;">this</span><span class="pl-k" style="color: rgb(167 , 29 , 93); font-size: 13.6px; line-height: 1.45;">.</span><span style="font-size: 13.6px; line-height: 1.45;">name;
}
}</span>
</pre>
</div>
<div class="highlight highlight-source-java" style="font-family: 'helvetica neue', helvetica, 'segoe ui', arial, freesans, sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol'; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-radius: 3px; font-family: consolas, 'liberation mono', menlo, courier, monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span><span style="color: #333333;"> </span><span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span><span style="color: #333333;"> </span><span class="pl-en" style="color: rgb(121 , 93 , 163);">CustomerController</span><span style="color: #333333;"> {
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">@Inject</span><span style="color: #333333;"> </span><span class="pl-k" style="color: rgb(167 , 29 , 93);"><span style="color: #333333;">MorphiaDao<</span><span class="pl-smi" style="color: rgb(51 , 51 , 51);">Customer</span><span class="pl-smi" style="color: #007000;">></span></span><span style="color: #333333;"> dao;
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">@GetAction</span><span style="color: #333333;">(</span><span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>/customer<span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="color: #333333;">)
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span><span style="color: #333333;"> </span><span class="pl-k" style="color: rgb(167 , 29 , 93);">Iterable<<span class="pl-smi" style="color: rgb(51 , 51 , 51);">Customer</span>></span><span style="color: #333333;"> </span><span class="pl-en" style="color: rgb(121 , 93 , 163);">list</span><span style="color: #333333;">() {
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">return</span><span style="color: #333333;"> dao</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span style="color: #333333;">findAll();
}
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">@GetAction</span><span style="color: #333333;">(</span><span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>/customer/{id}<span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="color: #333333;">)
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span><span style="color: #333333;"> </span><span class="pl-smi" style="box-sizing: border-box; color: #333333;">Customer</span><span style="color: #333333;"> </span><span class="pl-en" style="color: rgb(121 , 93 , 163);">get</span><span style="color: #333333;">(</span><span class="pl-smi" style="box-sizing: border-box; color: #333333;">String</span><span style="color: #333333;"> </span><span class="pl-v" style="color: rgb(237 , 106 , 67);">id</span><span style="color: #333333;">) {
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">return</span><span style="color: #333333;"> dao</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span style="color: #333333;">findById(</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">new</span><span style="color: #333333;"> </span><span class="pl-smi" style="box-sizing: border-box; color: #333333;">ObjectId</span><span style="color: #333333;">(id));
}
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">@PostAction</span><span style="color: #333333;">(</span><span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>/customer<span class="pl-pds" style="box-sizing: border-box;">"</span></span><span style="color: #333333;">)
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span><span style="color: #333333;"> </span><span class="pl-smi" style="box-sizing: border-box; color: #333333;">String</span><span style="color: #333333;"> </span><span class="pl-en" style="color: rgb(121 , 93 , 163);">create</span><span style="color: #333333;">(</span><span class="pl-smi" style="box-sizing: border-box; color: #333333;">Customer</span><span style="color: #333333;"> </span><span class="pl-v" style="color: rgb(237 , 106 , 67);">customer</span><span style="color: #333333;">) {
dao</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span style="color: #333333;">save(customer);
</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">return</span><span style="color: #333333;"> customer</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span style="color: #333333;">getId()</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span style="color: #333333;">toString();
}
}</span></pre>
</div>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
See <a href="https://github.com/actframework/act-doc/blob/master/en/model.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">the documentation</a> on more about Model and DAO</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#jobs-and-scheduler" id="user-content-jobs-and-scheduler" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Jobs and scheduler</h3>
<div class="highlight highlight-source-java" style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">MyClass</span> {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Every</span>(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>2s<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">jobA</span>() {
<span class="pl-c1" style="color: rgb(0 , 134 , 179);">...
</span> }
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@InvokedAfter</span>(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>MyClass.jobA<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">runAfterJobA</span>() {
<span class="pl-c1" style="color: rgb(0 , 134 , 179);">...
</span> }
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@OnAppStart
</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">jobB</span>() {
<span class="pl-c1" style="color: rgb(0 , 134 , 179);">...
</span> }
<span class="pl-c1" style="color: rgb(0 , 134 , 179);">...
</span>}</pre>
</div>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
See <a href="https://github.com/actframework/act-doc/blob/master/en/jobs.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">the documentation</a> for more about jobs and scheduling</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#events" id="user-content-events" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Events</h3>
<div class="highlight highlight-source-java" style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">CustomerController</span> {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Inject
</span> <span class="pl-smi" style="box-sizing: border-box;">EbeanDao</span> dao;
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Inject
</span> <span class="pl-smi" style="box-sizing: border-box;">EventBus</span> eventBus;
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">create</span>(<span class="pl-smi" style="box-sizing: border-box;">Customer</span> <span class="pl-v" style="color: rgb(237 , 106 , 67);">customer</span>) {
dao<span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>save(customer);
eventBus<span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>trigger(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>new-customer<span class="pl-pds" style="box-sizing: border-box;">"</span></span>, customer);
}
}</pre>
</div>
<div class="highlight highlight-source-java" style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;">@<span class="pl-smi" style="box-sizing: border-box;">Mailer</span>
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">PostOffice</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">extends</span> <span class="pl-e" style="color: rgb(121 , 93 , 163);">Mailer</span>.<span class="pl-e" style="color: rgb(121 , 93 , 163);">Util</span> {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@On</span>(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>new-customer<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Async
</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">sendWelcomeLetter</span>(<span class="pl-smi" style="box-sizing: border-box;">Customer</span> <span class="pl-v" style="color: rgb(237 , 106 , 67);">customer</span>) {
to(customer<span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>getEmail());
from(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span><a href="mailto:noreply@mycom.com">noreply@mycom.com</a><span class="pl-pds" style="box-sizing: border-box;">"</span></span>);
send(customer);
}
}</pre>
</div>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
See <a href="https://github.com/actframework/act-doc/blob/master/en/event.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">the documentation</a> for more about events</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#interceptors" id="user-content-interceptors" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Interceptors</h3>
<div class="highlight highlight-source-java" style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="pl-k" style="color: rgb(167 , 29 , 93);"> public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">App</span> {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Before</span>(<span class="pl-c1" style="color: rgb(0 , 134 , 179);">except</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">=</span> <span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>login,logout<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">authenticate</span>(<span class="pl-smi" style="box-sizing: border-box;">ActionContext</span> <span class="pl-v" style="color: rgb(237 , 106 , 67);">context</span>) {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">if</span> (<span class="pl-k" style="color: rgb(167 , 29 , 93);">!</span>context<span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>session()<span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>contains(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>username<span class="pl-pds" style="box-sizing: border-box;">"</span></span>)) {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">if</span> (context<span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>isAjax()) {
<span class="pl-k" style="color: rgb(167 , 29 , 93);">throw</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">new</span> <span class="pl-smi" style="box-sizing: border-box;">UnAuthorized</span>();
} <span class="pl-k" style="color: rgb(167 , 29 , 93);">else</span> {
redirect(<span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>/login<span class="pl-pds" style="box-sizing: border-box;">"</span></span>);
}
}
}
<span class="pl-k" style="color: rgb(167 , 29 , 93);">@Action</span>(<span class="pl-c1" style="color: rgb(0 , 134 , 179);">value</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">=</span> <span class="pl-s" style="color: rgb(24 , 54 , 145);"><span class="pl-pds" style="box-sizing: border-box;">"</span>/login<span class="pl-pds" style="box-sizing: border-box;">"</span></span> <span class="pl-c1" style="color: rgb(0 , 134 , 179);">methods</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">=</span> {<span class="pl-smi" style="box-sizing: border-box;">H</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span class="pl-smi" style="box-sizing: border-box;">Method</span><span class="pl-c1" style="color: rgb(0 , 134 , 179);"><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>GET</span>, <span class="pl-smi" style="box-sizing: border-box;">H</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span><span class="pl-smi" style="box-sizing: border-box;">Method</span><span class="pl-c1" style="color: rgb(0 , 134 , 179);"><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>POST</span>})
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">void</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">login</span>() {
<span class="pl-c1" style="color: rgb(0 , 134 , 179);">...
</span> }
}</pre>
</div>
<div class="highlight highlight-source-java" style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px;">
<pre style="background-color: rgb(247 , 247 , 247); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; font-stretch: normal; line-height: 1.45; margin-bottom: 0px; margin-top: 0px; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;">@With(<span class="pl-smi" style="box-sizing: border-box;">App</span><span class="pl-k" style="color: rgb(167 , 29 , 93);">.</span>class)
<span class="pl-k" style="color: rgb(167 , 29 , 93);">public</span> <span class="pl-k" style="color: rgb(167 , 29 , 93);">class</span> <span class="pl-en" style="color: rgb(121 , 93 , 163);">CustomerController</span>() {
<span class="pl-c1" style="color: rgb(0 , 134 , 179);">...
</span>}</pre>
</div>
<div style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px;">
See <a href="https://github.com/actframework/act-doc/blob/master/en/interceptor.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">the documentation</a> for more about interceptors</div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#more-features" id="user-content-more-features" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>More features</h3>
<ol style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/act-doc/blob/master/en/email.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Sending Email</a></li>
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/act-doc/blob/master/en/cli.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Creating CLI commands</a></li>
</ol>
<h2 style="border-bottom-color: rgb(238 , 238 , 238); border-bottom-style: solid; border-bottom-width: 1px; color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.75em; line-height: 1.225; margin-bottom: 16px; margin-top: 1em; padding-bottom: 0.3em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#comparing-to-playframework-v1x" id="user-content-comparing-to-playframework-v1x" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1; padding-right: 2px; text-decoration: none;"></a>Comparing to PlayFramework v1.x</h2>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#project-layout" id="user-content-project-layout" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Project layout</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play use <a href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">specific project layout</a></li>
<li style="box-sizing: border-box;">Act use standard maven project layout. See <a href="https://github.com/actframework/act-doc/blob/master/en/get_start.md#anatomy" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">The anatomy of an Act application</a></li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#controller-and-action-methods" id="user-content-controller-and-action-methods" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Controller and action methods</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><a href="https://www.playframework.com/documentation/1.4.x/controllers" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Play controller</a> must extends <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">play.mvc.Controller</code>. Action method must be <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">void</code> and <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">static</code></li>
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/act-doc/blob/master/en/controller.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Act controller</a> does not need to extend any class. However extending <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">act.controller.Controller.Util</code> makes it easy to use <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">renderXxx</code> methods. Act action method does not need to be <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">static</code>. Act action method can return object</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#routing-1" id="user-content-routing-1" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Routing</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play use <a href="https://www.playframework.com/documentation/1.4.x/routes" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">routes</a> file to define routing entry</li>
<li style="box-sizing: border-box;">Act use <a href="https://github.com/actframework/act-doc/blob/master/en/routing.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">routes</a> file plus <a href="https://github.com/actframework/act-doc/blob/master/en/routing.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">method annotation</a> to define routing entry</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#templates" id="user-content-templates" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Templates</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play use <a href="https://www.playframework.com/documentation/1.4.x/templates" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">groovy</a> as default template engine</li>
<li style="box-sizing: border-box;">Act use <a href="https://github.com/actframework/act-doc/blob/master/en/templating.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Rythm</a> as default template engine</li>
<li style="box-sizing: border-box;">Both framework support plugin different template engine</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#models-and-dao" id="user-content-models-and-dao" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Models and DAO</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play's DAO methods are built into <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">play.db.Model</code>. Sub class get the data access capablitity via byte code enhancement</li>
<li style="box-sizing: border-box;">Act framework does not require Model class to extend any class. ActFramework inject default DAO implemenation to host class (e.g. a Controller, or Mailer) to provide DAO capablity</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#sql-database-access" id="user-content-sql-database-access" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>SQL Database access</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play use <a href="https://www.playframework.com/documentation/1.4.x/jpa" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">JPA/Hibernate</a> to achieve SQL database access</li>
<li style="box-sizing: border-box;">Act use <a href="https://github.com/actframework/act-doc/blob/master/en/ebean.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Ebean</a> to achieve SQL database access</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#mongodb-access" id="user-content-mongodb-access" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>MongoDB access</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play use <a href="https://www.playframework.com/modules/morphia" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">PlayMoprhia</a> plugin (created by author of ActFramework) to access mongodb</li>
<li style="box-sizing: border-box;">Act use <a href="https://github.com/actframework/act-doc/blob/master/en/morphia.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Morphia plugin</a> to access mongodb</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#jobs" id="user-content-jobs" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Jobs</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><a href="https://www.playframework.com/documentation/1.4.x/jobs" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Play job</a> must be put into a class that extends <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">play.jobs.Job</code>. Each class implement one job logic</li>
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/act-doc/blob/master/en/jobs.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Act job</a> is just a <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">public void</code> method without parameters. The class hosting job method does not require to extend any class</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#events-1" id="user-content-events-1" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Events</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play does not provide event mechanism</li>
<li style="box-sizing: border-box;">Act provide <a href="https://github.com/actframework/act-doc/blob/master/en/event.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">very expressive and easy to use event binding and dispatching mechanism</a></li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#asynchronous-http-request-handling" id="user-content-asynchronous-http-request-handling" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Asynchronous http request handling</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play can <a href="https://www.playframework.com/documentation/1.4.x/asynchronous" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">suspend http request handling and resume when async operation ended</a></li>
<li style="box-sizing: border-box;">Act does not provide async http request handling at the moment (v0.1.1-SNAPSHOT)</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#i18n" id="user-content-i18n" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>i18n</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides an <a href="https://www.playframework.com/documentation/1.4.x/i18n" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">easy to use i18n support</a></li>
<li style="box-sizing: border-box;">Act support i18n through Rythm's <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">i18n()</code> extension. Act's i18n support needs to be refined and improved</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#cache" id="user-content-cache" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Cache</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">Cache</code> utility class with static method. See document[<a href="https://www.playframework.com/documentation/1.4.x/cache" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">https://www.playframework.com/documentation/1.4.x/cache</a>]</li>
<li style="box-sizing: border-box;">Rythm use <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">org.osgl.cache.CacheService</code> to provide cache utilities</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#sending-email" id="user-content-sending-email" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Sending email</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides <a href="https://www.playframework.com/documentation/1.4.x/emails" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">a controller style mailer utility</a></li>
<li style="box-sizing: border-box;">Act also provides a <a href="https://github.com/actframework/act-doc/blob/master/en/email.md" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">very easy to use mailing solution</a></li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#testing" id="user-content-testing" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Testing</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides a very <a href="https://www.playframework.com/documentation/1.4.x/test" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">descent testing facilities</a></li>
<li style="box-sizing: border-box;">Act relies on standard junit to implement application testing. Act also provides a specific <a href="https://github.com/actframework/act-test" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">act-test</a> to support application's Model test. At the moment Morphia support is provided.</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#security" id="user-content-security" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Security</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides limited <a href="https://www.playframework.com/documentation/1.4.x/security" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">security</a> support. However there are some third party plugins like <a href="https://www.playframework.com/modules/deadbolt" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">Deadbolt</a> and <a href="https://github.com/greenlaw110/play-aaa" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">play-aaa</a> (created by author of ActFramework)</li>
<li style="box-sizing: border-box;">Act provides authentication/role based authorization/accounting via <a href="https://github.com/actframework/act-aaa-plugin" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">act-aaa</a></li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#modules-and-depedencies" id="user-content-modules-and-depedencies" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Modules and depedencies</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play applied it's <a href="https://www.playframework.com/documentation/1.4.x/modules" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">specific way</a> to manage modules and dependencies</li>
<li style="box-sizing: border-box;">Act relies on maven to manage dependencies and modules</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#database-evolutions" id="user-content-database-evolutions" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Database evolutions</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides <a href="https://www.playframework.com/documentation/1.4.x/evolutions" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">database evolution</a> support</li>
<li style="box-sizing: border-box;">Act does not provide specific support on database evolution.</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#logging" id="user-content-logging" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>logging</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 16px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play provides a <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">Logger</code> class with static logging method. See <a href="https://www.playframework.com/documentation/1.4.x/logs" style="background-color: transparent; color: rgb(64 , 120 , 192); text-decoration: none;">document</a></li>
<li style="box-sizing: border-box;">Act does not have any specific class for logging. Developer could use any Logging solution (e.g. Log4J) in their application. However developer are also free to use <code style="background-color: rgba(0 , 0 , 0 , 0.0392157); border-radius: 3px; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 13.6px; margin: 0px; padding: 0.2em 0px;">App.logger</code> to create log items.</li>
</ul>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
<a class="anchor" href="https://gist.github.com/greenlaw110/f2900b42b2d995a3986a#deployment" id="user-content-deployment" style="background-color: transparent; color: rgb(64 , 120 , 192); display: inline-block; line-height: 1.2; padding-right: 2px; text-decoration: none;"></a>Deployment</h3>
<ul style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 16px; line-height: 25.6px; margin-bottom: 0px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;">Play can be deployed as a fullstack application or as a war file in JEE application servers</li>
<li style="box-sizing: border-box;">Act support only fullstack application deployment at the moment (0.1.1-SNAPSHOT)</li>
</ul>
<div>
<span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol";"><span style="line-height: 25.6px;"><br /></span></span></div>
<div>
<h3 style="color: rgb(51 , 51 , 51); font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 1.5em; line-height: 1.43; margin-bottom: 16px; margin-top: 1em;">
Resources</h3>
</div>
<div>
<ul style="color: #333333; font-family: 'helvetica neue', helvetica, 'segoe ui', arial, freesans, sans-serif, 'apple color emoji', 'segoe ui emoji', 'segoe ui symbol'; font-size: 16px; line-height: 25.6px; margin-bottom: 0px; margin-top: 0px; padding: 0px 0px 0px 2em;">
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/actframework" target="_blank">ActFramework Github Project</a></li>
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/act-doc" target="_blank">ActFramework Documentation</a></li>
<li style="box-sizing: border-box;"><a href="https://github.com/actframework/act-doc/blob/master/en/get_start.md" target="_blank">Getting start with ActFramework</a></li>
<li style="box-sizing: border-box;"><a href="https://github.com/greenlaw110/sydney_jvm_meetup_s04e01" target="_blank">The Act sample application created on Sydney JVM Meetup</a></li>
</ul>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-16392460394336908262012-12-06T15:29:00.002-08:002012-12-06T15:29:38.867-08:00Thinking about creating an new Java Web frameworkWhy: I love playframework v1 but not v2. However play team moves their attention away from v1.<br />
<br />
What should be kept from v1:<br />
<br />
<ul>
<li>Bytecode enhancement. This is a great stuff that enable framework and plugin developer to inject logic into Application code</li>
<li>A full stack framework. This should like Play which runs on itself instead of inside a servlet container</li>
<li>Support plugins. Though API might changed</li>
<li>Handy utility libraries for application developer, like IO, Codec, Images etc.</li>
<li>Built in simple Secure framework</li>
<li>The DB layer enable plugin different implementations, JPA, EBean, Morphia etc.</li>
<li>Built in validation</li>
<li>Easy to use asynchronous handling API, like Promise and Controller.await</li>
<li>Before, After, Final, Catch intecepters to plugin logic into request handling chain</li>
<li>Render with different template based on request.format</li>
<li>JavaExtension to template</li>
<li>And most important is Simple, Simple and Simple to application developers</li>
</ul>
<br />
What needs to be improved or changed:<br />
<ul>
<li>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</li>
<li>Action invocation mechanism. Reduce the use of reflection, static methods and Exception. But needs to keep the API still simple though</li>
<li>Plugin API. Support partitioned plugin API set instead of all-in-one big facade</li>
<li>Replace python stuff with pure script plus Java</li>
<li>CRUD</li>
<li>Replace default Groovy template engine with Rythm</li>
<li>Replace default JPA with Ebean ???</li>
<li>JSON support</li>
</ul>
<div>
<br />
Proposed Controller API:</div>
<div>
<br /></div>
<pre class="brush: java">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<Order> orders = ...
return new RenderPDF(orders);
}
}
</pre>
<br />
Sample route file:<br />
<br />
<pre class="brush: java">
GET /orders/{orderId} Orders.show
POST /orders/{orderId} Orders.saveUpdate
GET /orderReport Orders.report
</pre>
<br/>
What do you think?Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com21tag:blogger.com,1999:blog-2560373426889485631.post-28679432358946975112012-08-17T19:37:00.000-07:002012-08-17T19:37:23.452-07:00ToString Mode and Auto ToString Mode of Rythm template engine<p>In a <a href="http://software-lgl.blogspot.com.au/2012/06/rythm-now-has-sim-string-interpolation.html">recent blog</a> I've introduced <a href="http://www.playframework.org/modules/rythm-1.0.0-20120815a/string_interpolation">SIM (String Interpolation Mode)</a> of Rythm. This blog introduces another two new feature named <a href="http://www.playframework.org/modules/rythm-1.0.0-20120815a/to_string">TSM (ToString Mode)</a> and <a href="http://www.playframework.org/modules/rythm-1.0.0-20120815a/auto_to_string">ATSM (Auto ToString Mode)</a> of Rythm</p>
<h3>ToString Mode</h3>
<p>This feature allows developers to create <code>String toString()</code> method for their class easily:</p>
<pre class="brush: java">
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);
}
}
</pre>
<p>As a comparison, previously you need to write <code>toString()</code> method in the following way:</p>
<pre class="brush: java">
@Override public String toString() {
return Rythm.render("@args Address _;@_.unitNo @_.streetNo @_.street, @_.suburb, @_.state, @_.postCode", this);
}
</pre>
<p>So here are several facts about TSM:</p>
<ol>
<li>the sign "_" is used to refer to <code>this</code> object instance in the template</li>
<li>You don't need to declare "_" use <code>@args</code> statement in TSM</li>
<li>You must use <code>Rythm.toString()</code> interface instead of the normal <code>Rythm.render()</code> in order to use TSM</li>
</ol>
<h3>Auto ToString Mode</h3>
<p>If TSM makes writting <code>toString()</code> easy, ATSM makes it even easier because you don't need to write the template:</p>
<pre class="brush: java">
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);
}
}</pre>
<p>And you can pass in parameters to configure the style and output fields:</p>
<pre class="brush:java">
@Override public String toString() {
return Rythm.toString(this,
com.greenlaw110.rythm.toString.ToStringOption.defaultOption.setAppendTransient(true),
com.greenlaw110.rythm.toString.ToStringStyle.MULTI_LINE_STYLE);
}
</pre>
<p>The above code indicate that output <code>transient</code> fields which is not output by default. It also indicate that output should be in multiple lines. Refer to <a href="http://www.playframework.org/modules/rythm-1.0.0-20120815a/auto_to_string">here</a> for more details out the option and styling configuration.</p>
<p>You can use the following annotation to mark the fields that you don't want to output with Rythm's ATSM:</p>
<ul>
<li><code>com.greenlaw110.rythm.toString.NoExpose</code></li>
<li><code>org.codehaus.jackson.annotate.JsonIgnore</code></li>
</ul>
<h4>Compare to Apache Commons Lang's StringBuilder</h4>
<p>Like ATSM, <code>org.apache.commons.lang3.builder.ReflectionToStringBuilder</code> also allows to generate <code>toString()</code> output automatically. ATSM is slightly (around 20%) faster than <code>ReflectionToStringBuilder</code>. As a comparison, <code>TSM</code> is 2 times faster than it.</p>
<p>
<b>Foot notes:</b> Rythm Template Engine is a static typed Java template engine using Razor like syntax. There is a <a href="http://play-rythm-demo.appspot.com/">full feature set demo hosted on GAE</a>. The source code is hosted on <a href="https://github.com/greenlaw110/rythm">github</a>
</p>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com1tag:blogger.com,1999:blog-2560373426889485631.post-30707441791479915122012-06-30T16:17:00.001-07:002012-06-30T16:35:00.096-07:00Rythm 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 <code>String.format()</code>.
<pre class="brush: java">
String result = Rythm.render("Hello @who!", "Rythm");
</pre>
As a comparison, previously you need the following code:
<pre class="brush: java">
String result = Rythm.render("@args String who;Hello @who!", "Rythm");
</pre>
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 <code>java.lang.Object</code> type, and save your typing. Looks not a big deal, but it literally make <code>Rythm.render()</code> an replacement of <code>String.format()</code> for most cases. You get two benefit from Rythm SIM over String format:
<ol>
<li>performance: <code>Rythm.render</code> is 2 times faster than <code>String.format</code> except the first call</li>
<li>You can pass in arguments not only by position, but also by name
<pre class="brush: java">
Map<String, Object> args = new HashMap<String, Object>();
args.put("who", "world");
String result = Rythm.render("Hello @who!", args);
</pre>
</li>
</ol>
<h2>SIM Limitation</h2>
So as mentioned above SIM only applies to simple templates. The question is <b>what defines a simple template</b>?
<ul>
<li>
<p>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</p>
<pre class="brush:java">
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
</pre>
</li>
<li>
<p>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:</p>
<ol>
<li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#args">@args</a>, declare template argument variables</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#extends">@extends</a>, extends a layout template</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#section">@section</a>, define a template part to be inserted in the layout template</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#render">@render</a>, used in layout template to render a template section defined in sub template</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#doLayout">@doLayout</a>, same as <code>@render</code></li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#doBody">@doBody</a>, call back tag body</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#include">@include</a>, include another template content in place</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#set">@set</a>, set template variable to be fetched by layout template</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#get">@get</a>, get the template variable set in the sub template</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#expand">@expand</a>, execute/expand an macro</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#exec">@exec</a>, same as <code><code>expand</code></code></li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#macro">@macro</a>, define an macro</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#def">@def</a>, define an inline tag</li><li><a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#tag">@tag</a>, same as <code>@def</code></li><li>All extended keywords including the following defined in PlayRythm plugin<ol><li> <a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#url">@url</a>, reverse url lookup</li><li> <a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#fullUrl">@fullUrl</a>, absolute reverse url lookup</li><li> <a href="http://www.playframework.org/modules/rythm-1.0.0-20120630/reference#msg">@msg</a>, message lookup</li></ol></li></ol>
</li>
</ul>
<h2>How to render with SIM</h2>
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.
<p>
<b>Foot notes:</b> Rythm Template Engine is a static typed Java template engine using Razor like syntax. There is a <a href="http://play-rythm-demo.appspot.com/">full feature set demo hosted on GAE</a>. The source code is hosted on <a href="https://github.com/greenlaw110/rythm">github</a>
</p>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-56242262527063276042012-05-24T19:13:00.000-07:002012-05-24T19:13:16.468-07:00Step by step migrate your Groovy template to Rythm template - Part TwoIn the <a href="http://software-lgl.blogspot.com.au/2012/05/step-by-step-migrate-your-groovy.html">Step by step migrate your Groovy template to Rythm - Part One</a> 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.
<br/>
<br />
Groovy use <a href="http://www.playframework.org/documentation/1.2.4/tags#extends"><code>#{extends}</code></a> tag to specify the layout template you want to apply to the current template. On the layout template side, you can use <a href="http://www.playframework.org/documentation/1.2.4/tags#dolayout"><code>#{doLayout}</code></a> tag to load the content from sub template. Here is the typical scenario you met on Groovy template:
<br/>
<br/>
1. views/Application/index.html:
<pre class="brush:html">#{extends "main.html"/}
<h1>Home</h1>
...</pre>
<br/>
2. views/main.html:
<pre class="brush:html"><!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
<div id="content">
#{doLayout/}
</div>
...
</body>
</html></pre>
<br/>
Rythm use pretty much the same thing (<a href="http://www.playframework.org/modules/rythm-1.0.0-RC5/reference#extends"><code>@extends</code></a> and <a href="http://www.playframework.org/modules/rythm-1.0.0-RC5/reference#doLayout"><code>@doLayout</code></a> tag). Here is what they look like in Rythm:
<br/>
<br/>
1. rythm/Application/index.html:
<pre class="brush:html">@extends(main)
<h1>Home</h1>
...</pre>
<br/>
2. rythm/main.html:
<pre class="brush:html"><!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
<div id="content">
@doLayout()
</div>
...
</body>
</html></pre>
<br/>
Pretty simple, isn't it? One place worth attention. I use <code>@extends(main)</code> instead of <code>@extends("main.html")</code>. Actually I could use the latter notation, but it is redundant:
<ul>
<li>template inheritance is static, which happen at parsing time, so the quotation mark is redundant</li>
<li>template file extension is deduct using the current template format, thus ".html" is redundant</li>
</ul>
In addition, suppose your layout template are not put into the view root, e.g. you have a layout template file <code>app/views/themes/blueSky/main.html</code>, to reference it in extends tag you do it this way in groovy:
<pre class="brush:html">#{extends "themes/blueSky/main.html"/}</pre>
In Rythm you can copy the groovy notation:
<pre class="brush:html">@extends("themes/blueSky/main.html")</pre>
But I recommend you to use the simple Java package notation:
<pre class="brush:html">@extends(themes.blueSky.main)</pre>
Note, you are free to use <b>relative path</b> and <b>import path</b> shortcuts when you reference the layout template in extends tag, click <a target="_blank" href="http://www.playframework.org/modules/rythm-1.0.0-RC5/user_guide#call_tag_relative_path">here</a> to understand relative and import path shortcut.
<br/>
<br/>
In addition, <b><code>@render()</code></b> is an alias of <b><code>@doLayout()</code></b>. They are two identical tags, and it's up to you to decide which one fit your taste.
<br/>
<br/>
Now let's see something interesting.
<br/>
<br/>
<h4>Passing parameter to layout template</h4>
<br/>
So you can pass parameter from content template to layout template via the <a href="http://www.playframework.org/documentation/1.2.4/tags#set"><code>#set</code></a> and <a href="http://www.playframework.org/documentation/1.2.4/tags#get"><code>#get</code></a>. Let's say you have a layout template main.html:
<pre class="brush:html">...
<div class="#get{'theme'/}">
#{doLayout/}
</div></pre>
And in your content template, say index.html:
<pre class="brush:html">#{extends "main.html"/}
...
#{set theme:"blueSky"/}
...</pre>
You can basically follow the same pattern in Rythm. Here is the main.html:
<pre class="brush:html">...
<div class='@get("theme")'>
@doLayout()
</div></pre>
And the content template:
<pre class="brush:html">@extends(main)
...
@set(theme:"blueSky")
...</pre>
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:
<pre class="brush:html">@args String theme
...
<div class="@theme">
@doLayout()
</div></pre>
And the content template changed accordingly:
<pre class="brush:html">@extends(main, "blueSky")
...</pre>
It's more clean and simple than the clumsy <code>@set</code> and <code>@get</code>, isn't it?
<br/>
<br/>
<h4>Render sections</h4>
<br/>
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:
<pre class="brush:html">...
<div id="sidebar">#{get "sidebar"/}</div>
<div id="main">#{doLayout/}</div>
<div id="footer">#{get "footer"/}</div>
...</pre>
And the content template:
<pre class="brush:html">#{extends "main.html/}
...
#{set "sidebar"}
<ul>
<li>menu-1</li>
...
</ul>
#{/set}
...
#{set "footer"}
copyright ...
#{/set}
</pre>
Now let's see how Rythm handle it. First, main.html:
<pre class="brush:html">...
<div id="sidebar">@render("sidebar")</div>
<div id="main">@render()</div> @// as we said before @render() is an alias of @doLayout()
<div id="footer">@render("footer")</div>
...</pre>
And the content template in rythm version:
<pre class="brush:html">@extends(main)
...
@section("sidebar") {
<ul>
<li>menu-1</li>
...
</ul>
}
...
@section("footer") {
copyright ...
}
...</pre>
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:
<pre class="brush:html">...
<div id="sidebar">@render("sidebar")</div>
<div id="main">@render()</div> @// as we said before @render() is an alias of @doLayout()
<div id="footer">
@render("footer"){
copyright ... @// default content for footer section
}
</div>
...</pre>
Now you can omit the footer section from your content template, Rythm will pick up default content automatically!
<br/>
<br/>
In this article we introduced the differences and similarity between Groovy and Rythm on template layout management. We see how Rythm use <code>@extends</code> and <code>@doLayout</code> or <code>@render</code> 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!
<br/>
<br/>
See also: <a href="http://software-lgl.blogspot.com.au/2012/05/step-by-step-migrate-your-groovy.html">Step by step migrate your Groovy template to Rythm template - Part One</a>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com1tag:blogger.com,1999:blog-2560373426889485631.post-75769055783515627802012-05-21T04:48:00.002-07:002012-05-24T19:15:11.640-07:00Step by step migrate your Groovy template to Rythm template - Part One<b>The content of this blog applies to PlayFramework 1.2.x</b>
<br/>
<br/>
I've just release <a href="http://www.playframework.org/modules/rythm-1.0.0-RC4/history">Rythm-1.0RC4</a> with new features including precompile support, <a href="http://www.playframework.org/modules/rythm-1.0.0-RC4/user_guide#nullable_expression">null-safe expression</a> and <a href="http://www.playframework.org/modules/rythm-1.0.0-RC4/user_guide#properties_enhancement">template class properties enhancement</a>, 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.<br />
<br />
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.<br />
<br />
To start using Rythm you need to add the following statement into your <code>conf/dependencies.yml</code> file:<br />
<br />
<pre class="brush: yaml"> - play -> rythm 1.0.0-RC4 # 1.0.0-RC4 is the current version but you might change it accordingly</pre>
<br />
And then you go back to your console and type<br />
<br />
<pre class="brush: bash">play deps --sync
mkdir app/rythm</pre>
<br />
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 <code>app/views</code> folder:<br />
<br />
<b>step1</b>. copy the file to corresponding folder under <code>app/rythm</code>, e.g.<br />
<pre class="brush:bash">app/views/main.html -> app/rythm/main.html
app/views/Application/index.html -> app/rythm/Application/index.html</pre>
<br />
<b>step2</b>. update the file with Rythm syntax. (No worries, we will come back to this point very soon, I promise!)<br />
<br />
<b>step3</b>. Type <code>play run</code> 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.<br />
<br />
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.<br />
<br />
Now let's take our magnifier to inspect what is happening in step 2: update the groovy file with Rythm syntax.<br />
<br />
<h3>
1. Expression</h3>
<br />
In your groovy template, expressions are enclosed by "<code>${}</code>", E,g.
<br />
<pre class="brush: html">Hello ${who}</pre>
<br />
Rythm use "<code>@</code>" sign to mark an expression:
<br />
<pre class="brush: html">Hello @who</pre>
<br />
Smart guy will ask how to write the following expression in Rythm:
<br />
<pre class="brush: html">Jack is a ${vice}maniac.</pre>
<br />
Ok, here is how it looks like in Rythm:
<br />
<pre class="brush: html">Jack is a @(vice)maniac.</pre>
<br />
And similar for compound expressions:
<br />
<pre class="brush: html">@(foo.bar().numbers[5] + 16)</pre>
<br />
<b>Note</b>, to output the "@" sign, just put two "@" together:
<pre class="brush: html"><a href="mailto:john@@email.com">John</a></pre>
<br/>
<h4>
1.1 Null-Safe Expression</h4>
<br />
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:
<pre class="brush: html"><input type="text" name="firstName" value="${user?.firstName}"></pre>
You don't need to say good-bye to null-safe expression, as Rythm brings you the same thing:
<pre class="brush: html"><input type="text" name="firstName" value="@user?.firstName"></pre>
<br/>
<h4>1.2 Expression escape</h4>
<br/>
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: <code>${escape(expr)}</code>.
<br/>
<br/>
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 <code>.raw()</code> extension to stop auto-escape:
<pre class="brush: html"><div class="html-content">@html.raw()</div></pre>
<br/>
If you want to output raw data for all expression in a segment of your template file, use <code>@raw(){...}</code> tag:
<pre class="brush: html">@raw() {
None of the expression outputs will be escaped
including the @foo and @bar
}</pre>
<br/>
<h3>2. Control flow</h3>
<br/>
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.
<br/>
<br/>
<h4>2.1 if condition</h4>
<br/>
Groovy template:
<pre class="brush:html">#{if user.countryCode == 'en' }
Connected user is ${user}
#{/if}</pre>
<br/>
Rythm template:
<pre class="brush:html">@if ("en".equals(user.countryCode)) {
Connected user is @user
}</pre>
<br/>
<h4>2.2 if-else</h4>
<br/>
Groovy:
<pre class="brush:html">#{if user}
Connected user is ${user}
#{/if}
#{else}
Please log in
#{/else}</pre>
<br/>
Rythm:
<pre class="brush:html">@if(null != user) {
Connected user is @user
} else {
Please log in
}</pre>
<br/>
<h4>2.3 if-else-if</h4>
<br/>
Groovy:
<pre class="brush:html">#{if tasks.size() > 1}
Busy tasklist
#{/if}
#{elseif tasks}
One task on the list
#{/elseif}
#{else}
Nothing to do
#{/else}</pre>
<br/>
Rythm:
<pre class="brush:html">@if(tasks.size() > 1) {
Busy tasklist
} else if (tasks.size() > 0) {
One task on the list
} else{
Nothing to do
}</pre>
<br/>
<h4>2.4 loop</h4>
<br/>
Groovy:
<pre class="brush:html"><ul>
#{list items:products, as:'product'}
<li>${product}</li>
#{/list}
</ul></pre>
Rythm:
<pre class="brush:html"><ul>
@for(Product product:products) {
<li>@product</li>
}
</ul></pre>
<br/>
All Groovy loop variables are also available in Rythm loop. For the case of the loop above, they are:
<ul>
<li><code>@product_index</code>, the item’s index, starting at 1</li>
<li><code>@product_isLast</code>, true for the last element</li>
<li><code>@product_isFirst</code>, true for the first element</li>
<li><code>@product_parity</code>, alternates between <code>odd</code> and <code>even</code>
</ul>
<br/>
In addition, Rythm provides one additional loop variable to make the parity identification be more convenient:
<ul>
<li><code>@product_isOdd</code>, true for the odd order element</li>
</ul>
<br/>And to use those variables in your loop:
<pre class="brush:html"><ul>
@for(Product product:products) {
<span class="@product_parity">@product_index. @product</span>
@(product_isLast ? "" : "-")
}
</ul></pre>
<br/>
<h3>3. Scripting and Comment</h3>
<br/>
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.
<br/>
<br/>
<h4>3.1 Comment</h4>
<br/>
Groovy:
<pre class="brush:html">*{
this is a block comment in Groovy template engine
}*
*{this is a line comment in Groovy template engine}*</pre>
<br/>
Rythm:
<pre class="brush:html">@*
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</pre>
<br/>
<h4>3.2 Scripting</h4>
<br/>
Groovy use <code>%{...}%</code> and Groovy language to add dynamic logic into template:
<pre class="brush:html">%{
fullName = client.name.toUpperCase()+' '+client.forname;
}%
<h1>Client ${fullName}</h1></pre>
<br/>
Rythm use <code>@{...}</code> and Java language to do the same work:
<pre class="brush:html">@{
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())
****************************************************************@
<h1>Client @fullName</h1></pre>
<br/>
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.
<br/><br/>
In the <a href="http://software-lgl.blogspot.com.au/2012/05/step-by-step-migrate-your-groovy_24.html">next part</a> I will introduce page layout management with <code>@extend</code> keyword, again it achieves all you have in Groovy and more. Stay tuned!Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com7tag:blogger.com,1999:blog-2560373426889485631.post-77514557945433507612012-04-29T18:26:00.000-07:002012-04-29T18:26:12.889-07:00PlayRythm 1.0.0-RC1 releasedJust released this new big version to Play's <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/home">module repository</a>. There are lots of improvements in terms of both functionality and documentation, several bug fixes and a few break changes:<br />
<br />
<h3 id="breakchanges" style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #333333; font-family: 'Helvetica Nueue', sans-serif; font-size: 18px; line-height: 1.25; margin-bottom: 9px; margin-left: 0px; margin-right: 0px; margin-top: 1.3em; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
break changes</h3>
<ul style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #555555; font-family: 'Helvetica Nueue', sans-serif; font-size: 15px; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#renderBody" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@renderBody()</code></a> does not render layout content now. It’s used to <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#callback_tag_body" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">render tag body</a> specifically. To render the layout content, use <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#render" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@doLayout()</code></a> or <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#render" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@render()</code></a> without section name parameter</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">Automatic escape expression with html format if the template file name suffix is .html. If your code breaks, try to use <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#raw" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@raw()</code></a> tag to surround relevant template part or export your variable with<code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">.raw()</code> extension.<ul style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 20px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">Note <b style="line-height: inherit;">auto-escape can cause template execution performance up to 3 times slower</b>(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 <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">raw</code> block:<code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@raw(){your content comes here}</code>.</li>
</ul>
</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">app/view</code> as template root are no longer supported. All rythm template files must be put into<code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">app/rythm</code> folder</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">app/view/tags/rythm</code> as tag root are no longer supported. Just put tag files as normal template file into <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">app/rythm</code> folder</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#section" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@section</code></a> tag usage:<ul style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 20px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">previously <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@section sectionName {...}</code></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">now <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@section(“sectionName”) {...}</code></li>
</ul>
</li>
</ul>
<h3 id="Newfeatures" style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #333333; font-family: 'Helvetica Nueue', sans-serif; font-size: 18px; line-height: 1.25; margin-bottom: 9px; margin-left: 0px; margin-right: 0px; margin-top: 1.3em; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
New features</h3>
<ul style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #555555; font-family: 'Helvetica Nueue', sans-serif; font-size: 15px; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#tag_invoke_decoration" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Tag invocation decorations</a> and <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#chain_tag_invocation_decoration" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">chain</a> them together<ul style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 20px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#tag_invocation_cache" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Cache tag invocation result</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#invoke_action_cache" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Cache controller action invocation result</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#call_tag_relative_path" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Invoke tag/action call using relative path and import path</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#tag_invocation_callback" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Specify body callback parameter spec</a></li>
</ul>
</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#template_content_decoration" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Template content decorations</a> and <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#chain" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">chain</a> them together<ul style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 20px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#raw" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Mark a template block to output raw expression</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#escape" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Mark a template block to escape expression using specific type</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#assign" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">assign a block of template content into a variable</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#cache" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">cache a template block</a></li>
</ul>
</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#dynamic_tag_invocation" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Dynamic tag invocation with @invoke keyword</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#renderBody_with_params" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Call tag body with parameter</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#include" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Include other template inline</a>. And now you can <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#reuse_inline_tag" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">reuse inline tag definitions across multiple views</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#extends" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@extends()</code></a> directive now has <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/user_guide#extended_template_path" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">new syntax</a> to specify layout(parent) template</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#return" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Abort current template executing process and return to caller using <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@return</code></a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#break" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Break the current loop using <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@break</code></a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#continue" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Continue the current loop using <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@continue</code></a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">New <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/integration#cache4" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Cache4</code></a> annotation to mark on controller action method</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@ts()</code> output timestamp in place</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@__simple__</code> mark the current template as simple template with no implicit variables/imports and does not extend other template</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">An new demo application with 25 sample cases, with each one has template source and generated java source presented for quick study the Rythm engine</li>
</ul>
<h3 id="Smallenhancements" style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #333333; font-family: 'Helvetica Nueue', sans-serif; font-size: 18px; line-height: 1.25; margin-bottom: 9px; margin-left: 0px; margin-right: 0px; margin-top: 1.3em; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
Small enhancements</h3>
<ul style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #555555; font-family: 'Helvetica Nueue', sans-serif; font-size: 15px; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@verbatim(){}</code> now escape html code</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@render[Section]()</code> now accept <a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#default_section_content" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">default content/section block</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="http://www.playframework.org/modules/rythm-1.0.0-RC1/reference#for_second_form" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Support <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@for(int i = 0; i < 100; ++i)</code> loop style</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;">New alias for Play specific keywords:<ul style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 20px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@url</code>: previously <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@_u</code>, url reverse lookup</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@fullUrl</code>: previously <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@_au</code>, url reverse lookup with absolute path</li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@msg</code>: previously <code style="background-attachment: initial; background-clip: initial; background-color: #fafafa; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-left-radius: 3px; border-top-right-radius: 3px; border-top-style: solid; border-top-width: 1px; color: #666666; font-family: inconsolata, monospace; font-style: inherit; height: 4px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@_m</code>, i18n message lookup</li>
</ul>
</li>
</ul>
<h3 id="Issuesclosed" style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #333333; font-family: 'Helvetica Nueue', sans-serif; font-size: 18px; line-height: 1.25; margin-bottom: 9px; margin-left: 0px; margin-right: 0px; margin-top: 1.3em; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
Issues closed</h3>
<ul style="background-color: white; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #555555; font-family: 'Helvetica Nueue', sans-serif; font-size: 15px; list-style-image: initial; list-style-position: initial; list-style-type: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="https://github.com/greenlaw110/Rythm/issues/6" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">https://github.com/greenlaw110/Rythm/issues/6</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="https://github.com/greenlaw110/Rythm/issues/21" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">https://github.com/greenlaw110/Rythm/issues/21</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="https://github.com/greenlaw110/Rythm/issues/14" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">https://github.com/greenlaw110/Rythm/issues/14</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="https://github.com/greenlaw110/play-rythm/issues/5" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">https://github.com/greenlaw110/play-rythm/issues/5</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="https://github.com/greenlaw110/play-rythm/issues/1" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">https://github.com/greenlaw110/play-rythm/issues/1</a></li>
<li style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 4px; padding-left: 14px; padding-right: 0px; padding-top: 4px; position: relative;"><a href="https://github.com/greenlaw110/play-rythm/pull/11" style="border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #69af04; font-family: inherit; font-style: inherit; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: initial; outline-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">https://github.com/greenlaw110/play-rythm/pull/11</a></li>
</ul>
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-89452849853489002762012-04-04T22:22:00.001-07:002012-04-04T22:22:56.043-07:00Smooth your font in your Java IDEI have just installed <a href="http://code.google.com/p/gdipp/">gdipp</a> which makes your windows font rendered like MacOS and it looks really awesome. However I found a tiny problem is the equal symbol "=" is rendered as the minus symbol "-" in my Intellij IDEA, and someone using Netbeans also reported the same <a href="http://code.google.com/p/gdipp/issues/detail?id=69">issue</a>.
So here is the solution based on the issue discussion thread. Add the following section in your gdipp_setting.xml file:
<pre>
<process name="idea.*">
<renderer>20</renderer>
</process>
</pre>
So the code means using <code>GetGlyphOutline</code> to render font in process named "idea.*", specifically my IntelliJ IDEA process. Now everything is perfect!Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-67978128210714219932012-04-03T01:19:00.000-07:002012-04-03T01:20:39.428-07:00plupload file browse dialog only open on firefoxI've just experienced an issue with <a href="http://www.plupload.com/">plupload</a>. Say that the file browse dialog open only on Firefox, other browsers doesn't work including IE 9, Chrome, Opera, I didn't test Safari though.
Fortunately <a href="http://www.plupload.com/punbb/viewtopic.php?id=1390">this thread</a> told me where the issue comes from. You must put the <code>browse_button</code> inside the <code>container</code>:
<pre class="brush: javascript">
var uploader = new plupload.Uploader({
runtimes : 'html5, flash, browserplus',
browse_button : 'theUploadBtn',
container: 'divPlUploadContainer', // << 'theUploadBtn' must be inside this element!
max_file_size : '2mb',
url : 'file/upload/handler',
multipart: true,
flash_swf_url : '/lib/plupload/js/plupload.flash.swf',
filters : [
{title : "Image files", extensions : "jpg,gif,png"},
]
});
</pre>
However plupload still not work on Opera with this changeAnonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com2tag:blogger.com,1999:blog-2560373426889485631.post-26541033752001755832012-03-07T02:24:00.001-08:002012-03-09T21:29:32.074-08:00Rythm - an easy to use high performance Java template engine<p>I've kept looking for a template engine that has the rich features of <a href="http://www.playframework.org/">Play!framework</a>'s <a href="http://www.playframework.org/documentation/1.2.4/templates">groovy template engine</a>, the speed of <a href="https://github.com/branaway/Japid">Japid</a> and the clean, elegant syntax of <a href="http://razorengine.codeplex.com/">Razor</a> for years. Without any findings, finally I decide to create one by myself. And it comes Rythm.</p>
<p>I've used it for 2 months in real projects and can't feel any better than that. I'd like to share this work to public and start to promote it. This blog is to give a very brief introduce to Rythm by example. I found Mr. Philipp Schneider's <a href="http://blog.coresystems.ch/philipp/velocity-quick-and-easy-template-engine-for-java-2/">blog on Velocity</a> is easy to go and decide to rewrite it using Rythm. So let's have a look on how I use the template in Java:</p>
<pre class="brush: java">Map<string, object> context = new HashMap<string, object>();
context.put("title", "template");
Person p1 = new Person("Mueller");
Person p2 = new Person("Schneider");
List<person> list = new ArrayList<person>();
list.add(p1);
list.add(p2);
context.put("personList", list);
String readyToUseTemplateOutput = Rythm.render("/folderinResource/MyTemplate.anyending", context);</pre>
<p>You can also choose to pass template arguments by location:</p>
<pre class="brush: java">
Person p1 = new Person("Mueller");
Person p2 = new Person("Schneider");
List<person> list = new ArrayList<person>();
list.add(p1);
list.add(p2);
String readyToUseTemplateOutput = Rythm.render("/folderinResource/MyTemplate.anyending", "template", list);</pre>
<p>And now the template file:</p>
<pre class="brush: java">@args String title, List<person> personList;
Hello world!
This is my first @title
@for (Person person: personList) {
@if (person_index == 1) {Here is a list of persons:}
- @person.getName()
}</pre>
<p>The result will look like this:</p>
<pre class="brush: java">Hello world!
This is my first template
Here is a list of persons:
- Mueller
- Schneider</pre>
<p>So this was really easy to use. And you can also create complex templates, that extends a layout template, invoke customized tags etc. You can do nearly all things that you can in velocity. Maybe even more. </p>
<p>In addition, Rythm is very fast, <a href="http://rythmengine.com/document/feature#performance">about 2 to 3 times faster than velocity</a>. Some other features about Rythm:</p>
<ul>
<li><b>Strong typed</b>. Meaning your template get compiled and less runtime error</li>
<li><b>In-memory compilation</b>. No need to call your javac to process generated java source files. Just call the API to process your template and get your result</li>
<li><b>Cached</b>. Your template compilation get cached so next time no parsing/generating/compilation and it means super fast</li>
<li><b>Hot reload on dev mode</b>. So if you are working on a server program you don't need to restart the server, just hit F5 to refresh your browser.</li>
<li><b>General purpose</b>. Rythm can be used to generate any type of text file. It's not limited to HTML/XML</li>
<li><b>Easy to define tag/macro</b> because every template is a tag and can be invoked from within any other templates</li>
<li><b>Support template inheritance</b>. Reusing your layout page is piece of cake.</li>
</ul>
<br/>
<p>Check more on <a href="http://www.rythmengine.com">http://www.rythmengine.com</a>!</p>
<p>Updates: I have just release an new <a href="http://www.playframework.org/modules/rythm">template engine plugin</a> built on top of Rythm for <a href="http://www.playframework.org">Play!Framework</a>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com9tag:blogger.com,1999:blog-2560373426889485631.post-40038348174906728042011-10-08T14:55:00.000-07:002012-03-07T22:10:57.491-08:00Play!Framework: Use RenderArgs and Excel module effectivelyMr. Basav Nagur has posted a <a href="http://bnagur.blogspot.com/2011/09/play-framework-excel-report-example.html">blog </a>demonstrates how easy it is to create Excel reports in Play!Framework. Being the author of Excel module, I really appreciate that. In additional I would like to help make the controller more concise in the sample code. Here is the original code of Application controller:<br />
<pre class="brush: java">package controllers;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.RandomStringUtils;
import models.Customer;
import play.Logger;
import play.modules.excel.RenderExcel;
import play.mvc.Controller;
import play.mvc.With;
@With(ExcelControllerHelper.class)
public class Application extends Controller {
public static void index() {
render();
}
public static void customerphonelist(){
Logger.info("Generating Customer Phone List Excel report ");
request.format = "xlsx";
Date date = new Date();
String user = "Bob";
List customers = new ArrayList();
for (int i = 0 ;i < 10; i++){
customers.add(new Customer("Mr", RandomStringUtils.randomAlphabetic(15), RandomStringUtils.randomNumeric(10)));
}
renderArgs.put("date", date);
renderArgs.put("user", user);
renderArgs.put("customers", customers);
renderArgs.put(RenderExcel.RA_ASYNC, true);
renderArgs.put(RenderExcel.RA_FILENAME, "customer_list_report.xlsx");
render();
Logger.info("Completed Customer Phone List Excel report ");
}
} </pre>
<div class="line number1 index0 alt2" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 13px; height: auto !important; left: auto !important; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 1em !important; padding-right: 1em !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre !important; width: auto !important;">
<span style="color: #006699;"><span style="line-height: 14px;"><b><br /></b></span></span></div>
<div>
The code is correct, however we could make even better in several places:</div>
<div>
<ol>
<li>"<code class="java color1" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; color: gray !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">@With</code><code class="java plain" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">(ExcelControllerHelper.</code><code class="java keyword" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; color: rgb(0, 102, 153) !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; font-weight: bold !important; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">class</code><code class="java plain" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">)</code>" could be removed. The dependency on that @With has been dropped since Excel v1.2.2</li>
<li>All renderArgs.put(...) for app variables could be removed. You simply pass the variable in the render() directly, and they will get put into renderArgs automatically. </li>
<li>"<code class="java plain" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">renderArgs.put(RenderExcel.RA_ASYNC, </code><code class="java keyword" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; color: rgb(0, 102, 153) !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; font-weight: bold !important; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">true</code><code class="java plain" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">);</code>" could be eliminated if you have "excel.async=true" in your conf/application.conf file.</li>
<li>"<code class="java plain" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">renderArgs.put(RenderExcel.RA_FILENAME, </code><code class="java string" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; color: blue !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">"customer_list_report.xlsx"</code><code class="java plain" style="background-attachment: initial !important; background-clip: initial !important; background-color: white; background-image: none !important; background-origin: initial !important; border-bottom-left-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-width: 0px !important; border-color: initial !important; border-image: initial !important; border-left-width: 0px !important; border-right-width: 0px !important; border-style: initial !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-top-width: 0px !important; bottom: auto !important; box-sizing: content-box !important; float: none !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 13px; height: auto !important; left: auto !important; line-height: 13px; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; min-height: inherit !important; outline-color: initial !important; outline-style: initial !important; outline-width: 0px !important; overflow-x: visible !important; overflow-y: visible !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important; position: static !important; right: auto !important; text-align: left; top: auto !important; vertical-align: baseline !important; white-space: pre; width: auto !important;">);</code>" could be eliminated if your template file name is "<span style="background-color: white; color: blue; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 13px; line-height: 13px; text-align: left; white-space: pre;">customerphonelist.xlsx</span>" which matches the controller name, or if the action method name renamed to "customer_list_report".</li>
</ol>
<div>
All these tiny little things tries to show the beauty of this great framework: being nice to programmer and making programming on the framework a really enjoyable experience. Now the new version of the Application.java:</div>
</div>
<pre class="brush: java">
package controllers;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.RandomStringUtils;
import models.Customer;
import play.Logger;
import play.modules.excel.RenderExcel;
import play.mvc.Controller;
public class Application extends Controller {
public static void index() {
render();
}
public static void customer_list_report(){
Logger.info("Generating Customer Phone List Excel report ");
request.format = "xlsx";
Date date = new Date();
String user = "Bob";
List customers = new ArrayList();
for (int i = 0 ;i < 10; i++){
customers.add(new Customer("Mr", RandomStringUtils.randomAlphabetic(15), RandomStringUtils.randomNumeric(10)));
}
render(date, user, customers)
Logger.info("Completed Customer Phone List Excel report ");
}
}
</pre>
<div>
<br /></div>
Isn't it more concise and easier for both programming and reading? What do you think?<br />
<br />
One additional note about xlsx format of excel template, in order to use that, you will need Excel v1.2.3x version instead of v1.2.3 version mentioned in original post.<br />
<br />
BTW, I would be really glad if someone tell me how to format code in the way Mr. Basav did in his post :)Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com5tag:blogger.com,1999:blog-2560373426889485631.post-27424783897285854272011-09-17T17:40:00.000-07:002011-09-18T12:47:14.660-07:00The Trouble with LESSCSS<a href="http://www.playframework.org/modules/greenscript-1.2.6g/home">GreenScript v1.2.6</a> start to support <a href="http://lesscss.org/">LESS</a>. I am pretty excited with this feature and decide to move on to LESS. However very soon I found I am faced with an annoying issue with LESS.<br />
<br />
So the story starts with <a href="http://twitter.github.com/bootstrap/">twitter bootstrap</a>, a CSS framework built with LESS which is pretty hyped up by web developers recently. I decide to use it in my <a href="http://www.playframework.org/documentation/1.2.3/main#appviews">view</a>. I've included 'less/bootstrap.less' in my default template. It's all good, unless I want to reference a variable defined in bootstrap library in my own foo.css:<br />
<code><span style="color: #073763;">
.hero-unit .h2 {<br />
margin-bottom: .5em;<br />
font-size: 40px;<br />
color: @grayLight; // grayLight is defined in less/preboot.less file<br />
padding: 0 10em;<br />
}
</span></code>
<br />
<br />
The problem with the above code is when GreenScript tries to compile it, the less compiler complains that the variable @grayLight is not defined. Well, it's a surprise but it's correct. The fix is to add the following line to the beginning of the css file:<br />
<code><span style="color: #073763;">
@import "bootstrap/preboot.less";
</span></code>
<br />
<br />
However, the issue with this approach is it duplicates all compiled css code from "bootstrap/preboot.less" in the final css output. And if every css file tries to include this or that less libraries, the css will get bloated very quickly.<br />
<br />
Another approach is to remove all @import clause from LESS file and let GreenScript's dependent management mechanism to manage the import relationships. E.g. in the view file (or in greenscript.conf file), declare the dependency between foo.css and bootstrap/preboot.less:<br />
<code><span style="color: #073763;">
#{css 'foo < bootstrap/preboot'/}
</span></code>
<br />
<code><span style="color: #073763;"><br /></span></code><br />
GreenScript will make sure the content of preboot.less be put in front of foo.css when doing merge of the 2 files. And then call less compiler to compile the merged content. That could solve the result css bloat out problem, but another issue comes up. Because GreenScript run LESS compilation on merged file only, if there is an error in the compilation, it's not possible to give out information that which file caused the trouble, and make it very hard to debug the LESS errors.<br />
<br />
The final solution might need a pure Java Less compile engine supporting the session concept, where all the LESS variables, mixins etc be cached through out the session and could used in future compilation process in the same session. So far I don't know there is any implementation for this stuff. I would like to put it in my TO-DO list. But please let me know if you already have that tool.<br />
<br />Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com1tag:blogger.com,1999:blog-2560373426889485631.post-74223417810599772932011-08-05T06:48:00.001-07:002011-08-05T07:06:15.726-07:00Remove the scrollbars from your facebook canvas applicationOne of my facebook canvas applications always display the vertical and horizontal scrollbars with it, which is very annoying. By looking into the html source code with firebug, I found the app is hosted inside the <ifram> element with "smart_sizing_iframe" class. While another app without the scrollbars is hosted inside the <ifram> element with "canvas_iframe_util" class. I am pretty sure that my app code is the same in terms of canvas size setting.<br /><br />After visiting my app settings from https://developers.facebook.com I got the tricky: go to the "canvas setting" under "On Facebook", you have two option for IFrame size: "Show Scrollbars" and "Auto-resize". By selecting "Auto-resize" and save, then refresh your application page, then you got it! Yes, the scrollbar get removed.Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com2tag:blogger.com,1999:blog-2560373426889485631.post-26329395118696697052011-07-28T05:04:00.000-07:002012-03-07T22:11:35.551-08:00Use GreenScript correctlyI've just encountered an mail about greenscript in the <a href="http://www.playframework.org/">playframework</a> google group. Here is the code:<br /><p>-- main.html --</p><pre class="brush: html"><br /><html><br /><head><br /><title>#{get 'title' /}</title><br />#{get 'moreStyles' /}<br /><link href="@{'/public/images/favicon.ico'}" rel="shortcut icon" type="image/x-icon"></link><br />#{script 'jquery-1.6.2.min.js' /}<br />#{script 'jquery.validate.min.js' /}<br />#{script 'jquery.form.js' /}<br />#{get 'moreScripts' /}<br /></head><br /><body><br />#{doLayout /}<br /></body><br /></html></pre><br />-- index.html --<pre class="brush: html"><br />#{extends 'main.html' /}<br />#{set title:'title' /}<br />#{set 'moreStyles'}<br />#{greenscript.css "main005", output:'all'/}<br />#{/set}<br />#{set 'moreScripts'}<br />#{greenscript.js output:true}<br />#{/set}<br />...</pre><br /><br />So what's wrong in the above code:<br />1. JavaScripts did not get processed (minimize and compress) at all. The above code is still using #{script} tag to output JavaScripts, which will NOT gain the benefit of greenscript at all<br />2. Using #{set 'moreScripts'} and #{get 'moreScripts'} is neither needed nor encouraged when you have the power of greenscript.<br /><br />This code gives me a feeling that you have an electric motor saw but you are using it like a plain saw by not powering it on. The correct way could be much more simpler:<br /><br />-- main.html --<br /><pre class="brush: html"><html><br /><head><br /><title>#{get 'title' /}</title><br /><meta charset="utf-8"><br /><link href="@{'/public/images/favicon.ico'}" rel="shortcut icon" type="image/x-icon"/><br />#{greenscript.js 'jquery.form < jquery.validate.min < jquery-1.6.2', output:'all'/}<br />#{greenscript.css output:'all'/}<br /></head><br /><body><br />#{doLayout /}<br /></body><br /></html></pre><br />-- index.html --<pre class="brush: html"><br />#{extends 'main.html' /}<br />#{set title:'title' /}<br />#{greenscript.css 'main005' /}</pre><br />Tips:<br /><ul><li><code>you can declare multiple resource files in one greenscript tag. E.g. <code>#{greenscript.js 'a b c'/}</code> declares /public/javascripts/a.js, /public/javascripts/b.js and /public/javascripts/c.js using one call to greenscript js tag</code></li><li><code>you can declare dependencies inside greenscript tag, e.g. <code>#{greenscript.js 'jquery.validate.min < jquery-1.6.2' /}</code> will guarantee jquery-1.6.2.js be rendered before jquery.validate.min.js/</code></li><li><code>use [output: 'all'] to render all declared and not rendered resources. E.g. <code>#{greenscript.css output: 'all' /}</code> will output all declared css resource in place. Usually you should use [output: 'all' ] inside <head> block</code></li><li><code>By typing "<code>play greenscript:cp -a .</code>" in your project folder, you copied the needed tags to your project and you can simply the invoking of greenscript tag as: <code>#{js .../}, #{css ... /}</code></code></li></ul>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-57867668618726432212011-06-18T16:58:00.001-07:002011-06-18T17:00:17.883-07:00Play-Excel v1.2.1 released with support to asynchronous Excel rendering<span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; "><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">I am very glad to release play-excel-1.2.1 which support asynchronous report rendering. Here are changes compare to v1.1:</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><b style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">Render method call</b></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.1: play.modules.excel.Excel.<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">renderExcel(...)</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.2: play.mvc.Controller.render(...<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">), play.mvc.Controller.<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">renderTemplate(...)</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">in other words, now you don't even aware that you are rendering a Excel report or normal HTML report. Everything is determined by request.format. Once your request.format set to 'xls' or 'xlsx', Excel module will take over the rendering process automatically. There are 2 ways to set request.format:</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">1. explicitly set request.format in controller methods</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">a. Set request.format in Action methods</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">b. Set request format in @Before methods based on http params for example</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">2. set request.format in route config file. Refer to <a href="http://www.playframework.org/documentation/1.2.1/routes#content-types" target="_blank" style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; color: rgb(119, 153, 187); ">http://www.playframework.<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">org/documentation/1.2.1/<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">routes#content-types</a> for detail</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><b style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">Template location</b></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.1 Excel template can not be put inside views folder, instead you will need to put the templates outside of views folder and set the template root in application.conf file, e.g. <span style="font-family: 'Envy Code R', Monaco, consolas; font-size: 13px; line-height: 18px; white-space: pre-wrap; ">excel.template.root=app/<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">excel_tmpl</span></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.2 Just put Excel template in views folder along with your normal groovy template files. And of course "excel.template.root" shall not be used anymore</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><b style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></b></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><b style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">File name</b></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.1 set download file name by set "fileName" in renderArgs</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.2 use play.modules.excel.<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">RenderExcel.RA_FILENAME instead of "fileName".</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><b style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></b></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><b style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">Async rendering (v1.2.1 only)</b></div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.1 does not support asynchronous rendering</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">v1.2.1 support transparent asynchronous rendering. You don't have to deal with Future, Promise, await, request.new etc and you get the power for nearly free (Yes, this is really cool! and thanks to the excellent play framework again!). The only place you need to touch is </div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">1. add "excel.async=true" in application.conf, which enable async rendering globally</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">2. do renderArgs.set(play.modules.<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">excel.RenderExcel.RA_ASYNC, true) in your action controller to enable async rendering for this controller action only</div><div style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; "><br /></div></span><span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; "><div><span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; "><br /></span></div>For those who don't yet see the power of async rendering, please refer to <a href="http://www.playframework.org/documentation/1.2.1/asynchronous" target="_blank" style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; color: rgb(119, 153, 187); ">http://www.playframework.<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">org/documentation/1.2.1/<wbr style="font-family: tahoma, verdana, 'lucida sans', helvetica, arial !important; ">asynchronous</a>, or think about the fact that a large Excel table rendering might take as long as 500ms and blocking request handling thread for half second is NOT acceptable in a high performance web server like play which use only limited thread (N+1) to handle web requests.</span><div><span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; "><br /></span></div><div><span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; "><br /></span></div><div><span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; "><br /></span></div><div><span class="Apple-style-span" style="border-collapse: collapse; font-size: 12px; font-family: tahoma, verdana, 'lucida sans', helvetica, arial; ">- Green</span></div>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-31709743082991685292011-04-03T21:07:00.000-07:002011-04-03T21:56:02.743-07:00greenscript-1.2d releasedThere are a couple of new features released on this version (v1.2d):<br /><br /><div><b>1. Resource and dependency management in modules</b></div><div>Now you are able to manage your javascript and css files in modules. Meaning you could be able to create a "greenscript.conf" file in your ${module.root}/conf folder, put javascript and css files in ${module.root}/public/(javascripts|stylesheets} folders and reuse them with any play applications. </div><div><br /></div><div><b>2. Inline dependency declaration in tags</b></div><div>There is a long time complaint about greenscript that the sequence of declared resources in tag does not get kept when those resources are output to html page. Now with inline dependency declaration feature, the inconvenience is largely removed. E.g.</div><div><br /></div><div><span class="Apple-style-span" >#{greenscript.js 'myapp < mylib < jquery-1.4.4.min' /}</span></div><div><br /></div><div>A tag declaration like above automatically set the dependence graph between myapp.js, mylib.js and jquery-1.4.4.min.js. I.e. myapp.js relies on mylib.js, which in turn relies on jquery-1.4.4.min.js. You don't need to be forced to create conf/greenscript.conf to declare the dependencies.</div><div><br /></div><div>This feature is very useful for those application with relatively simple resource dependencies.</div><div><br /></div><div><b>3. Reverse dependence declaration in greenscript.conf file</b></div><div>This is actually a feature added since v1.2c. Usually you declare dependency relationship in greenscript.conf file as follows:</div><div><br /></div><div><span class="Apple-style-span" >js.myapp=mylib1,mylib2</span></div><div><br /></div><div>which means myapp.js relies on both mylib1.js and mylib2.js. However with reverse dependence declaration, you switch the dependency relationship arrow:</div><div><br /></div><div><span class="Apple-style-span" >js.mylib1-=myapp1,myapp2</span></div><div><br /></div><div>meaning both myapp1.js and myapp2.js relies on mylib1.js. This feature makes it convenient to declare dependency relationships associated with things like jquery:</div><div><br /></div><div><span class="Apple-style-span" >js.jquery-1.4.4.min-=jquery-ui-1.8.9.min,jquery-validate.min,jquery-tmpl.min</span></div><div><span class="Apple-style-span" ><br /></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; ">Note to declare reverse dependence relationship, you put a 'hyphen' right left to 'equal' sign in the statement.</span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; "><br /></span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; "><b>4. support '.bundle' suffix</b></span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; ">The '.bundle' suffix could be used in greenscript.conf dependence relationship declarations. E.g.</span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; "><br /></span></span></div><div><span class="Apple-style-span" >js.common.bundle=mylib1,mylib2,mylib3...</span></div><div><span class="Apple-style-span" >js.common.bundle-=myapp1,myapp2...</span></div><div><span class="Apple-style-span" >...</span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; "><br /></span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; ">In the above example, 'common.bundle.js' is not a real javascript file. It's merely a symbol represent a group of resources (mylib1.js, mylib2.js, mylib3.js ...). </span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; "><br /></span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; ">This feature makes it convenient to group your resources. It could also be used to create alias for resources that might be updated due to new version, e.g.</span></span></div><div><span class="Apple-style-span" ><span class="Apple-style-span" style="font-family: Georgia, serif; "><br /></span></span></div><div><span class="Apple-style-span" >js.jq.bundle=jquery-1.4.4.min</span></div><div><span class="Apple-style-span" >js.mylib1=jq.bundle,...</span></div><div><br /></div><div>In the above example, you create an alias 'jq.bundle' for jquery-1.4.4.min, which could be easily updated to jquery-1.5.2.min in your greenscript.conf file.</div><div><br /></div><div>In summary, the new version of greenscript continue to move ahead in the way to make developer's life more easier and more interesting.</div>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-71337577756066749022010-12-23T17:36:00.001-08:002010-12-23T18:32:43.713-08:00java.lang.VerifyError caused by Play-MorphiaIt comes out intermittently and shows something like: <br /><pre>Exception in thread "main" java.lang.VerifyError: (class: models/NodeDelta, method: findById signature: (Ljava/lang/Object;)Lplay/modules/morphia/Model;) Wrong return type in function<br /> at java.lang.Class.getDeclaredMethods0(Native Method)<br /> at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)<br /> at java.lang.Class.getDeclaredMethods(Class.java:1791)<br /> at com.google.code.morphia.utils.ReflectionUtils.getDeclaredAndInheritedMethods(ReflectionUtils.java:115)<br /> at com.google.code.morphia.utils.ReflectionUtils.getDeclaredAndInheritedMethods(ReflectionUtils.java:98)<br /> at com.google.code.morphia.mapping.MappedClass.discover(MappedClass.java:131)<br /> at com.google.code.morphia.mapping.MappedClass.<init>(MappedClass.java:110)<br /> at com.google.code.morphia.mapping.Mapper.addMappedClass(Mapper.java:139)<br /> at com.google.code.morphia.Morphia.map(Morphia.java:55)<br /> at play.modules.morphia.MorphiaPlugin.afterApplicationStart(MorphiaPlugin.java:166)<br /> at play.Play.start(Play.java:440)<br /> at play.Play.init(Play.java:274)<br /> at play.server.Server.main(Server.java:131)<br /></pre><br />Something is wrong obviously in the bytecode enhancer. But I just can't figure it out until i noticed the line of code:<br /><pre>CtMethod findById = CtMethod.make("public static Model findById(java.lang.Object id) { return mf.findById(id); }",ctClass);</pre><br />Where <code>mf</code> is an instance of <code>play.db.Model.Factory</code>, and method <code>play.db.Model.Factory#findById</code> return an instance of <code>play.db.Model</code>, while actually a <code>play.modules.morphia.Model</code> is expected. Changing the line to the follows fixed the VerifyError:<br /><pre>CtMethod findById = CtMethod.make("public static Model findById(java.lang.Object id) {return <span style="color:red">(Model)</span>mf.findById(id); }",ctClass);</pre>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-69314027909280604242010-12-15T20:08:00.000-08:002010-12-15T21:41:27.370-08:00Create a hierachical navigator in IBM Lotus WCMI googled for long time for a solution that could produce hierarchical unordered list corresponding to site areas. Something like:<br /><pre><ul><br /><br /><li>A<br /> <ul><br /> <li>A.1</li><br /> <li>A.2</li><br /> </ul><br /></li><br /><br /><li>B<br /> <ul><br /> <li>B.1</li><br /> <li>B.2</li><br /> <li>B.3<br /> <ul><br /> <li>B.3.1</li><br /> <li>B.3.2</li><br /> <li>B.3.3</li><br /> </li><br /> </ul><br /></li><br /><br /></ul></pre><br /><br />I follow the method introduced <a href="http://wiki.base22.com/display/btg/Nested+bulleted+list+in+WCM">here</a>. However I found it does not work out the whole hierarchies. I guess the NAV--SubNavigation with StartType equals to "Current Site Area" prevent it from happening.<br /><br />The final solution is to use navigator to generate a linear list of nodes and use javascript to reconstruct the hierarchies.<br /><br />Here is navigator definition:<br /><br />Start Type: selected<br />Include Start: false<br />Ancestor Level: none<br />Descendant Level: All (or choose the level of hierarchies you want)<br />Preceding Siblings Level: none<br />Next Siblings Level: none<br />Show Site: false<br />Show content: false<br />Expand current navigator branch one level: false<br />Expand navigator to display current site area: false<br />Results per page: 1000 (or choose a number that is larger than the maximum items)<br />Start page: 1<br />Maximum pages to include: 1000 (or choose a number large enough)<br />Pages to read ahead: 1000 (or choose a number large enough)<br />Distinguish items with no children using the final navigator result design: false<br />Header: <url><br />Footer: </ul><br />Separator:<br />Navigator result design 1:<br /><pre><li class="l1" id="<Placeholder tag="idnum"/>"><a href="<Placeholder tag="href"/>" target="_self" title="<Placeholder tag="Title"/>"><Placeholder tag="Title"/></a></li></pre><br />Navigator result design 2:<br /><pre><li class="l2" id="<Placeholder tag="idnum"/>"><a href="<Placeholder tag="href"/>" target="_self" title="<Placeholder tag="Title"/>"><Placeholder tag="Title"/></a></li></pre><br />Navigator result design 3:<br />...<br /><br />And this navigator gives the following html code:<br /><pre><ul><br /><li class="l1">A</li><br /><li class="l2">A.1</li><br /><li class="l2">A.2</li><br /><li class="l1">B</li><br /><li class="l2">B.1</li><br /><li class="l2">B.2</li><br /><li class="l2">B.3</li><br /><li class="l3">B.3.1</li><br /><li class="l3">B.3.2</li><br /><li class="l3">B.3.3</li><br /></ul></pre><br /><br />Now it's javascript's work. In order to re-constructure the hierarchies, I write the following codes:<br /><br /><pre>function process(level) {<br /> var sel = 'li.l' + (level - 1);<br /> jQuery.each(root.children(sel), function(id, el){<br /> var pe = jQuery(this);<br /> var dock;<br /> var nl = pe.nextUntil(':not(li.l' + level + ')');<br /> jQuery.each(nl, function(id, el){<br /> if (!dock) dock = getDock(pe, level - 1);<br /> jQuery(el).appendTo(dock);<br /> });<br /> });<br />}<br /><br />function getDock(pe, level) {<br /> var ul = pe.children('ul');<br /> if (ul.size() == 0) {<br /> ul = jQuery('<ul class="l' + level + 'ul"></ul>').appendTo(pe);<br /> } else {<br /> ul = ul[0];<br /> }<br /> return ul;<br />} <br /><br />var root = null;<br />jQuery(function(){<br /> root = jQuery('#ul'); //you should update #ul accordingly<br /> jQuery.each([5,4,3,2], function(id, val){process(val)});<br />});</pre><br /><br />Now a good rendered hierarchies presented in my final html page.Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-13076662533387548092010-11-16T00:59:00.000-08:002010-12-19T22:45:40.093-08:00Build full text search capability upon MongoDBRecently I am working on a content management system migration project. We have exported the existing system into a folder composed of 18k xml files organized into a set of sub folders. What we need to do is to understand the relationships among the files and folders, manipulate them by adding/removing/updating and then import into a new server.<br /><br />Navigating through these huge amount of files is definitely not an easy task, and the embedded base64 encoded content makes this task almost an MIP. This is why I decide to build a full-text search tool to help us quickly locate files contain certain contents we are interesting at any time.<br /><br />I pick up MongoDB because it is a document database, don't need restricted schema definition, and I am quite familiar with it as the author of <a href="http://www.playframework.org/modules/morphia">play-morphia</a> plugin. So what I am doing is to write a script (in perl) parse all XML files into the database. The script parse tags/attributes/text nodes/CDATAs of the XML files, decode base64 element if found. The interesting part is how to setup a full-text search capability in MongoDB. Following <a href="http://www.mongodb.org/display/DOCS/Full+Text+Search+in+Mongo">this</a> article, I've created an array column called keywords for each document. The XML parser script will add into keywords array for each words found in tags/attributes/text/CDATA and decoded Base64 content. <br /><br />Next is to implement a query for full text search, which is not specified in the article mentioned above. The key for full text query is use $all operator and regular expression. For example, if you want query documents including both "NSW" and "QLD", the query statement in javascript could be: <br /><br /><code>db.docs.find({_keywords:{$all:[/\bNSW\b/, /\bQLD\b/]}})</code>; <br /><br />In java, the code snippet could be: <br /><pre><br />DBObject q = new BasicDBObject();<br />if (keys_.size() > 0) {<br /> DBObject keys = new BasicDBObject();<br /> List<Pattern> pl = new ArrayList();<br /> for (String w: keys_) {<br /> w = w.replace("\\s+", "\\s+");<br /> pl.add(Pattern.compile(w));<br /> }<br /> keys.put("$all", pl.toArray(new Pattern[]{}));<br /> q.put("_keywords", keys);<br />}<br />DBCursor c = col_.find(q);<br />if (0 < skip_) c.skip(skip_);<br />if (0 < limit_) c.limit(limit_);<br /></pre>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-80355187422858638172010-10-01T19:25:00.000-07:002010-10-01T19:51:47.612-07:00Google.load vs. $(document).ready()I am trying to use google visualization in my recent project. After some study, I found it is quite different in terms of usage from my previous mindset. Usually when we need an external javascript library, we go to the web site and download it, and include it in our html file like:<br /><br /><script type='text/javascript' src='url-to-the-js-lib'></script><br /><br />However, this is quite different with google visualization case. A typical usage with google visualization could something like:<br /><br /><script type='text/javascript' src='http://http://www.google.com/jsapi'></script><br /><script type='text/javascript'><br />google.load('visualization', '1', {'packages':['piechart', 'table', 'linechart']});<br />google.setOnLoadCallback(mydrawfunc);<br /></script ><br /><br />the API name "setOnLoadCallback" is misleading to me. It looks like a special hook that get invoked when the visualization (or other google apis) loaded into the dom. So here is my hypothetical google-loader.js: <pre><code>$(document).ready(function(){<br /> $('<div id="google-loading-overlay"></div>').css({<br /> 'position': 'fixed',<br /> 'top': 0,<br /> 'right': 0,<br /> 'bottom': 0,<br /> 'left': 0,<br /> 'background': 'url(/img/busy.gif) no-repeat center center',<br /> 'background-color': '#ECECEC',<br /> 'z-index': 9999<br /> }).appendTo($('body'));<br /> google.load('visualization', '1', {'packages':['piechart', 'table', 'linechart']});<br /> google.setOnLoadCallback(function(){<br /> $('#google-loading-overlay').remove();<br /> myDrawFunc();<br /> });<br />});</code></pre>The idea is simple, create an overlay before calling google.load(...), preventing user from operating the current page and display a busy indicator. After the visualization apis get loaded, remove the overlay and draw the charts.<br /><br />However, it just don't work. You always get a blank page, in Chrome, it shows an null error, in firefox it looks like the loading process never end. So what's going on here? I suddenly see the light when reading <a href="http://groups.google.com/group/google-ajax-search-api/browse_thread/thread/507cdb5ca10a2d01?pli=1">this thread</a>: <span style="font-style:italic;font-weight:bold">The problem that you're having here is that google.setOnLoadCallback and $(document).ready are essentially synonymous.</span>. setOnLoadCallback basically means your dom construction is finished. So the solution is very simple, just put the following line in my google-loader.js: <pre><code>google.load('visualization', '1', {'packages':['piechart', 'table', 'linechart']});</code></pre>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com1tag:blogger.com,1999:blog-2560373426889485631.post-86034812974789937852010-09-20T17:59:00.001-07:002010-09-20T19:50:53.149-07:00Setting up Django environment in CentOS 5I am trying to setup Django v1.2.3 to run on our server which is CentOS 5.2.<br /><br />Though Django support python2.4 bundled with this OS, I decide to get it running on Python2.6, which makes me feel not so out. In the beginning I was thinking it could be a task of 10 mins, and not expecting so many unexpected things happened:<br /><br />The first issue is replacing python2.4 with python2.6 breaks the yum toolkit on CentOS 5.2. Shame for that. Fortunately some other guys has met the problem already and there are lot's of blogs and question/answers addressing this issue. I follow this one: <a href="http://www.question-defense.com/2009/12/25/how-to-install-python-2-6-on-centos-5-without-breaking-yum">how to install python2.6 on centos5 without breaking yum</a>. It almost works, just a minor problem: yum report that libffi-3.0 not found while installing python2.6. So google again, and there it is: <br /><code>wget ftp://ftp.pbone.net/mirror/centos.karan.org/el5/extras/testing/i386/RPMS/libffi-3.0.5-1.el5.kb.i386.rpm</code><br />After installing this rpm package, I can get python2.6 installed.<br /><br />Now download Django-1.2.3.tar.gz from official site, unpack, and run <code>python26 setup.py install</code>. Oops, wait, there is problem:<br /><p style="color:red">invalid Python installation: unable to open usr/lib/python2.6/config/Makefile</p><br />Okay, google again, and someone said it's due to you have not installed python-dev package. Let's try <code>yum install python26-dev</code> and then run <code>python26 setup.py install</code> again. Bingo!<br /><br />Now that we have the Django installed at <code>/usr/lib/python2.6/site-packages</code>. Let's give it a try:<br /><br />1. update <code>/etc/bashrc</code>, add "<code>export DJANGO_HOME=/usr/lib/python2.6/site-packages/django</code>"<br />2. <code>. /etc/bashrc && chmod a+x $DJANGO_HOME/bin/*.py</code><br />3. <code>ln -s $DJANGO_HOME/bin/django-admin.py /usr/bin/django-admin.py</code><br />4. <code>cd /tmp</code><br />5. <code>django-admin startproject mysite</code><br /><br />Oops, error again: <pre style="color:red">Traceback (most recent call last):<br /> File "/usr/bin/django-admin.py", line 2, in ?<br /> from django.core import management<br />ImportError: No module named django.core</pre><br />Damn it, I forgot django is installed to python26. Okay, let me do something to hack it:<pre><code># cd $DJANGO_HOME/bin<br /># find . -name '*.py' | sed -i 's/env python/env python26/'</code></pre><br />now run <code>django-admin startproject mysite</code> works. and let me continue:<br />6. <code>cd mysite && python26 manage.py runserver</code><br /><br />OMG, it breaks again, all the files generated by <code>django-admin</code> use python as default env, not python26. I am getting tired of adding my hacks to Django. I need to figure out some other ways.<br /><br />Yes, python support virtualenv, that's exactly what I need! Follow the process described in <a href="http://andrew.io/weblog/2010/02/installing-python-2-6-virtualenv-and-virtualenvwrapper-on-dreamhost/">this blog</a>, I can continue again:<pre><code># wget http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.5.1.tar.gz<br /># tar xzf virtualenv-1.5.1.tar.gz<br /># cd virtualenv-1.5.1<br /># su greenl<br />$ python26 virtualenv.py ~/opt/local<br />$ cd ~<br />$ wget http://www.doughellmann.com/downloads/virtualenvwrapper-1.23.tar.gz<br />$ tar xzf virtualenvwrapper-1.23.tar.gz<br />$ cd virtualenvwrapper-1.23<br />$ cp virtualenvwrapper_bashrc ~/bin<br />$ cd ~<br />$ mkdir .virtualenvs<br />$ mkvirtualenv django<br />$ workon django<br />$ easy_install django<br />$ cd /tmp<br />$ sudo rm -rf mysite<br />$ django-admin.py startproject mysite<br />$ cd mysite<br />$ python manage.py runserver &<br />$ lynx localhost:8000</code></pre><br />Works perfect!<br /><br />In conclusion: <br />1. You can install python2.6 on CentOS 5 without breaking yum<br />2. You can install django latest version (currently v1.2.3) on python2.6 site-packages<br />3. You need to install virtualenv in order to get django run on python2.6 transparently<br />4. You may want to install virtualenvwrapper in order to make your life easier with virtualenv.<br />5. After you have done all these, you have an nice env for your django journey!Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-82372673084659379602010-09-19T16:33:00.000-07:002010-09-20T04:00:08.010-07:00Routing problem with GreenScript configuratorIn the morning when I play with GreenScript configurator to verify it's compatibility with Play-1.0. I found all these mapping entries do not work anymore:<ul><li><code>http://localhost:9000/gs/</code></li><li><code>http://localhost:9000/gs/conf</code></li><li><code>http://localhost:9000/gs/configure</code></li><li><code>http://localhost:9000/gs/setting</code></li></ul><br />However, this link works: <code>http://localhost:9000/gs</code> (without "/" suffix!)<br /><br />Later I realized that I have an entry in the routing table of the demo app: <code>GET /gs/ staticDir:public/gs</code>, for shortcut of URL to compressed/minimized files.<br /><br />Yes, this is the problem. You can't make both static file and controller mapping to the same url path!Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-74239750962452994102010-09-19T16:18:00.000-07:002010-09-19T17:22:11.214-07:00Play python interface compatibilityit looks like the new version of <a href="http://www.playframework.org/modules/greenscript">GreenScript</a> is quite welcome in the community.<br /><br />Tom is obviously one of them who love this plugin. He report a bug very promptly. After installed v1.1, as long as he try to invoke any play command like <code>play eclipsify</code> or <code>play greenscript:cp ...</code>. it will end up with the following error:<pre><code>=====<br />C:\code\phase3>play eclipsify<br />~ _ _<br />~ _ __ | | __ _ _ _| |<br />~ | '_ \| |/ _' | || |_|<br />~ | __/|_|\____|\__ (_)<br />~ |_| |__/<br />~<br />~ play! 1.0.3.2, http://www.playframework.org<br />~<br />Traceback (most recent call last):<br /> File "C:\play-1.0.3.2\play", line 1459, in <module><br /> execfile(commands)<br /> File "C:\play-1.0.3.2\modules\greenscript-1.1\commands.py", line 4,<br />in <module><br /> from play.utils import *<br />ImportError: No module named play.utils<br />====<br /></code></pre><br /><br />This is my fault. I didn't expect the play command interface has been changed since play-1.1. Here is the solution:<pre><code><br />try:<br /> # play_command is defined in Play-1.0 only<br /> play_command<br />except NameError:<br /> play_command = None<br />if play_command is None:<br /> # ~~~~~~~~~~~~~~~~~~~~~ running on v1.1<br /> # go v1.1 logic<br />else:<br /> # ~~~~~~~~~~~~~~~~~~~~~ running on v1.0<br /> # go v1.0 logic<br /></pre></code>Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0tag:blogger.com,1999:blog-2560373426889485631.post-91300306968066726202010-09-18T23:11:00.000-07:002010-09-19T01:58:51.285-07:00Play-GreenScript v1.1 ReleasedThis is a version with huge improvements:<ul><li>Many bug fixes</li><li>Completely new Plugin Configurator</li><li>Add Command to enable user copy module tags/templates to user app directory</li><li>More clear configuration settings</li><li>Even more simplified tag syntax</li><li>Support zero configuration</li><li>Document improvement</li></ul><h3>Comparison to v1.0</h3><ol><li><h4>Configuration:</h4><ul><li>v1.0 - The dependency configuration file: "greenscript.conf" is mandatory</li><li>v1.1 - Zero configuration</li></ul></li><li><h4>Dynamic configuration</h4><ul><li>v1.0 - A simple window with a <textarea> tag. You are on your own to write the content in the textarea. Error prone: typos, unattended updates to dependencies</li><li>v1.1 - A sophisticated web interface help you clearly view the status/configuration of GreenScript plugin and prevent you from making mistakes when you try to turn on/off minimizing/compressing/cache.</li></ul></li><li><h4>Tags</h4><ul><li>v1.0 - #{greenscript.css import:['css1', 'css2']/}</li><li>v1.1 - #{greenscript.css 'css1 css2'/}<p>For existing greenscript users, the old syntax also works, but you are encourage to move to the new simple version.</p></li></ul></li><li><h4>Commands</h4><ul><li>v1.0 - no command support</li><li>v1.1 - play greenscript:cp -a --tag=xx | -t --template=xx</li></ul></li></ol><br />For more information please go to <a href="http://www.playframework.org/modules/greenscript-1.1/home">GreenScript home</a>.<br /><br />PS: Forgot the secret weapon: with "play greenscript:cp -a .", you can use tags in this way:<br /><br />#{js 'js1 js2 ...' /}<br />#{css 'css1, css2, ...' /}<br /><br />How can you expect anything simpler than this?Anonymoushttp://www.blogger.com/profile/11952421268765991465noreply@blogger.com0