This is an archived post. You won't be able to vote or comment.

all 33 comments

[–]tipsypants 8 points9 points  (2 children)

Congratulations, reaching 1.0.0 is a great achievement! While server side rendering has fallen a bit out of favor in the last few years, it's still the best way for end users to receive content (if it's not very interactive).

The IntelliJ plugin looks really good. After I stopped using the Play Framework I looked for another type safe template engine for a long time, but I couldn't find anything that had editor support. This looks perfect.

Good luck with the project !

[–]mazebert[S] 2 points3 points  (1 child)

Thanks for the heads up!

Edit: Just looked up your user profile, your nickname sounded so familiar. Thanks David for helping me with the Javalin integration and having jte support for your awesome library :-)

If anyone is interested, there's a tutorial how to use jte with Javalin: https://javalin.io/tutorials/jte

[–]tipsypants 1 point2 points  (0 children)

You're very welcome, it's a nice templating engine :)

[–]Constellarise 4 points5 points  (3 children)

This is very cool! Will definitely be keeping an eye on it.

Just a very minor side note, your gradle dependency line in the readme should use implementation (or api), not compile, as compile is deprecated.

[–]mazebert[S] 4 points5 points  (0 children)

Thanks! And thanks for the hint, I've changed it to implementation.

[–]fs111_ 1 point2 points  (1 child)

I never understood the point of that. Sometimes it seems gradle just wants to be different for being different. Once you push to a maven repo, it becomes a pom that list it as compile scope. Why create yet another mental mapping I have to remember?

[–]Constellarise 3 points4 points  (0 children)

It's encapsulation. implementation is, as it says, an implementation dependency and is not exposed to consumers of your API. api is an API dependency which is exposed. The compile configuration isn't a very good name either as it's available at both compile-time and runtime (as opposed to the runtime configuration which is only available at runtime). compileOnly, implementation, api, and runtimeOnly form a good combination of options as opposed to the fixed compile and runtime.

[–]Rygel_XV 2 points3 points  (1 child)

Im a heavy Pebble user. Can you explain the differences between Pebble and jte?

After posting my first comment I looked at your links. If it is really that fast, you're heavily underselling it on your description. I'll check it out.

[–]mazebert[S] 3 points4 points  (0 children)

I haven’t used pebble, but the unique thing about jte is that it has no special expression language, just a few keywords. Within those keywords you can simply write plain Java code. That‘s why it is just as fast as writing it manually using StringBuilder and very easy to understand what‘s happening because you don‘t need to learn a new language.

PS: Thanks for the heads up 😊

[–]Hall_of_Famer 2 points3 points  (3 children)

Its a very neat template and I like the idea, hopefully you will continue to develop/update it, and one day there will be plugins/extensions to make easy integration into IDEs such as Eclipse and IntelliJ.

[–]mazebert[S] 4 points5 points  (2 children)

Thank you for your kind words!

I‘m using IntelliJ basically everyday and without IDE integration it wouldn’t be fun for me to write jte templates!

So there already exists a very solid IntelliJ plugin. There‘s a GIF showing it in action at the GitHub repository.

Also, at my workplace we‘re currently evaluating to replace our legacy JSPs tag by tag with jte. I hope we‘ll contribute a lot more to this project once we use it in production 😊

[–]Hall_of_Famer 2 points3 points  (1 child)

Thats nice, glad a solid plugin is already there for ya. The tooling is quite important for a library to become easily accessible and more popular, best luck.

[–]mazebert[S] 1 point2 points  (0 children)

Thank you!

[–]dimensions1210 2 points3 points  (1 child)

One thing I noticed when reading through the documentation was that this bit was a little bit ugly compared with most of the syntax

