0
votes

I am about to re-write a web-platform, and I am using Spring Boot/Spring MVC. A major part of the platform is the website. I am struggling deciding which template-engine to use. Thymeleaf seems to be recommended, while JSP discouraged. I am not sure if my requirements are unusual, at least they do not sound like that to me:

  • I do not want to repeat myself in the different templates, they should all be displayed inside a "master template/layout"
  • The master template/layout will have navigation and footer, which have dynamic content (eg. it is not only the main content that is dynamic)

1) With Thymeleaf, from what I have been able to understand, using Layouts would be the recommended (only?) approach. However, it looks to me like all dynamic content much still be generated in each template (where it flows into the layout using the layout:fragment attribute). This sounds less than ideal, as it would mean I would still have to generate the dynamic part of the layout in each template. Is there no way to include dynamic content in Thymeleaf layouts, where the content (menu, footer, twitter-feed etc) is generated separately from the actual content-template?

2) JSP seems to be able to solve this rather easily, using a custom tag for the layout, that has <jsp:include> -tags for the dynamic content and a <jsp:doBody> -tag for the actual content-template. However, from reading the Spring Boot documentation, I somehow got the impression that it is encouraged to use a different template-engine that JSP. The approach described above would however let me define a header.jsp, navigation.jsp, footer.jsp and twitterFeed.jsp that generates the content dynamically (based on database content, logged in user etc), while the actual content-template purely focuses on the content to display. Is there something I am missing in my comparison between Thymeleaf and JSP here, why would I not chose JSP as my project's template engine?

3) With the approach meantioned in 2), would I be limited to putting all my Java logic in the JSPs for the templates included in the main layout (header, navigation, footer, twitter-feed), or is there a better way to back these stubs up with a controller-like class?

4) Are there any other template engines that integrate well with Spring MVC / Spring Boot, that would be a better choice that any of the above mentioned ones?

1
Don't use JSP. It's not a template engine. It's a horrendous hangover from worse times. The JSP gets compiled into Java code and that gets deployed as a separate servlet - requests then get forwarded to it. To be honest, I completely fail to understand your concerns, or comprehend what you mean by "all dynamic content much still be generated in each template". I am not sure if you are confusing server side templating with a something like AJAX - but the two are far from equivalent.Boris the Spider
My concern with the Thymeleaf-approach is that according to github.com/ultraq/thymeleaf-layout-dialect/blob/master/Docs/… it looks to me like i would have to define in each child-template how the parent-template should render the menu, the twitter-feed, the footer etc - regardless if the child-template is home.html, login.html, content.html, blogpost.html etc. I am not an advocate of JSP, I am aware of its history and shortcomings (and even that Spring Boot kind of discourages the use of it). I just need to be convinced that Thymeleaf (or any other) can do the job.kvitso

1 Answers

3
votes

Use can use Thymeleaf Ultraq Layout to create a base template which will act as a decorator for your other templates as shown below:

base-template.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>

  <title layout:title-pattern="$CONTENT_TITLE - $LAYOUT_TITLE">Sample</title>
  <meta name="description" content=""/>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <!-- all CSS links here -->
</head>


<body>
<div class="container">
  <div class="content">
    <div layout:fragment="page_content">
      <!-- Content from other pages which decorate using this template -->
    </div>
  </div>
</div>

<!-- /.container -->
<!-- All script tags here -->

<th:block layout:fragment="scripts">
  <!-- If you have any page specific scripts -->
</th:block>
</body>
</html>

Then the other pages will use the above template as a decorator as shown below:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{base-template}">

<head>
  <title>This page title</title>
</head>

<div layout:fragment="page_content">
  <!-- content for this page -->
</div>

<th:block layout:fragment="scripts">
  <!-- add any scripts related to this page -->
</th:block>
</html>

The syntax ~{base-template} is used with Thymeleaf 3 onward.

You can proceed with the above approach and not repeat the navigations, headers and footers on your other pages.