To integrate Velocity templates into a Vaadin Web application, you’ll need to follow these steps to combine the two frameworks. This can be particularly useful if you want to use Velocity for templating certain parts of the application, like emails, custom HTML content, or other non-Vaadin UI areas.
Steps to Integrate Velocity with Vaadin
- Add Velocity Dependencies
Ensure you have the Velocity dependency in your project. If you’re using Maven, add the following to yourpom.xml
:<dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.3</version> </dependency>
- Configure the Velocity Engine
Set up aVelocityEngine
bean or an instance in your Vaadin application. Configure it to locate templates and initialize properties.import org.apache.velocity.app.VelocityEngine; import java.util.Properties; public class VelocityConfig { public static VelocityEngine createVelocityEngine() { Properties properties = new Properties(); properties.setProperty("resource.loader", "class"); properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); VelocityEngine velocityEngine = new VelocityEngine(properties); velocityEngine.init(); return velocityEngine; } }
Here, the
ClasspathResourceLoader
allows you to store Velocity templates in theresources
folder of your project. Adjust these settings if you need templates from a different location. - Create Velocity Templates
Add.vm
files (Velocity templates) undersrc/main/resources/templates
(or another directory if you configured it differently). For instance, you could createwelcome.vm
:<div> <h1>Welcome, $name!</h1> <p>Thank you for joining us at $appName.</p> </div>
Note: In this file you need to have only one root element and it must not be <html>. Use anything else – Paragraph, Div, whatever.
- Rendering Velocity Templates in Vaadin
To render Velocity templates, you need to populate aVelocityContext
with data and then merge it with the template. Here’s an example of how to render a template and display the result in a VaadinHtml
:import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.Route; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import java.io.StringWriter; import com.vaadin.flow.component.Html; @Route("welcome") public class WelcomeView extends VerticalLayout { public WelcomeView() { VelocityEngine velocityEngine = VelocityConfig.createVelocityEngine(); VelocityContext context = new VelocityContext(); context.put("name", "Toma"); context.put("appName", "Program Tom . com / Dev"); StringWriter writer = new StringWriter(); velocityEngine.mergeTemplate("templates/welcome.vm", "UTF-8", context, writer); Htmllabel = new Html(writer.toString()); add(label); } }
This example uses a
VelocityContext
to pass data (likename
andappName
) to thewelcome.vm
template, merges the context into the template, and displays the rendered HTML in a VaadinLabel
. - Considerations
- CSS and Styling: Since Velocity renders HTML content, you might want to style it within the
.vm
files, or use Vaadin components and style those if integration with Vaadin’s theming is required. - Error Handling: Handle template errors gracefully, especially if templates are missing or not correctly rendered.
- Caching: Use caching mechanisms for templates if they are frequently used and don’t change often to improve performance.
- CSS and Styling: Since Velocity renders HTML content, you might want to style it within the
By combining Velocity with Vaadin in this way, you can leverage Velocity’s templating capabilities while maintaining the interactive functionality of Vaadin for other parts of your web app.
Could it be used in a Servlet along side the Vaadin App?
Yes, you can use Velocity in a servlet alongside a Vaadin app. This approach is especially useful if you want to generate static or semi-static HTML content, like reports or dynamically generated emails, without involving Vaadin’s component-based UI structure. Here’s how you can set up a Velocity servlet within a Vaadin application:
Create a Servlet or a Spring Boot Controller
Define a servlet to render Velocity templates. The servlet will use a VelocityContext
to populate data and then merge it with the specified template.
import jakarta.annotation.PostConstruct;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.io.IOException;
import java.io.StringWriter;
@Controller
@WebServlet(urlPatterns = "/velocity/*")
public class VelocityServlet extends HttpServlet {
private VelocityEngine velocityEngine;
@Override
public void init() throws ServletException {
super.init();
velocityEngine = VelocityConfig.createVelocityEngine();
}
@PostConstruct
public void initStuff() {
velocityEngine = VelocityConfig.createVelocityEngine();
}
@GetMapping("/velocity/*")
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Create context with data
VelocityContext context = new VelocityContext();
context.put("name", "Toma");
context.put("appName", "Program Tom . Com / LTD");
// Merge template
StringWriter writer = new StringWriter();
velocityEngine.mergeTemplate("templates/welcome.vm", "UTF-8", context, writer);
// Set response type and write output
resp.setContentType("text/html");
resp.getWriter().write(writer.toString());
}
}
In this example:
- The servlet is mapped to
/velocity/*
, allowing you to access it by visitinghttp://localhost:8080/velocity/
. VelocityContext
is used to pass dynamic data to the template.- The merged output is written directly to the servlet response as HTML content.
- Deploying the Servlet Alongside the Vaadin App
In a Vaadin application with a servlet-based backend, Vaadin’s primary servlet (e.g.,VaadinServlet
) handles the UI while your custom servlet (likeVelocityServlet
) can handle Velocity template rendering. Both can coexist in the same application, but make sure they are mapped to different URL patterns to avoid conflicts. - Accessing from the Vaadin App
If you need to link to the servlet or fetch the generated content within the Vaadin application, you can аdd hyperlinks pointing to the/velocity/*
URL.
- Use Cases
This setup is useful for:
-
- Generating static HTML reports or PDFs.
- Creating dynamic email templates or notifications.
- Serving simple HTML content outside of Vaadin’s component model, like terms of service or non-interactive informational pages.
By combining Velocity in a servlet with a Vaadin app, you gain flexibility to generate HTML content both within and outside of the Vaadin UI framework.