Author: Mahendra Rao B
Original post on Foojay: Read More
Hello to all Java and Spring enthusiasts. I am the Java Template Engine, a fresh newcomer to the Spring Initializer Ecosystem.
I have gained popularity as a template engine for developing user interface applications that use Java syntax within Spring Boot applications, alongside other engines such as Freemarker, Thymeleaf, Mustache, and Velocity. Many developers widely use Spring Boot, a framework that simplifies Java application development, and incorporating a template engine like mine streamlines the process of creating dynamic and responsive user interfaces.
Here’s my definition:
The JTE documentation highlights that the Java Template Engine(jte) offers a secure and efficient solution tailored for Java and Kotlin. JTE aims to minimize the introduction of new keywords and uses existing language features, simplifying the understanding of a template’s functionality.
I am pleased to present the following features that I offer:
- I provide simplified and user-friendly syntax.
- You can write plain Java or [Kotlin](https://kotlinlang.org/ “Kotlin”) for expressions.
- The system performs context-aware HTML escaping at compile time.
- The [IntelliJ plugin](https://plugins.jetbrains.com/plugin/14521-jte “IntelliJ plugin”) delivers Intellisense and refactoring capabilities.
- Automatic reloading functionality occurs during the development process.
- I ensure enhanced execution speed. For more details please refer this link
Java Template Engine (JTE) is capable of integrating with various frameworks.
- Spring MVC
- Spring Boot
- Ktor
- Micronaut
- Quarkus
- Javalin
- Eclipse Vert.x
- Severell
- http4k
How will I operate internally?
The respective build tools need to integrate the following dependency in the pom.xml
and build.gradle
. For,
Maven
<dependency> <groupId>gg.jte</groupId> <artifactId>jte</artifactId> <version>3.1.13</version> </dependency>
Gradle
implementation("gg.jte:jte:3.1.13")
To render any template, you must utilize an instance of the gg.jte.TemplateEngine
for an entire application.
import gg.jte.ContentType; import gg.jte.TemplateEngine; import gg.jte.CodeResolver; import gg.jte.resolve.DirectoryCodeResolver; // ... CodeResolver codeResolver = new DirectoryCodeResolver(Path.of("jte")); // This is the directory where your .jte files are located. TemplateEngine templateEngine = TemplateEngine.create(codeResolver, ContentType.Html);
Once we fully initialize the template engine instance, we can begin rendering the template.
import gg.jte.TemplateOutput; import gg.jte.output.StringOutput; // ... TemplateOutput templateOutput = new StringOutput(); templateEngine.render("home.jte", model, templateOutput);
Here, the term templateOutput
indicates where the template renders. We have different template output implementation as follows
gg.jte.output.StringOutput
– generates output in the form of a String.gg.jte.output.FileOutput
– writes content to a designated java.io.File.gg.jte.output.PrintWriterOutput
– outputs to a PrintWriter, for example, the writer obtained from HttpServletRequest.gg.jte.output.WriterOutput
– transmits data to a java.io.Writer.
The model
refers to the data provided to this template, which may be an instance of any class.
Now it’s time for us to get involved with a practical Spring Boot example. To start with
Step1: Access start.spring.io
Step2: Choose project, language, Spring Boot version(preferably released version), project metadata, along with Java version
Step3: Under dependency selection, please add both Web
and JTE
(Template Engines) dependencies.
Step4: And then you generate and download the project
pom.xml
looks like this
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.bsmlabs</groupId> <artifactId>spring-boot-jte</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-jte</name> <description>Spring Boot Project with Java Template Engine</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>23</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>gg.jte</groupId> <artifactId>jte</artifactId> <version>3.1.13</version> </dependency> <dependency> <groupId>gg.jte</groupId> <artifactId>jte-spring-boot-starter-3</artifactId> <version>3.1.13</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>gg.jte</groupId> <artifactId>jte-maven-plugin</artifactId> <version>3.1.13</version> <executions> <execution> <id>jte-generate</id> <phase>generate-sources</phase> <goals> <goal>generate</goal> </goals> <configuration> <sourceDirectory>${project.basedir}/src/main/jte</sourceDirectory> <contentType>Html</contentType> <binaryStaticContent>true</binaryStaticContent> <targetResourceDirectory>${project.build.outputDirectory}</targetResourceDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Unzip the project and import into IntelliJ /Eclipse IDE
Let’s create a simple controller called IndexController and create Page Layout with instance fields
package com.bsmlabs.jte; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @Controller public class IndexController { @GetMapping("/") public String getIndex(Model model) { model.addAttribute("name", "Welcome To Java Template Engine"); model.addAttribute("page", new Page("Hello JTE", "JTE Application")); return "index"; } }
package com.bsmlabs.jte; public record Page(String title, String description) { }
The next step involves creating a template index.jte within the /src/main/jte folder, a directory that is established during the generation process at start.spring.io.
@import com.bsmlabs.jte.Page @param String name @param Page page <!DOCTYPE html> <html lang="en"> <head> <title>${page.title()}</title> @if(page.description() != null) <meta name="description" content="${page.description()}"> @endif <script src="https://cdn.tailwindcss.com"></script> </head> <body> <nav class="bg-gray-800"> <div class="hidden sm:ml-6 sm:block"> <div class="flex space-x-4"> <a href="#" class="rounded-md bg-gray-900 px-3 py-2 text-sm font-medium text-white" aria-current="page">Dashboard</a> <a href="#" class="rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Blog</a> <a href="#" class="rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">Projects</a> </div> </div> </nav> <p class="text-slate-700 dark:text-slate-500 font-medium">${name}!</p> </body> </html>
- The directive @import corresponds directly to Java imports in this context, thereby ensuring that
com.bsmlabs.jte.Page
is recognized by the template. - The parameter required for this template is the Page object i.e.,
@param Page page
- The @if/@endif construct represents an if-block. The content within the parentheses (page.getDescription() != null) consists of standard Java code.
${}
used for writing the template output inside the expression.
Inside application.properties
we will add the following properties
# When developmentMode is set to true, the jte file watcher will monitor template changes and recompile them accordingly. gg.jte.development-mode=true spring.application.name=spring-boot-jte # By default template files are available in /src/main/jte gg.jte.templateLocation=src/main/jte # with templateSuffix as .jte gg.jte.templateSuffix=.jte
As we are developing with Spring Boot and incorporating the spring-boot-starter-web starter
, both org.springframework.web.servlet.ViewResolver
and templateEngine will be automatically configured.
Conclusion
By integrating the Java Template Engine (JTE) into various frameworks, one can experience a novel approach that provides significant benefits, including superior performance, increased concurrency, and quicker template rendering.
The complete code can be found over on Github.
References
Dan Vega Youtube link: https://www.youtube.com/watch?v=KoWgHSWA1cc
The post Spring Boot: Java Template Engine (JTE) appeared first on foojay.