java - In Thymeleaf how can you use separate resolvers for HTML and JavaScript to copy JavaScript from a file into the generated HTML -


i creating proof of concept program later brought larger project. thymeleaf seemed template engine try (natural templates active development) , seems fit have been having following issue.

goal: take json , generate html file work offline report viewing. trying convert premade html template single html page no external references other files or internet.

problem: can't javascript resolve correctly inside template resolver.

detailed description: have attempted keep javascript , html in separate directories. way javascript can use '.js' suffix , html can use '.html' suffix.

in order created 2 resolvers, 1 html , 1 js. have seen similar things done html fragments , seemed work other people.

the problem js resolver never seems used when hits <script th:include="jquery.min></script"part of demo.tpl.html file. figured because .setorder(1) on html resolver , .setorder(2) on js resolver when can't find 'jquery.min' template first resolver query second resolver such template.

i attempted resolution js resolver set first resolver , attempted resolve 'demo.js' (which doesn't exist) instead of failing , checking second resolver in list have 'demo.tpl.html' available resolve.

it seems if ever uses first resolver , second resolver ignored.

relevant environment details:

   ...    <properties>       <jdk.version>1.8</jdk.version>    </properties>    ...    <dependency>       <groupid>org.thymeleaf</groupid>       <artifactid>thymeleaf</artifactid>       <version>3.0.0.release</version>    </dependency> 

also, not using spring, command line tool , wanted keep light possible , didn't see need spring.

the type of resolver using filetemplateresolver since not using servlet resolve html directly browser.

file structure:

file structure of project

github link: https://github.com/njfife/jsontohtmlreportgenerator

the commit @ time of question: 619fb96

applicationstart.java (main):

public class applicationstart {      public static void main(string ... args) {         ... stuff ...         jsonconverter jsonconverter = new jsonconverter();         string html = jsonconverter.render(); // fails         system.out.println(html);         ... stuff ..     } } 

jsonconverter.java:

public class jsonconverter {      private templateengine templateengine;     private standardmessageresolver messageresolver;     private properties properties;     private context context;     private classloader classloader = this.getclass().getclassloader();      // of top of not related issue     // skip template resolvers built      public jsonconverter() {         // set template location         file templates =              new file(classloader.getresource("templates").getfile());         // translation data         this.properties = new properties();         this.context = new context();         // hardcoded spanish testing         this.context.setlocale(new locale("es"));         // translation , message stuff, not         // issue in case.         try {             stringbuilder defaultfilename = new stringbuilder();             defaultfilename.append("messages");             if(!context.getlocale().equals(locale.english)) {                 defaultfilename.append("_");                 defaultfilename.append(context.getlocale().tostring());             }             defaultfilename.append(".properties");             inputstream propertiesstream = classloader                 .getresourceasstream(defaultfilename.tostring());             this.properties.load(propertiesstream);          } catch (exception e) {             system.out.println("error!");         }          // here down probally issue          this.templateengine = new templateengine();          // build html resolver         filetemplateresolver htmlfiletemplateresolver             = new filetemplateresolver();         htmlfiletemplateresolver             .setprefix(templates.getabsolutepath() + "/html/");         htmlfiletemplateresolver.setsuffix(".tpl.html");         htmlfiletemplateresolver.settemplatemode(templatemode.html);         htmlfiletemplateresolver.setcacheable(false);         htmlfiletemplateresolver.setcharacterencoding("utf-8");         htmlfiletemplateresolver.setorder(1); // set primary         messageresolver = new standardmessageresolver();         messageresolver.setdefaultmessages(this.properties);         templateengine.setmessageresolver(messageresolver);          filetemplateresolver javascriptfiletemplateresolver              = new filetemplateresolver();         javascriptfiletemplateresolver             .setprefix(templates.getabsolutepath() + "/includes/");         javascriptfiletemplateresolver.setsuffix(".js");         javascriptfiletemplateresolver             .settemplatemode(templatemode.javascript);         javascriptfiletemplateresolver.setcacheable(false);         javascriptfiletemplateresolver.setcharacterencoding("utf-8");         javascriptfiletemplateresolver.setorder(2);         // resolve resource location         templateengine.addtemplateresolver(htmlfiletemplateresolver);         templateengine             .addtemplateresolver(javascriptfiletemplateresolver);     }      public string render() {         // testing programatic alteration of context         context.setvariable("name", "nathan");         // fails render html when when including jquery         return templateengine.process("demo", context);     } } 

relevant html template:

... stuff .. <head>     <meta charset="utf-8">     <title>title</title> </head> <body>     <th:block>         <script th:include="jquery.min"></script>         <script th:include="highcharts.min"></script>     </th:block>     <h1>chart demo</h1>     <div id="container"></div>     <p th:text="#{hello}"></p>     <p th:text="${name}"></p>     <p th:text="#{message}"></p>     <p th:text="#{message.with.var(${name})}"></p> </body> ... stuff ... 

tl;dl - if want templateengine switch resolvers when source template file isn't in current resolver's path have set checkexistence flag true calling yourtemplateresolver.setcheckexistence(true);. if don't attempt resolve template first resolver in list if there no template file name in path.

also, th:include deprecated don't use it, use th:insert or 1 of other options instead.


so, decided walk through source code , find deciding templateresolver use template , came across block of code:

for (final itemplateresolver templateresolver : configuration.gettemplateresolvers()) {              final templateresolution templateresolution =                     templateresolver.resolvetemplate(configuration, ownertemplate, template, templateresolutionattributes);             if (templateresolution != null) {                 if (logger.istraceenabled()) {                     logger.trace(                             "[thymeleaf][{}] template resolver match! resolver \"{}\" resolve template \"{}\"",                             new object[] {templateengine.threadindex(), templateresolver.getname(), loggingutils.loggifytemplatename(template)});                 }                 return templateresolution;             }              if (logger.istraceenabled()) {                     logger.trace(                             "[thymeleaf][{}] skipping template resolver \"{}\" template \"{}\"",                             new object[] {templateengine.threadindex(), templateresolver.getname(), loggingutils.loggifytemplatename(template)});             }          } 

for reason template resolution comming 'not null' though there no file present.

digging resolvetemplate function found conditional:

if (this.checkexistence && !templateresource.exists()) { // check if flag set true     return null; } 

adding htmlfiletemplateresolver.setcheckexistence(true);

and changing "demo.tpl.html" file use th:insert instead of th:include fixed everything.

<th:block>     <script th:insert="jquery.min"></script>     <script th:insert="highcharts.min"></script> </th:block> 

not sure why need tell templateresolver existence of template requirement resolver being valid resolver template. @ least think default should true don't think mine standard use case it's possible outlier here.


Comments

Popular posts from this blog

javascript - Slick Slider width recalculation -

jsf - PrimeFaces Datatable - What is f:facet actually doing? -

angular2 services - Angular 2 RC 4 Http post not firing -