Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

The Joy of Mustache: Server Side Templates for the JVM

DZone's Guide to

The Joy of Mustache: Server Side Templates for the JVM

Here are a few server side templates you can use for JVMs. See how Mustache can make your life a bit easier for you and, by extension, your users.

· Java Zone
Free Resource

Learn how our document data model can map directly to how you program your app, and native database features like secondary indexes, geospatial and text search give you full access to your data. Brought to you in partnership with MongoDB.

You can load a home page and log into your application using a form. The user can’t yet log out, so you probably want to add that feature, ideally as a link on all pages, so that makes it part of the layout. To show how that works, let’s add a generic, declarative menu bar to the application, and make one part of it a logout button.

The logout link is actually pretty easy. We only need a form with the CSRF token and a link to submit it, e.g:

Layout.html

<!doctype html>
<html lang="en">
<head>
  <title>{{{layout.title}}}</title>
</head>
<body>
  <form id="logout" action="/logout" method="post">
    <input type="hidden" name="_csrf" value="{{_csrf.token}}" />
    <button type="submit" class="btn btn-primary">Logout</button>
  </form>
  {{{layout.body}}}
</body>
</html>

That already should work. But lets incorporate the logout into a more generic set of menu links. A list of elements in HTML can be represented as a <ul/> with nested <li/>, so the menus for your application can be rendered that way. In Mustache you do iteration just like lambdas, using a tag, so let’s invent a new one called {{#menus}}:

Layout.html

<!doctype html>
<html lang="en">
<head>
  <title>{{{layout.title}}}</title>
</head>
<body>
  <ul class="nav nav-pills" role="tablist">
    {{#menus}}<li><a href="{{path}}">{{name}}</a></li>{{/menus}}
    <li><a href="#" onclick="document.getElementById('#logout').submit()">Logout</a></li>
  </ul>
  {{{layout.body}}}
  <form id="logout" action="/logout" method="post">
    <input type="hidden" name="_csrf" value="{{_csrf.token}}" />
  </form>
</body>
</html>

Notice that inside the {{#menus}} tag we pull out variables, "name" and "path" using the normal Mustache syntax.

Now you have to define the tag in your controller advice (or equivalently in the controllers), so that "menus" resolves to an iterable:

LayoutAdvice.java

@ModelAttribute("menus")
public Iterable<Menu> menus() {
  return application.getMenus();
}

So this new code introduced a Menu type that contains the static content for each menu in the UI. The layout calls for "name" and "path", so you need those properties:

Menu.java

class Menu {
  private String name;
  private String path;
  // ... getters and setters
}

In the layout advice above, the menus came from an application object. That wasn’t strictly necessary: you could have declared the list of menus inline in the menus() method, but extracting it into another object gives us the chance to use a nice Spring Boot feature, where we can declare the menus in a config file in a compact format.

So now you need to create the Application object to hold the menus, and inject it into the layout advice:

Layout.java

private Application application;

@Autowired
public LayoutAdvice(Compiler compiler, Application application) {
  this.compiler = compiler;
  this.application = application;
}

Where in Application you have something like this

Application.java

@Component
@ConfigurationProperties("app")
class Application {
  private List<Menu> menus = new ArrayList<>();
  // .. getters and setters
}

The @ConfigurationProperties tells Spring Boot to bind to this bean from the environment. Switching from application.properties to application.yml you could create a "Home" and a "Login" menu like this:

Application.yml

app.menus:
  - name: Home
    path: /
  - name: Login
    path: /login

With this in place, the "layout.html" that you already defined now has all it needs to work.

The sample code is tagged with "menus" at this point in GitHub, if you want to check it out and compare notes. It’s also the final state, so it’s the same code in master, possibly with bug fixes and updates to libraries. I hope you enjoy using Mustache as much as I do.

Discover when your data grows or your application performance demands increase, MongoDB Atlas allows you to scale out your deployment with an automated sharding process that ensures zero application downtime. Brought to you in partnership with MongoDB.

Topics:
mustache ,spring ,java ,jvm

Published at DZone with permission of Dave Syer. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}