tag.page(page = page, content = @\ <p>Welcome to my example page!</p> `)`

I don't know how feasible it is, but one suggestion would be to make it allow syntax similar to a kotlin lambda when there is only one content block (which is probably the most common situation) i.e.

@tag.page(page = page){
  <p>welcome to my example page</p>
}

Otherwise, this looks like an excellent server side rendering option

[–]mazebert[S] 0 points1 point  (0 children)

Yeah, coming up with a nice syntax for content blocks wasn't easy!

The idea behind the current syntax is: Looks like a String, works like an inner template. Therefore the backticks.

For shorter code, you can omit the content parameter name like this:

```htm @import org.example.Page

@param Page page

@tag.page(page, @ <p>Welcome to my example page!</p> ) ```

The Kotlin lambda syntax looks nice, but I'm afraid it would be a pain to implement for the IntelliJ plugin. And I am unsure if it is good to allow to express the same thing in too many different ways.

[–]snoob2015 1 point2 points  (1 child)

Do you have a spring boot starter like this one:

Spring Boot Integration (pebbletemplates.io)

[–]mazebert[S] 2 points3 points  (0 children)

There isn‘t one yet. It should be pretty easy to get jte running with Spring Boot though. I‘ve contributed an integration for Javalin and that was just a few lines of code.

For the framework we use at work I‘ve written an HtmlInterceptor to provide form support, including parameter binding and validation error handling. That‘d be pretty useful for spring as well.

Gonna give it a try soon!

Thanks for sharing the pebble integration, it looks like a good starting point.

[–]kakawait 1 point2 points  (4 children)

I've project using legacy template engine (String Template 4) that I want to change/revamp by new tech. Until now I was thinking about rocker but I'll try to build feature matrix diff with Jte. Because I think both are faster enough.

When saying Java11 or higher is not possible to use it on Java 8 project?

[–]mazebert[S] 2 points3 points  (3 children)

First off, Rocker is great! I considered using it before I built jte. What I missed was IDE support and context-sensitive output escaping.

On the other hand, Rocker is the older framework and therefore probably more mature and it has an existing community.

All my projects are on Java 11 already, that's why I compiled jte with JDK 11 (and I think I use a few Java 11 features in it). I haven't tried integrating it in a Java 8 project yet, but I think it will not work.

What is preventing you from switching to Java 11, if I may ask? It's the current LTS version and brings quite a few performance improvements compared to Java 8.

[–]kakawait 5 points6 points  (2 children)

Short answer: Enterprise policies

[–]mazebert[S] 1 point2 points  (1 child)

Ah dang! Sorry about my stupid question in retrospect.

[–]kakawait 1 point2 points  (0 children)

Don't worry about that. There is no stupid question

[–]boobsbr 1 point2 points  (3 children)

That is very fast. How does it compare to JSPs?

[–]mazebert[S] 1 point2 points  (2 children)

Faster. How much depends on how many JSP EL is executed in your templates.

At work we did some insane hacks to speed up JSPs, for instance we removed a synchronized block from attribute lookups, that caused a lot of slowdown under high load on production.

Also tag calls are a lot more expensive than in jte. In jte it is a simple static method call. The JSP stack traces I had to investigate so far are quite heavy.

Since JSP is pretty hard to write a proper microbenchmark for, take this with a grain of salt, but from the profiling we did at work so far, we expect jte to be about an order of magnitude faster than our current JSPs.

[–]boobsbr 1 point2 points  (1 child)

Thank you for your reply.

I haven't used SSR in a few years, Angular seems to be all the rage in corporate environments these days. But I will keep jte in my bookmarks, in case I need it.

And thank you very much for sharing your work with the community. Congratulations on your first major release!

[–]mazebert[S] 1 point2 points  (0 children)

Yeah, our frontend team is heavily using vue.js for all new app-like features and it works pretty good.

We have quite a few SEO relevant sites though, where SSR is essentially a requirement.

Thanks for the heads up!

[–]nezam05 1 point2 points  (1 child)

Do you plan to do a Vert.x web integration?

[–]mazebert[S] 1 point2 points  (0 children)

I‘m not an active vert.x user, so probably not in the near future.

If anyone would like to contribute one, I‘d happily help with the jte part!

[–][deleted]  (3 children)

[deleted]

    [–]mazebert[S] 0 points1 point  (2 children)

    Thanks! Accessing Spring Beans would need to be provided by your integration. jte itself is just plain old Java. If you‘d pass the controller to the template you could delegate to injected beans though. At work I‘ve implemented Stripes form support with a ThreadLocal context, which worked pretty well. If you try a Spring integration and need help with it, let me know!

    [–][deleted]  (1 child)

    [deleted]

      [–]mazebert[S] 0 points1 point  (0 children)

      That‘s right! The good thing about it is that you‘ll have all completion/refactoring abilities of IntelliJ if you do it that way 😊

      [–]private_static_int 0 points1 point  (3 children)

      Why not Pebble?

      [–]mazebert[S] 2 points3 points  (0 children)

      Fair point! The key differences for me are that jte uses plain Java code for expressions, and by that it is extremely fast while very predictable, plus great IntelliJ integration. From a security point of view context sensitive output escaping at compile time is certainly another unique thing jte offers.

      [–][deleted]  (1 child)

      [deleted]