Skip to content

Instantly share code, notes, and snippets.

@theotherian
Last active December 24, 2015 04:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theotherian/6746967 to your computer and use it in GitHub Desktop.
Save theotherian/6746967 to your computer and use it in GitHub Desktop.
A way to map Handlebars helper functions on the server side within a Jersey resource
A way to map Handlebars helper functions on the server side within a Jersey resource
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.github.jknack.handlebars.Template;
@Path("desktop")
public class DesktopView {
@GET
@Produces(MediaType.TEXT_HTML)
public Response get() throws IOException, InterruptedException, ExecutionException {
Template template = HandlebarsManager.get().compile("home");
return Response.ok(template.apply(new Args("Ian", "Denny", "Chris"))).build();
}
}
import javax.ws.rs.Path;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import org.apache.log4j.Logger;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Helper;
public class HandlebarsResourceFeature implements DynamicFeature {
private final Logger logger = Logger.getLogger(getClass());
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (Helper.class.isAssignableFrom(resourceInfo.getResourceClass())) {
Class<?> resourceClass = resourceInfo.getResourceClass();
String helperName = resourceClass.getAnnotation(Path.class).value();
// HandlebarsManager exists in the project linked at the end of this post.
Handlebars handlebars = HandlebarsManager.get();
if (handlebars.helper(helperName) == null) {
Helper<?> helper = null;
try {
helper = resourceInfo.getResourceClass().asSubclass(Helper.class).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
logger.fatal("Can't instantiate " + resourceClass.getCanonicalName(), e);
}
if (helper != null) {
handlebars.registerHelper(helperName, helper);
}
else {
logger.info("Not registering " + helperName + " a second time; already registered previously");
}
}
}
}
}
<html>
<head>
<title>Home Page</title>
</head>
<body>
<h1>Welcome to the site!</h1>
<p>Here are the latest messages:</p>
{{#each names}}
<ul>
<li>
<h2>Messages from {{this}}</h2>
{{#latestmessages this}}
{{> messages this}}
{{/latestmessages}}
</li>
</ul>
{{/each}}
</body>
</html>
<html>
<head>
<title>Mobile Home Page</title>
<script src="/handlebars.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript">
{{#precompile "messages"}}{{/precompile}}
</script>
</head>
<body>
<h1>Welcome to the mobile site!</h1>
<h4>Click on a name to see messages</h4>
{{#each names}}
<div class="message-container-{{this}}">
<p><a class="message-link" id="{{this}}" href="#">{{this}}</a></p>
</div>
{{/each}}
<script type="text/javascript">
$(document).ready(function bindAll() {
$('.message-link').bind('click', event, function showMessages() {
var name = event.target.id;
var messageList = '#message-list-' + name;
if ($(messageList).length) {
if ($(messageList).is(':visible')) {
return;
}
else {
$('.message-list').hide();
$(messageList).show();
return;
}
}
else {
$('.message-list').hide();
}
// here's the important bit involving calling the resource
var messageTemplate = Handlebars.templates['messages'];
$.get('latestmessages/' + name).done( function(data) {
var html = messageTemplate(data);
$('.message-container-' + name).append('<div id="message-list-' + name + '" class="message-list">');
$(messageList).append(html);
});
});
});
</script>
</body>
</html>
import java.io.IOException;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.github.jknack.handlebars.Helper;
import com.github.jknack.handlebars.Options;
@Path("latestmessages")
public class MessageResource implements Helper<String> {
@GET
@Path("{name}")
@Produces(MediaType.APPLICATION_JSON)
public List<Message> get(@PathParam("name") String name) {
return getMessages(name);
}
private List<Message> getMessages(String name) {
// MessageDatastore exists in the project linked at the end of this post
return MessageDatastore.getMessagesByName(name);
}
@Override
public CharSequence apply(String context, Options options) throws IOException {
return options.fn(getMessages(context));
}
}
<ul>
{{#each this}}
<li>{{text}} <span style="font-size: x-small;">{{when}}</span></li>
{{/each}}
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment