Thymeleaf ViewComponent with Java and Maven
Huge shoutout to @wimdeblauwe he helped me to get the library working with java and maven. Go and checkout his book Taming Thymeleaf
Creating a ViewComponent⌗
We just need to add the @ViewComponent annotation to a class and define a render() method that returns a ViewContext. We can pass the properties we want to use in our template.
// HomeViewComponent.java
@ViewComponent
public class HomeViewComponent {
private final ExampleService exampleService;
public HomeViewComponent(ExampleService exampleService) {
this.exampleService = exampleService;
}
public ViewContext render() {
return new ViewContext(
ViewProperty.of("helloWorld", "Hello World"),
ViewProperty.of("coffee", exampleService.getCoffee())
);
}
}
Next we define the HTML in the HomeViewComponent.html in the same package as our ViewComponent Class.
// HomeViewComponent.html
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:text="${helloWorld}"></div>
<br>
<strong th:text="${coffee}"></strong>
</body>
</html>
We can then call the render method in our Controller
// Router.java
@Controller
public class Router {
private final HomeViewComponent HomeViewComponent;
public Router(HomeViewComponent HomeViewComponent) {
this.HomeViewComponent = HomeViewComponent;
}
@GetMapping("/")
ViewContext homeView(){
return HomeViewComponent.render();
}
}
If we now access the root url path of our spring application we can see that the component renders properly:
Nesting components:⌗
We can also embed components to our templates with the attribute view:component="componentName"
.
<div view:component="navigationViewComponent"></div>
When our render method has parameters we can pass them by using the .render(parameter)
method.
<div view:component="parameterViewComponent.render('Hello World')"></div>
Parameter components:⌗
We can also create components with parameters. We can either use default values when we pass a null value, get a property from a Service or we can throw a custom error.
@ViewComponent
public class ParameterViewComponent {
public ViewContext render(String parameter) throws Exception {
if (parameter == null) {
throw new Exception("You need to pass in a parameter");
}
return new ViewContext(
ViewProperty.of("office", parameter)
);
}
}
// ParameterViewComponent.html
<h2>ParameterComponent:</h2>
<div th:text="${office}"></div>
This enables us to define the properties for our ParameterViewComponent in the HomeViewComponent:
// HomeViewComponent.java
@ViewComponent
public class HomeViewComponent {
private final ExampleService exampleService;
public HomeViewComponent(ExampleService exampleService) {
this.exampleService = exampleService;
}
public ViewContext render() {
return new ViewContext(
ViewProperty.of("helloWorld", "Hello World"),
ViewProperty.of("coffee", exampleService.getCoffee()),
ViewProperty.of("office", exampleService.getOfficeHours())
);
}
}
// HomeViewComponent.html
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<body>
<div th:text="${helloWorld}"></div>
<div view:component="parameterViewComponent.render(office,null)"></div>
</body>
</html>
If we now access the root url path of our spring application we can see that the parameter component renders properly:
Maven Installation⌗
Add this to your pom.xml:
<project>
<dependencies>
<dependency>
<groupId>de.github.tschuehly</groupId>
<artifactId>thymeleaf-view-component</artifactId>
<version>0.3.1</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.html</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>Jitpack</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
</project>