Japid42
A full feaured Java-based template engine for Play2
Install / Use
/learn @branaway/Japid42README
h1. japid42 - Japid for Play 2
Bing Ran (bing.ran@gmail.com)
The latest version: see the end of this file for version information
Compatibility: Play 2.1.x, 2.2.x Note: One must use Japid42 version 0.9.16 or later with Play 2.2.1 or later.
Note: version 0.7.4 and older is compatible with 2.0.4. Version 0.9.9.1 or earlier is compatible with Play2.1.x.
h2. About
Japid42 is a native Java based template engine for Java programmers using Play2. It can also be used in any application that need an advanced templating solution.
Very fast in reloading changed views. You simply change the views and refresh your browser to get it right away in a blink instead of taking a coffee break. Japid manages its own view compilation and class loading. Changes in the Japid views are isolated from the Play reloading mechanism.
Full featured. It at least matches the feature set of the built-in Scala based template engine.
Excellent runtime performance.
Java-based, thus very friendly to Java programmers.
The core Japid has been used in production for a long time and is very robust.
Japid views compile lazy and compile on demand, unnoticed.
It integrates with Play2 seamlessly, in the meantime can be used stand-alone with any Java applications.
h2. Features
- freely mixing Java code in templates.
- layout inheritance
- tags and local snippet
- controller action invocations from within views
- implicit objects available in views: request, response, session, flash, lang
- all sorts of directives
- support Play2 forms, fields, data binding and form validations.
- cache with action invocation, wither using the Cached annotation or timeout spec in `a directive
- session.authentityToken to protect app from forged form submission attach.
- render data to dynamic templates in memory
- support JDK6 & 7.
- fully distribute-able in jar files.
New features since version 0.9.5:
- It comes with a Play router implementation that use a mixture of annotation and convention to do away with the route files of typical Play applications. See below for detail.
Credit: the work is derived from Peter Hausel's little nice project hosted here: https://github.com/pk11/play-jaxrs. The differences are explained later.
h2. Usage
h4. For a full sample application with Japid, see: http://github.com/branaway/computer-japid
Please also check out the JapidSample project in the samples directory for an example.
Basically you'll need to do three things:
- Get the dependencies
- declare Japid in the project/Build.scala and add the local repository resolver:
Note: adjust the version number accordingly.
- Initialize Japid in Global.java in the app directory:
Note:
- There are a few things that can be customized here. Here is a list of them. Hopefully they are self-explanatory.
Please see the @computer-japid@ (https://github.com/branaway/computer-japid) example for a real-world Global class definition.
- Extend cn.bran.play.JapidController to create your own controllers and use the renderJapid(...) etc to render the views.
- Create the Japid view script "{my app root}/japidroot/japidviews/Application/index.html":
- Hit http://localhost:9000/ to see Japid at work!
h2. Releasing Your Application
When an app is ready to be distributed, you'll need to modify the build.scala to prepare your project for distribution. There are two things needed to be done:
include a directive in the build.scala to specify where the Japid root directory is, so the Japid scripts are included in the generated jar file. Note, you'll want to leave it commented out in dev mode, since it would trigger app reloading when a Japid script is changed.
<pre><code> val main = play.Project(appName, appVersion, Seq()).settings( ... ,unmanagedResourceDirectories in Compile <+= baseDirectory( _ / "japidroot" ) ) </code></pre>(optionally, to avoid some warning messages) set the japid root to null explicitly in your global settings file, so the Japid engine will pick up the Japid scripts in the jars.
<pre><code> public class Global extends GlobalSettingsWithJapid { @Override public void onStartJapid() { if (_app.isDev()) setTemplateRoot("japidroot"); else setTemplateRoot((String[])null); // scan class only } } </code></pre>This applies to using Japid in sub-projects settings too.
h2. Using Japid in Sub-projects
In Build.scala, you may have a sub-project defined like this:
<pre><code> val appDependencies = Seq( "japid42" % "japid42_2.10" % "{the version number}" ) val foo = PlayProject("foo", "0.1", appDependencies, path = file("modules/foo")) val main = PlayProject(appName, appVersion, appDependencies).settings( resolvers += Resolver.url("Japid on Github", url("http://branaway.github.io/releases/"))(Resolver.ivyStylePatterns) ).dependsOn(foo) </code></pre>Obviously you have a sub-project located in modules/foo. For the system to know the Japid scripts in the sub-project, you'll need to tell Japid the location, using the JapidRenderer.setTemplateRoot(String...) method, in the global initialization method:
<pre><code> public class Global extends cn.bran.play.GlobalSettingsWithJapid { @Override public void onStartJapid() { setTemplateRoot("japidroot", "modules/foo/japidroot"); } } </code></pre>In the above example, the first argument is the location of the Japid scripts in the parent project. The second argument is the root for the Japid scripts in the sub-project. All paths are relative to the root of the master project.
The @computer-japid@(http://github.com/branaway/computer-japid) sample application demos this feature.
h2. Use Japid Router to replace the Play2 routing mechanism (experimental but quite usable)
Note: version 0.9.5 supports Play 2.1.1 while version 0.9.6+ supports Play 2.1.2, and version 0.9.11 supports Play 2.2.x.
Every typical Play applications come with a route file in the conf directory. The conf file is compiled to multiple scala files when the app is loaded or reloaded.
Two issues with the approach:
Compiling the route file is slow. The multiple scala files derived from the route file take a long time a compile. Any change in the route file triggers this lengthy process which is a productivity killer in development.
Maintaining the route file is annoying. Every time one adds a new method or change the signature of an action method, one must go searching the long routing table in the route file to adjust the mapping properly. Another productivity killer.
The newly introduced Japid Router takes care of these by using some conventions with minimum Annotations.
These are the steps to take advantage of the feature:
- Enable the Japid Router in the global settings:
- Use a few annotations in the controllers:
Note: the Japid routing can actually co-exist with the traditional route file. The Japid router falls back to the default route file in case no route is matched.
The @GET, @POST, @PUT, @DELETE, @HEAD, @OPTIONS, @Path, @PathParam and @QueryParam are standard JAX-RS annotations. But the resemblance to JAX-RS ends there.
h3. The auto-routing convention
When an action method carries no JAX-RS @Path annotation, the routing takes a set of conventional rules:
