text: .
  I want to show you what a neat little tool JMustache is for server side rendering of HTML (or anything else in plain text come to that). I always liked Mustache because of its simplicity - it’s "just enough" templating - and you really couldn’t wish for a cleaner, leaner, more lightweight library than this one, if you have to render templates in the JVM. There is one jar file with no dependencies, and it adds 78kb to your classpath, which isn’t going to hurt anyone, and will put a smile on many faces. It has very few features, which is excellent for people who can’t remember syntax, and the manual is short, comprehensive, readable, and useful.
  If you carry on reading, as we build up a sample application, you will see how to build HTML pages with Mustache, rendering static and dynamic content, building forms and menus, and abstracting the layout of the pages into separate components. The simplicity of Mustache shines through, and guides you to put logic in Java, keeping the templates as clean as possible. As a sidebar you will see how to secure an application with a custom login form in a slightly unusual but interesting way.
  Sample Code
  There is some sample code following the text in GitHub. It is a tiny Spring MVC application, also using Spring Security. If you want to see it develop in stages along with the text, you can use some tags:
  "base" is a starting point with a working application
  "includes" creates a re-usable layout using a header and a footer
  "layout" is a slightly more advanced implementation using a Mustache lambda
  "menus" adds some more UI elements using more Spring Boot and Mustache features
  At every stage you can checkout the tag and run the app. There is a Maven wrapper in the root of the project, so you can build and run it from the command line, e.g.
  $ git clone $ cd mustache-sample $ git checkout base $ ./mvnw spring-boot:run
  Instead of running from the command line you can import the project
  into your favourite IDE and run the main method in the
  DemoApplication.
  The app runs on, and you can authenticate with any username and password (even empty!). There are no real features in the sample app, but it does have login and logout and a home page, to provide some hooks to show the templating features.
  Getting Started
  Spring Boot has
  autoconfiguration support for JMustache, so it is easy to get up and
  running with a Spring MVC application. You could generate a project
  from the Spring Initializr, and ask it for
  spring-boot-starter-mustache.
  Spring Boot automatically configures a
  ViewResolver for JMustache,
  so you can implement a home page by providing a controller that
  returns a view name, e.g.
  @Controller class HomeController { @GetMapping("/") String home() { return "index"; } }
  With this controller, when the user visits the home page ("/") Spring
  will render a template at
  classpath:/templates/index.html, which
  means in the directory
  src/main/resources/templates in your
  project. For example you could drop this in and confirm that it works:
  <!doctype html> <html lang="en"> <body> <h1>Demo</h1> <div>Hello World</div> </body> </html>
  Make the Application Secure
  There’s no dynamic (templated) content there yet. Let’s make the app
  secure and add a login form, at which point you will need the dynamic
  content. So add
  spring-cloud-starter-security to your dependencies
  and the home page will be automatically protected. Suppose you
  want to have a login form at "/login", so you’ll need the controller:
  @Controller @RequestMapping("/login") class LoginController { @GetMapping public String form() { return "login"; } }
  You will also need some basic security configuration, which you can add as a method in the main application, if you extend a base class from Spring Security:
  @SpringBootApplication public class DemoApplication extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login", "/error").permitAll() .antMatchers("/**").authenticated() .and().exceptionHandling() .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")); } }
  Custom Authentication Processing with Spring MVC
  Spring Security implements form login (and everything else really)
  using a
  Filter, so that’s what you would get with the built in
  formLogin() configuration. Just to make things interesting, you are
  going to do the authentication in a Spring MVC handler, enabling you
  to add some custom logic, and MVC is easier to work with than
  filters.
  So let’s extend the
  LoginController with a method to handle
  username/password authentication (it is easy to extend to more
  complicated logic). The main thing it needs to do is validate the
  input and if it is a real user, populate the
  SecurityContext:
  @PostMapping public void authenticate(@RequestParam Map<String, String> map) throws Exception { Authentication result = new UsernamePasswordAuthenticationToken( map.get("username"), "N/A", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); SecurityContextHolder.getContext().setAuthentication(result); }
  To mimic the behaviour of the built-in Spring Security login form, you
  also need to be able to redirect to a "saved request" that the user
  tried to access before login. Spring Security has an
  AuthenticationSuccessHandler abstraction for that, and a simple
  implementation that knows about the saved request. So the
  authenticate method can use that (it needs the servlet request and
  response, which you can add those as method parameters, and Spring MVC
  will inject them):
  private AuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler(); @PostMapping public void authenticate(@RequestParam Map<String, String> map, HttpServletRequest request, HttpServletResponse response) throws Exception { // ... authenticate user from request parameters handler.onAuthenticationSuccess(request, response, result); }
  The Login Form
  Now you are ready to accept authentication requests, you need a form for
  users to fill in and submit. The
  LoginController renders the "login"
  template, so you need to add a "login.html" to your templates
  folder. For example:
  <!doctype html> <html lang="en"> <body> <h1>Login</h1> <form action="/login" method="post"> (1) <label for="username">Username:</label> <input type="text" name="username" /> (2) <label for="password">Password:</label> <input type="password" name="password" /> (3) <input type="hidden" name="_csrf" value="{{_csrf.token}}" /> (4) <button type="submit" class="btn btn-primary">Submit</button> </form> </body> </html>
  a form, with a submit button to send the contents to "POST /login"
  username field input
  password field input
  CSRF token, in the format required by Spring Security.
  The CSRF token is your first piece of dynamic content, and it shows
  you how Mustache works, and incidentally why it is called
  "Mustache". Variables from the "context" (in this case the Spring MVC
  model object) can be rendered using double braces, or "mustaches"
  (
  {{ and
  }}). JMustache also navigates the object graph inside
  variables, so
  _csrf.token resolves as the "token" property of the
  "_csrf" object.
  Spring Security puts the "_csrf" object into request attributes. To
  get it copied to the MVC model you need a setting in your
  application.properties:
  spring.mustache.expose-request-attributes=true
  With all that in place, you should find that on visiting the application in a browser will first redirect to "/login". Because of the weak (non-existent) authentication logic in your handler, you can put anything you like in the form and submit it to see the home page.
  The sample code has a "base" tag which is an application with all the features we have seen so far.
  Layout Abstractions: Using Includes
  There are only 2 pages in our application, but even with such a small code base there is going to be a quite a bit of duplication in the HTML. It is useful to extract some common elements of all pages into re-usable templates. One way to do this is with "includes". So we could extract the top matter and bottom matter into "header.html":
  <!doctype html> <html lang="en"> <body>
  and "footer.html"
  </body> </html>
  (These are intentionally trivial examples. In a real app they would probably have a lot of stylesheets, scripts, and meta tags.)
  With those templates we can re-write the home page:
  {{>header}} <h1>Demo</h1> <div>Hello World</div> {{>footer}}
  and the login form would look similar (just the body of the HTML). In these examples you can see the Mustache syntax for "includes", which is a bit like a variable, but with an extra ">" in the opening tag. The name of the template is resolved in the same way as the view templates (so "footer" is mapped to "footer.html" in the "templates" directory).
  "Natural" Templates
  Some people like to use HTML templates that render on their own and can be viewed in a browser. It’s kind of neat to be able to edit the templates and be able to see the result independent of any server or application logic. Mustache isn’t a perfect language for such "natural" templates, but it does have one feature that you can use to get something approximating it. That feature is "comments".
  So, for example, you could add a static header and footer to your home
  page template, so that it renders in the browser (almost) as if it was
  in the application. Just surround the static content with Mustache
  comment tags (
  {{! and
  }}). For example:
  {{! <!doctype html> <html lang="en"> <body> }} {{>header}} <h1>Demo</h1> <div>Hello World</div> {{>footer}} {{! </body> </html> }}
  The browser will still render the Mustache tags as literal braces, but you can squint and ignore those, and the rest of the content will be layed out exactly as it would be in the application. Obviously, with such basic content there isn’t a huge benefit, but when the content is more complex and has styling and scripts it might make more sense.
  The sample code has a tag in GitHub called "includes", which is an application with all the features we have seen so far.
  Layout Abstractions: Using a Lambda
  Some people will be perfectly happy with a header and a footer in
  separate templates, but others will moan. To be honest it does feel a
  little awkward to be laying out hierarchical content (HTML), and be
  forced to break elements (like the
  <body> tag in the sample) across
  multiple files. It would be nicer if we could control the layout in a
  single file, something like this:
  <!doctype html> <html lang="en"> <body> {{{layout.body}}} </body> </html>
  and then somehow generate the "body" content in our home page and login page.
  Mustache allows you to insert generic "executable" content into your templates. This is a really powerful feature, and you can use it to extract the layout into its own template, as well as to do other things that involve a bit of logic. The syntax for that is a generic Mustache tag that resolves to something executable. The home page would look something like this:
  {{#layout}} <h1>Demo</h1> <div>Hello World</div>\ {{/layout}}
  To make this work you first need an object called "layout" of type
  Mustache.Lambda in our MVC model. You could do this in your
  controller methods, or (better) use a
  @ControllerAdvice to add model
  attributes to all views. For example:
  @ControllerAdvice class LayoutAdvice { @ModelAttribute("layout") public Mustache.Lambda layout() { return new Layout(); } } class Layout implements Mustache.Lambda { String body; @Override public void execute(Fragment frag, Writer out) throws IOException { body = frag.execute(); } }
  Notice that the "layout" attribute renders its body using
  Fragment.execute() and assigns it to a property called "body", which
  can be referenced as a variable in Mustache. The "layout.html"
  template already contains the code to pull in the body,
  {{{layout.body}}}, so all that remains is to actually render the
  layout (so far we have only rendered the body). We can do this, in a
  first pass, by importing the layout explicitly into the home
  page:
  {{#layout}} <h1>Demo</h1> <div>Hello World</div>\ {{/layout}} {{>layout}}
  Do the same with the login template:
  {{#layout}} <h1>Login</h1> <form action="/login" method="post"> <label for="username">Username:</label> <input type="text" name="username" /> <label for="password">Password:</label> <input type="password" name="password" /> <input type="hidden" name="_csrf" value="{{_csrf.token}}" /> <button type="submit" class="btn btn-primary">Submit</button> </form> {{/layout}} {{>layout}}
  and you are good to go. Everything works, and the app shows the login page and home page with the same layout.
  Rendering the Layout in the Lambda
  To remove the need for the explicit
  {{>layout}} include in every
  page that uses
  {{#layout}}, you can do that part inside the
  lambda. You’ll need a reference to the Mustache compiler, and then you
  just need to compile a template which includes the layout and execute
  it:
  class Layout implements Mustache.Lambda { String body; private Compiler compiler; public Layout(Compiler compiler) { this.compiler = compiler; } @Override public void execute(Fragment frag, Writer out) throws IOException { body = frag.execute(); compiler.compile("{{>layout}}").execute(frag.context(), out); } }
  The compiler is wired into the
  Layout in its constructor, and it can
  be injected into the controller advice using
  @Autowired:
  @ControllerAdvice class LayoutAdvice { private final Mustache.Compiler compiler; @Autowired public LayoutAdvice(Compiler compiler) { this.compiler = compiler; } @ModelAttribute("layout") public Mustache.Lambda layout(Map<String, Object> model) { return new Layout(compiler); } }
  That’s it. You can remove the include from the view templates. E.g. this works for the home page:
  {{#layout}} <h1>Demo</h1> <div>Hello World</div>\ {{/layout}}
  The last line of the old version of the template has effectively been
  moved into the
  Layout lambda.
  More Dynamic Content
  It’s quite common for layout templates like the one that we are developing to have content that varies between uses. For instance you might want the "title" on the home page to be different to that on the login page, but it is part of the HTML header, not the body, so logically it is part of the layout. Let’s make that explicit, by adding the title to the header of the layout:
  <!doctype html> <html lang="en"> <head> <title>{{{layout.title}}}</title> </head> <body> {{{layout.body}}} </body> </html>
  This is a strong hint about how you can implement this feature: the layout has a new property called "title", and you can give it a default value in the class declaration:
  class Layout implements Mustache.Lambda { String body; String title = "Demo Application"; ... }
  Now, all that remains is to populate that property. Logically, setting the title is part of the page view, not the layout, so you’d like to set it in the same place you declare the rest of the page content. Other template languages have "parameterised fragments", but Mustache is too minimalistic for that. The minimalism is a feature, and actually it leads to quite an elegant solution to this problem.
  All you have is tags, so you might want to do something like this:
  {{#layout}}{{#title}}Home Page{{/title}} <h1>Demo</h1> <div>Hello World</div>\ {{/layout}}
  That looks like it might work. All you need to do is provide a lambda to capture the title. In the layout advice you can do this:
  @ControllerAdvice class LayoutAdvice { ... @ModelAttribute("title") public Mustache.Lambda defaults(@ModelAttribute Layout layout) { return (frag, out) -> { layout.title = frag.execute(); }; } }
  and as long as the call to
  {{#title}} is nested inside the call to
  {{#layout}} everything will work out just fine. You cleaned up your
  templates and moved a tiny piece of logic to Java, where it belongs.
  The sample code is tagged with "layout" at this point, if you want to check it out and compare notes.
  Logout: Menus and Spring Boot Configuration:
  @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::
  private Application application; @Autowired public LayoutAdvice(Compiler compiler, Application application) { this.compiler = compiler; this.application = application; }
  where in
  Application you have something like this
  .
  Footnote
  The sample has one or two extra features on top of the code in the
  text. One of which is that the "active" menu is rendered differently
  to the others using a CSS style. For that to work, you need to add a
  flag to the
  Menu and reset it in the layout advice. The logic is
  natural and easy to add to the advice. Another is that the title for
  the page is part of the menu definition instead of being a separate
  lambda.