# Java Template Engine \[JTE]

The Java Template Engine (jte) is a secure and lightweight template engine designed for Java and Kotlin applications. It emphasizes minimal syntax, leveraging existing language features to make templates intuitive and maintainable.

{% hint style="info" %}
for more info visit official doc - [https://jte.gg](https://jte.gg/syntax/)
{% endhint %}

### Some of the features of JTE -

1. **Performance**: JTE compiles templates to Java bytecode, resulting in efficient runtime execution.
2. **Compile-time checking**: Catch errors at compile time rather than runtime.
3. **Lightweight**: Minimal overhead and dependencies.
4. **Hot reloading**: See changes immediately without restarting your application.
5. **Pre-compilation**: Improve startup times by pre-compiling templates.

### Integrating jte into a Spring Boot Application

1. Create spring boot project with web starter.
2. add the following dependency to use jte

```xml
 <dependency>
      <groupId>gg.jte</groupId>
      <artifactId>jte</artifactId>
      <version>3.1.12</version>
 </dependency>
<dependency>
      <groupId>gg.jte</groupId>
      <artifactId>jte-spring-boot-starter-3</artifactId>
      <version>3.1.12</version>
</dependency>
```

It will also create jte folder in application, in which we need to store our templetes.

3. Add the following plugin along with spring boot maven plugin

```xml
<plugin>
        <groupId>gg.jte</groupId>
        <artifactId>jte-maven-plugin</artifactId>
        <version>3.1.12</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>
```

4. Create a template in jte directory with extension of .jte.&#x20;

template - index.jte in src/main/jte

```java
@param String name // for parameters from model map

<!DOCTYPE html>
<html>
<head>
    <title>Hello JTE</title>
</head>
<body>
    <h1>Hello, ${name}!</h1>
</body>
</html>

```

5. To view this on browser we need to create a controller also&#x20;

```java
@Controller
public class HomeController {

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("name", "Dan"); // sending name parameter to jte
        return "index";
    }
}
```

### Properties available for JTE

```properties
# determine the jte template locations
gg.jte.templateLocation=src/main/jte # default is same

# configure template suffix
gg.jte.templateSuffix=.jte # default is same

# precompile the templates for faster startup and rendering, recommended in prod
gg.jte.usePrecompiledTemplates=true #dafault is false

# used for development as watcher will watch for changes in templates and recompile them
gg.jte.developmentMode=true
```

### Template Syntax

### ${} &#x20;

* To display data from variable , can be used with general data types along with Any class implementing `gg.jte.Content`&#x20;

### <%-- ... --%>&#x20;

* To display comments

### @import

* Used to import direcly from app like classes, records etc.
* Need to use fully qualified name e.g. **`@import com.app.Sample`&#x20;**&#x20;

### **@Param**&#x20;

* It used to declare the parameter that is passed to this template. e.g. **`@param Sample sample`**&#x20;
* The datatype could be premitive or the custom dto , models or records etc.
* For any classes we need to either import them first or need to use fully qualified name with @param.&#x20;
* we can also assign default values

### `@if`/`@endif`&#x20;

* Used for flow control in the template
* for nesting we can also use @elseif

### `@for` and `@endfor`

* Used to loop over variable&#x20;
* loop can be both fori or for in
* we can also use @else with for , as in case of no data else part will get executed.

### !{}

* used to declare local variable
* that can be used with ${}

### Content

* `gg.jte.Content` is a special parameter type, that is used to pass template code to other templates, much like lambdas in Java.&#x20;
* They are handy for sharing structures between different templates.

### Example -

```html
@import org.example.Page  # imports custom class
@import gg.jte.Content # imports content
@import my.Model

@param Page page
@param Content content
@param Content footer = null # asigning default value
@param String param;
@param Model model
@param Task task

<title>${param}</title>
<head>
    @if(page.getDescription() != null)
        <meta name="description" content="${page.getDescription()}">
    @endif
    <title>${page.getTitle()}</title>
</head>
<body>
    <h1>${page.getTitle()}</h1>
    
    <%-- if else --%>
    @if(model.entries.isEmpty())
        <p>I have no entries!</p>
    @elseif(model.entries.size() == 1)
        <p>I have one entry!</p>
    @else
        <p>I have ${model.entries.size()} entries!</p>
    @endif
    
    ## looping
    @for(var entry : model.entries)
    <li>${entry.title}</li>
    @endfor
    
    @for(int i = 0; i < 10; ++i)
        <li>i is ${i}</li>
    @endfor
    
    ## variable
    !{var innerObject = someObject.get().very().deeply().located().internal().object();}
    
    ${innerObject.a()}
    ${innerObject.b()}
    
    <div class="content">
        ${content}
    </div>
    @if (footer != null)
        <div class="footer">
            ${footer}
        </div>
    @endif
    
    <%-- importing other templte --%>
     @for(Task task : tasks)
          @template.task-row(task = task)
    @endfor
                    
</body>
```

```html
task-row.jte

@import com.app.model.Task
@param Task task

<tr id="task-${task.getId()}">
    <td class="py-2">${task.getDescription()}</td>
    <td class="text-right">
        <button class="px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600">
            Delete
        </button>
    </td>
</tr>

```

example for content -

```java
@import org.example.WelcomePage
@param WelcomePage welcomePage

@template.layout.page(
    page = welcomePage,
    content = @`
        <p>Welcome, ${welcomePage.getUserName()}.</p>
    `,
    footer = @`
        <p>Thanks for visiting, come again soon!</p>
    `
)
```
