Skip to content

3.0.0

Compare
Choose a tag to compare
@casid casid released this 19 Jun 20:48
· 131 commits to main since this release

We are happy to announce the release of jte 3. This version brings enhanced functionality, improved performance, and streamlined dependencies. Read on to discover what's new and improved in this release.

New Features:

1. Extension API:

Thanks to @edward3h, this release introduces a powerful extension API that allows you to generate custom content based on your template metadata. So far, there are two extensions ready to be used:

  • jte-native-resources creates GraalVM native image resources (previously part of jte core)
  • jte-models generates type safe model classes for each template.

For instance, using the jte-models extension will allow you to write code like this:

var templates = new StaticTemplates();
templates.helloWorld("Hi!").render(output);

We are very excited to see what other applications you're going to use this API for!

2. Enhanced Loop Syntax:

Loops now support an else branch that is executed if the loop did not iterate over any items. This provides convenient display of empty states. Here's an example:

<table>
  <tr>
    <td>Item</td>
    <td>Qty</td>
  </tr>
  @for(var item : groceryList)
    <tr>
      <td>${item.getName()}</td>
      <td>${item.getQuantity()}</td>
    </tr>
  @else
    <tr>
      <td colspan="2">You have forgotten your groceries list at home!</td>
    </tr>
  @endfor
</table>

A new version of the IntelliJ plugin supporting for-else has been released and is waiting for JetBrains approval. Big thanks to @bohdan-shulha for the idea and @kelunik to find a way to make this happen.

3. Optimized HTML Output Escaping:

We have improved the performance of HTML output escaping by replacing the OWASP Java Encoder with a custom, optimized version. This optimization not only boosts performance but also eliminates external dependencies back to zero. This ensures that jte remains fast and self-contained.

4. Improved UTF-8 Binary Output Performance:

We fine-tuned the performance of UTF-8 binary output. The latest benchmark results showcase significant enhancements in this area, resulting in faster and more efficient processing of UTF-8 binary output. The benchmark below uses UTF-8 binary output and HTML output escaping:

alt Template Benchmark

Breaking Changes:

1. Dropped Support for Java Versions < 17:

Starting from jte 3, support for Java versions below 17 has been discontinued. However, users who are still on older Java versions can continue to use jte 2, which will be maintained with necessary security patches as long as required.

2. Native Image Generation Extension:

Users who utilize the native image generation feature will need to migrate to the new extension provided in this release.

Old:

jte {
    generate()
    generateNativeImageResources = true
    binaryStaticContent = true
}

New:

jte {
    generate()
    jteExtension("gg.jte.nativeimage.NativeResourcesExtension")
    binaryStaticContent = true
}

3. Removed TemplateOutput Method:

The TemplateOutput#getWriter() method has been removed in this release. While we anticipate that this change will not affect most users, please be aware of this modification if you have relied on this method in your code. In case you created a custom TemplateOutput you can now safely remove this method from your implementation.

4. HTML tags in each template must be properly closed

Before jte 3, those were valid templates:
open-thing.jte

<div>

close-thing.jte

</div>

And could be used like this:

@template.open-thing()
Hello
@template.close-thing()

However, this resulted in brittle templates. Currently jte in Html mode checks at compile time, if a template is valid HTML. Since open-thing.jte and close-thing.jte can be compiled seperately, there's no way for the compiler to check if they are used correctly. We could do such a check at runtime, but this is quite against jte's design philosophy. We want to minimize runtime errors as much as possible and rather detect problems at compile time. So, with jte 3 open-thing.jte and close-thing.jte won't compile anymore.

Instead of two separate templates, one template with a content parameter can be used instead:

thing.jte

@import gg.jte.Content
@param Content content

<div>
  ${content}
</div>

And the usage will look like this:

@template.thing(content = @`
  Hello
`)

We believe this will result in templates, that will be better to maintain in the long run. Not only will this read better in IntelliJ, also users of such templates won't be able to forget a closing template anymore.

We are confident that these updates will enhance your experience with jte and provide a more efficient and powerful template engine for your Java or Kotlin projects. Thank you for your continued support and valuable feedback.

Happy templating!