Spring boot + thymeleaf in IntelliJ: cannot resolve vars

This is a problem with IntelliJ: IDEA-132738.

Basically IntelliJ is unable to locate the model variables when Spring Boot has been used to autoconfigure everything.


Prerequisites

  • Thymeleaf plugin is installed

  • The html element has an XML namespace declaration for th that is set to http://www.thymeleaf.org (with www.), for example:

    <html xmlns:th="http://www.thymeleaf.org">
    

IntelliJ version >= 2017.3

Detection should work automatically. However, some people complain that it still does not work for them), the issue IDEA-132738 should be fixed (@FloatOverflow: "I confirm that in version 2017.3 build 25.Oct.2017 the problem has been solved"):

Status 2017.3

Support for Spring Boot autoconfigured MVC applications is complete, all bundled autoconfiguration view types are supported.

Fix versions: 2017.3

If variables are not automatically detected you can still add the @thymesVar annotation as shown below.

IntelliJ version < 2017.3

It is, as Andrew wrote, a known error IDEA-132738. There is a workaround how to get rid of the error marks in the IDE. IntelliJ also supports the semi-automatic generation of the below mentioned code:

You can use Alt+Enter shortcut to invoke intention "Declare external variable in comment annotation" in order to get rid of "unresolved model attribute" in your views.

Add the following code to your html file:

<!--/* Workaround for bug https://youtrack.jetbrains.com/issue/IDEA-132738 -->
    <!--@thymesVar id="post" type="your.package.Post"-->
    <!--@thymesVar id="title" type="String"-->
    <!--@thymesVar id="content" type="String"-->
<!--*/-->

If you use extensions objects constructed automatically by ThymeLeaf, such as #temporals from thymeleaf-extras-java8time for conversion of java.time objects:

<span th:text="${#temporals.format(person.birthDate,'yyyy-MM-dd')}"></span>

and IntelliJ cannot resolve them, use similar code, and just add # in front of the object name:

<!--@thymesVar id="#temporals" type="org.thymeleaf.extras.java8time.expression.Temporals"-->

I want to add one more thing. As stated above, the issue has been fixed in IntelliJ 2017.3. I can also confirm this.

However, I noticed that this is only true if you define all your attributes directly inside the responsible controller function, like e.g. this:

@RequestMapping(value = "/userinput")
public String showUserForm(Model model){
    model.addAttribute("method", "post");
    model.addAttribute("user", new User());
    return "userform";
}

If you are using a sub-function in which you define the model attributes (see Example below), IntelliJ can still not find the attributes in the HTML template.

Example:

@RequestMapping(value = "/userinput")
public String showUserForm(Model model){
    return doIt(model);
}

private String doIt(Model model) {
    model.addAttribute("method", "post");
    model.addAttribute("user", new User());
    return "userform";
}

So, always make sure you put your code directly inside the view function!


Update

TL;DR: skip to accepted answer below: https://stackoverflow.com/a/44804086/474034

As mentioned in the comments by multiple people, this solution is not correct. The Thymeleaf documentation (see http://thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html), have in all their examples a version with www. included:

<html xmlns:th="http://www.thymeleaf.org">

See also the Standard-Dialect.xml on Github, which declares namespace-uri as:

namespace-uri="http://www.thymeleaf.org" 

Original Answer

I had two different portions of code: the first was showing the error and the second was not doing it. I observed that there is a difference in the xmlns:th attribute.

First Page: Not working!

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">

Second Page: Working!

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://thymeleaf.org">

I removed the www. and it works for me!