Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to use fragment inside template but get TemplateInputException: Error resolving template #322

Closed
alan-czajkowski opened this issue Mar 16, 2024 · 3 comments

Comments

@alan-czajkowski
Copy link

alan-czajkowski commented Mar 16, 2024

Building a back-end app using Spring Boot 3.1
Using dependency:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
      <version>3.1.9</version>
    </dependency>

which uses:

    <dependency>
      <groupId>org.thymeleaf</groupId>
      <artifactId>thymeleaf-spring6</artifactId>
      <version>3.1.2.RELEASE</version>
    </dependency>

Rendering templates on the fly using the Template engine:

    ...

    SpringResourceTemplateResolver templateResolver;

    // HTML template resolver
    templateResolver = new SpringResourceTemplateResolver();
    templateResolver.setPrefix("/WEB-INF/thymeleaf/templates");
    templateResolver.setTemplateMode(TemplateMode.HTML);
    templateResolver.setCharacterEncoding(UTF_8.name());
    templateResolver.setCacheable(false);
    templateResolver.setCheckExistence(true);
    templateResolver.setApplicationContext(this.applicationContext);
    templateEngine.addTemplateResolver(templateResolver);

    // TEXT template resolver
    templateResolver = new SpringResourceTemplateResolver();
    templateResolver.setPrefix("/WEB-INF/thymeleaf/templates");
    templateResolver.setTemplateMode(TemplateMode.TEXT);
    templateResolver.setCharacterEncoding(UTF_8.name());
    templateResolver.setCacheable(false);
    templateResolver.setCheckExistence(true);
    templateResolver.setApplicationContext(this.applicationContext);
    templateEngine.addTemplateResolver(templateResolver);

    ...

    renderedContent = templateEngine.process(templatePath, context);

    ...

template directory layout:
Screen Shot 2024-03-16 at 4 16 58 PM

welcome.html:

<!DOCTYPE html>
<html xml:lang="en" xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
  <title th:text="#{templates.email.html.welcome.title}">Subject: ${subject}</title>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body style="font-family: sans-serif">
<div th:replace="~{email/fragments/header.html :: header}">hi</div>
...
</body>
</html>

there is no problem rendering this template (without the fragment) using:

    renderedContent = templateEngine.process("/email/welcome.html", context);

as soon as you add the fragment:

<div th:replace="~{email/fragments/header.html :: header}">hi</div>

you get this error:

...
Caused by: org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/thymeleaf/templates/email/welcome.html]")
	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1103)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1064)
	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1053)
	at com.sihuve.dyskover.common.manager.template.TemplateManager.render(TemplateManager.java:227)
	... 181 more
Caused by: org.attoparser.ParseException: Error resolving template [email/fragments/header.html], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "/email/welcome.html" - line 8, col 6)
	at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
	at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
	at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
	... 187 more
Caused by: org.thymeleaf.exceptions.TemplateInputException: Error resolving template [email/fragments/header.html], template might not exist or might not be accessible by any of the configured Template Resolvers (template: "/email/welcome.html" - line 8, col 6)
	at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869)
	at org.thymeleaf.engine.TemplateManager.parseStandalone(TemplateManager.java:250)
	at org.thymeleaf.standard.expression.FragmentExpression.resolveExecutedFragmentExpression(FragmentExpression.java:567)
	at org.thymeleaf.standard.processor.AbstractStandardFragmentInsertionTagProcessor.computeFragment(AbstractStandardFragmentInsertionTagProcessor.java:419)
	at org.thymeleaf.standard.processor.AbstractStandardFragmentInsertionTagProcessor.doProcess(AbstractStandardFragmentInsertionTagProcessor.java:115)
	at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
	at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
	at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
	at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)
	at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleOpenElementEnd(TemplateHandlerAdapterMarkupHandler.java:304)
	at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:278)
	at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleOpenElementEnd(OutputExpressionInlinePreProcessorHandler.java:186)
	at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleOpenElementEnd(InlinedOutputExpressionMarkupHandler.java:124)
	at org.attoparser.HtmlElement.handleOpenElementEnd(HtmlElement.java:109)
	at org.attoparser.HtmlMarkupHandler.handleOpenElementEnd(HtmlMarkupHandler.java:297)
	at org.attoparser.MarkupEventProcessorHandler.handleOpenElementEnd(MarkupEventProcessorHandler.java:402)
	at org.attoparser.ParsingElementMarkupUtil.parseOpenElement(ParsingElementMarkupUtil.java:159)
	at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:710)
	at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)

doesn't matter which fragment path you use:

  • email/fragments/header.html
  • email/fragments/header
  • fragments/header.html
  • fragments/header
@alan-czajkowski
Copy link
Author

is anybody looking into this?

@ultraq
Copy link
Member

ultraq commented Jul 3, 2024

Hey there, the thymeleaf-spring6 package was moved into the main thymeleaf repo a while back, so there probably aren't too many people monitoring this repo.

As for your issue, "Error resolving template" is in many cases a path issue. I can see from your config that you have a path prefix of /WEB-INF/thymeleaf/templates, and you're trying to find a template fragment at email/fragments/header.html, so when you put those 2 together you get /WEB-INF/thymeleaf/templatesemail/fragments/header.html which is missing a / in the middle to complete it.

Given you're doing things like renderedContent = templateEngine.process("/email/welcome.html", context); with a leading /, then it might be easiest to add the leading / to email/fragments/header.html as well.

@alan-czajkowski
Copy link
Author

@ultraq I think the leading / might have solved it ...
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants