Module definition
module.xml
<?xml version="1.0"?>
<module name="sample2" root-type="sample2" path="/sample2">
<nature>groovy</nature>
</module>
JAX-RS resources
Sample2.groovy
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import org.nuxeo.ecm.webengine.model.impl.*;
import org.nuxeo.ecm.webengine.model.*;
/**
* Templates sample.
*
* This demonstrates how to use template files to build client responses.
* JAX-RS provides a flexible mechanism to send responses based on the mime type that the client expects.
* To send a response to the client you simply return the Object you want as the response.
* JAX-RS engines will usually know how to render common Java objects like String, InputStream, File etc.
* If you need to output specific objects you need to register a custom MessageBodyWriter class.
* In JAX-RS you are not able to modify the HttpServletResponse object directly from a resource method. (add headers, cookies etc)
* Anything you may want to output must be returned from the resource method back to JAX-RS engine, and the engine will output it for you.
* This is a very good thing, even if for some people this approach may seem strange.
* You may ask yourself, ok cool, The response rendering is pretty well separated from the resource logic.
* But how can I modify response headers?
* In that case you must return a javax.ws.rs.Response that may be used to customize your response headers.
*
<p>
* WebEngine is adding a new type of response objects: templates.
* Templates are freemarker based templates that can be used to render your objects depending on the request context.
* WebEngine is adding some cool extensions to freemarker templates that let you build your web site in a modular fashion.
* These extensions are called blocks. Blocks are dynamic template parts that can be extended or replaced using derived blocks.
* Using blocks, you can write a base template that may define the site layout (using blocks containing empty or generic content) and then
* write final <i>skins</i> for your layout by extending the base template and redefining blocks you are interested in.
* See the <i>skin</i> directory for template examples.
*
<p>
* Templates are stored in files under the <i>skin</i> directory. Templates are always resolved relative to the <i>skin</i> directory,
* even if you are using absolute paths.
* The following variables are accessible from a template when rendered at rendering time:
*
<ul>
*
<li> <code>Context</code> - the WebContext instance
*
<li> <code>Engine</code> - the WebEngine instance
*
<li> <code>This</code> - the target Web Object.
*
<li> <code>Root</code> - the root WebObject.
*
<li> <code>Document</code> - the target Document if any otherwise null.
*
<li> <code>Session</code> - the Repository Session. (aka Core Session)
*
<li> <code>basePath</code> - the request base path (context path + servlet path)
* </ul>
* To render a template as a response you need to instantiate it and then return it from the resource method.
* The template will be processed by the corresponding MessageBodyWriter and rendered on the client stream.
*
* @author <a href="mailto:[email protected]">Bogdan Stefanescu</a>
*/
@WebObject(type="sample2")
@Produces(["text/html"])
public class Sample2 extends ModuleRoot {
@GET
public Object doGet() {
return "Sample2: Hello World!";
}
/**
* Return the template index.ftl from 'skin' directory
*/
@GET
@Path("index1")
public Object getIndex1() {
return getTemplate("index1.ftl");
}
/**
* Inject the variable 'name' in the template context and then return the template.
*/
@GET
@Path("index1/{name}")
public Object getIndex1(@PathParam("name") String name) {
return getTemplate("index1.ftl").arg("name", name);
}
/**
* Render the index2 template
*/
@GET
@Path("index2")
public Object getIndex2() {
return getTemplate("index2.ftl");
}
/**
* Example of using redirect.
* The redirect method inherited from DefaultModule is returning a Response object that is doing a redirect
*/
@GET
@Path("redirect/{whereToRedirect}")
public Response doRedirect(@PathParam("whereToRedirect") String path) {
return redirect(ctx.getModulePath() + "/"+ path);
}
/**
* Example of using a Response object.
* This method is sending a 403 HTTP error.
*/
@GET
@Path("error/{errorCode}")
public Response sendError(@PathParam("errorCode") String errorCode) {
try {
int statusCode = Integer.parseInt(errorCode);
Response.Status status = Response.Status.fromStatusCode(statusCode);
if (status != null) {
return Response.status(status).build();
}
} catch (Exception e) {
}
return Response.status(500).entity("Invalid error code: " + errorCode).build();
}
}
Object views
skin/base.ftl
<!-- Base template that defines the site layout -->
<html>
<head>
<title><@block name="title"/></title>
</head>
<body>
<table width="100%" border="1">
<tr>
<td><@block name="header">Header</@block></td>
</tr>
<tr>
<td><@block name="content">Content</@block></td>
</tr>
<tr>
<td><@block name="footer">Footer</@block></td>
</tr>
</table>
</body>
</html>
skin/index1.ftl
<@extends src="base.ftl">
<@block name="title">Index 2</@block>
<@block name="header">
<#if name>
Hello ${name}!
<#else>
Hello World!
</#if>
</@block>
<@block name="content">
This is the <i>index1</i> skin.
</@block>
<@block name="footer">
The footer here ...
</@block>
</@extends>
skin/index2.ftl
<@extends src="base.ftl">
<@block name="title">Index 2</@block>
<@block name="content">
This is the <i>index2</i> skin.
</@block>
</@extends>