Vertx 3.0 integration with Thymeleaf

778 views
Skip to first unread message

J0t1

unread,
Jul 13, 2015, 4:18:39 AM7/13/15
to ve...@googlegroups.com

Hi All,

I am new to Vertx and we recently started using Vertx 3.0 for developing a web application. Right now I am running my vertx application as a .jar file using command prompt

We are using thymeleaf templates to develop the UI, I am able to render thymeleaf pages through vertx like this
ThymeleafTemplateEngine thymeleafEngine = ThymeleafTemplateEngine.create();
TemplateHandler templateHandler = TemplateHandler.create(thymeleafEngine, "src/main/webapp/templates","text/html");
router.route("/dynamic/*").handler(templateHandler);

Here i have provided the path to look for my thymeleaf templates while creating TemplateHandler. However, I am not able to use TemplateResolver for the same purpose. This is how i tried to use it:
TemplateResolver  templateResolver =  new ClassLoaderTemplateResolver();
templateResolver
.setPrefix("src/main/webapp/templates");
templateResolver
.setTemplateMode("HTML5");
templateResolver
.setSuffix(".html");
thymeleafEngine
.getThymeleafTemplateEngine().setTemplateResolver(templateResolver);
TemplateHandler templateHandler = TemplateHandler.create(thymeleafEngine);

With this code it tries to look for the html page i am requesting under "/templates" location which is the default location for TemplateHandler. So looks the TemplateResolver configuration I provide is not getting picked up at all. 

Apart from setting the template location i also want to turn of caching atleast in the dev environment so that i do not need to restart Vertx for every template change, that can also be achieved using TemplateResolver as far as i know
templateResolver.setCacheable(false);

Another reason for using TemplateResolver is when i use a thymeleaf template with header and footer fragments e.g.
<div th:replace="header:: header"></div>

I am getting following error in vertx, which means its not able to find "header.html" file at run time though its present in the same location as test.html file which i am trying to render. I believe if we set that path using TemplateResolver this will get resolved.

org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.standard.processor.attr.StandardReplaceFragmentAttrProcessor' (s
rc/main/webapp/templates/testdriver/test.html:30)
.....
Caused by: io.vertx.core.VertxException: io.vertx.core.file.FileSystemException: java.nio.file.NoSuchFileException: header

Can someone please guide me if this is the right way to configure and use thymeleaf with Vertx? or please point me to any working examples we have which uses TemplateResolvers.
Also where will vertx/thymeleaf look for the templates by default? Where should my /templates folder be ? I tried putting that in WEB-INF folder, Its part of my jar also and I try to manually add it in my classpath while i am running my vertx instance but nothing has worked for me so far.

Thanks in advance.

Michael Remme

unread,
Jul 13, 2015, 7:46:23 AM7/13/15
to ve...@googlegroups.com


Am Montag, 13. Juli 2015 10:18:39 UTC+2 schrieb J0t1:

Hi All,

I am new to Vertx and we recently started using Vertx 3.0 for developing a web application. Right now I am running my vertx application as a .jar file using command prompt

We are using thymeleaf templates to develop the UI, I am able to render thymeleaf pages through vertx like this
ThymeleafTemplateEngine thymeleafEngine = ThymeleafTemplateEngine.create();
TemplateHandler templateHandler = TemplateHandler.create(thymeleafEngine, "src/main/webapp/templates","text/html");
router.route("/dynamic/*").handler(templateHandler);

Here i have provided the path to look for my thymeleaf templates while creating TemplateHandler. However, I am not able to use TemplateResolver for the same purpose. This is how i tried to use it:
TemplateResolver  templateResolver =  new ClassLoaderTemplateResolver();
templateResolver
.setPrefix("src/main/webapp/templates");
templateResolver
.setTemplateMode("HTML5");
templateResolver
.setSuffix(".html");
thymeleafEngine
.getThymeleafTemplateEngine().setTemplateResolver(templateResolver);
TemplateHandler templateHandler = TemplateHandler.create(thymeleafEngine);

With this code it tries to look for the html page i am requesting under "/templates" location which is the default location for TemplateHandler. So looks the TemplateResolver configuration I provide is not getting picked up at all. 

Apart from setting the template location i also want to turn of caching atleast in the dev environment so that i do not need to restart Vertx for every template change, that can also be achieved using TemplateResolver as far as i know
templateResolver.setCacheable(false);

a code snippet how i am changing the cache:

    thEngine = new ThymeleafTemplateEngineImpl();

    thEngine.setMode(ThymeleafTemplateEngine.DEFAULT_TEMPLATE_MODE);


    TemplateEngine te = thEngine.getThymeleafTemplateEngine();

    Set<ITemplateResolver> trs = te.getTemplateResolvers();

    for (ITemplateResolver tr : trs) {

      ((TemplateResolver) tr).setCacheable(false);

    }

    templateHandler = TemplateHandler.create(thEngine);

 

Another reason for using TemplateResolver is when i use a thymeleaf template with header and footer fragments e.g.
<div th:replace="header:: header"></div>

I am getting following error in vertx, which means its not able to find "header.html" file at run time though its present in the same location as test.html file which i am trying to render. I believe if we set that path using TemplateResolver this will get resolved.

org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.standard.processor.attr.StandardReplaceFragmentAttrProcessor' (s
rc/main/webapp/templates/testdriver/test.html:30)
.....
Caused by: io.vertx.core.VertxException: io.vertx.core.file.FileSystemException: java.nio.file.NoSuchFileException: header

here you are defining that the content shall be fetched as a fragment, which is defined in the file header.html. You should read
it's quite interesting ;-)

J0t1

unread,
Jul 13, 2015, 2:07:55 PM7/13/15
to ve...@googlegroups.com
Thanks a ton Michael for your help ,  i used similar approach to set prefix and suffix for the TemplateResolver and it worked !!!
Only catch is it is still appending "/template" to the prefix I provide in the resolver to look for the thymeleaf templates. But when it tries to resolve header.html it picks up exact path i have given in prefix.
e.g. 
TemplateEngine te = thEngine.getThymeleafTemplateEngine();
Set<ITemplateResolver> trs = te.getTemplateResolvers();
for (ITemplateResolver tr : trs) {
      ((TemplateResolver) tr).setCacheable(false);
      ((TemplateResolver) tr).setPrefix("src/main/webapp/thyme/");
      ((TemplateResolver) tr).setSuffix(".html");
}

When i request "test.html"(which uses header fragment defined in header.html), it is looking into path src/main/webapp/thyme/templates/test.html, and for header.html it looks under path src/main/webapp/thyme/header.html. But I can live with placing my templates in this manner.
Another interesting(or weird!) thing is, if i set suffix as .html then it will get appended to whatever resource i request, so if i am requesting test.html, the template name it looks for becomes test.html.html. If i remove the suffix configuration , its not appending .html to header also, and throws FileNotFound. 
Probably i need to keep the suffix configuration and manipulate the request url i get to remove .html.

Thanks again !

J0t1

unread,
Jul 14, 2015, 3:00:40 PM7/14/15
to ve...@googlegroups.com
I resolved one of the problem i.e "/templates" is getting appended to the path configured in template resolver prefix by creating TemplateHandler object like this
TemplateHandler templateHandler = TemplateHandler.create(thEngine,"","text/html");

Posting in case someone else faces same issue.
Reply all
Reply to author
Forward
0 new messages