Dynamic replacement thymeleaf + spring

Can you create dynamic replacements in Thymeleaf?

I have the following controller:

@Controller
public class LoginController {

    @RequestMapping("/login")
    public String getLogin(Model model){
        model.addAttribute("template","login");
        return "index";
    }
}

      

And the following view:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head></head>
<body>

<div th:replace="fragments/${template} :: ${template}"></div>

</body>
</html>

      

And I am getting the following error:

Error resolving template "fragments/${template}", template might not exist or might not be accessible by any of the configured Template Resolvers

      

UPDATE

I tried to handle my variables like this:

<div th:replace="fragments/${__#{${template}}__} :: ${__#{${template}}__}"></div>

      

As is now ${template}

replaced with login

, I now have the following error:

Exception evaluating SpringEL expression: "??login_en_US??"

      

+4


source to share


5 answers


I believe the appropriate method for controlling this behavior in timylef is to use layout:fragment

. Please correct me if I am wrong. Here's a simple example of my layout page and login page that loads "dynamically":

layout.html

<html xmlns:layout="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Layout</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
</head>
<body>
<div>
    <div class="app-container">
        <div th:fragment="content">
        </div>
    </div>
</div>
<div th:fragment="script"></div>
</body>
</html>

      

Then, when the login loads, it replaces the div th:fragment

with a related div in the html view that matches the string returned by the controller method, in this case login.html:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.w3.org/1999/xhtml"
      layout:decorator="layout">
<head>
    <title>Login</title>
</head>
<body>
<div th:fragment="content">
    <form th:action="@{/login}" method="post">
        <div><label> User Name : <input type="text" name="username"/> </label></div>
        <div><label> Password: <input type="password" name="password"/> </label></div>
        <div><input type="submit" value="Sign In"/></div>
    </form>
</div>
</body>
</html>

      



Now, if you want to load another snippet conditionally, I use the approach which is to add replacement tags with th: if case. Here's an example of a form that displays various questions based on an attribute of the current user:

<div th:if="${foo.type)} == 'type_1'">
    <div th:replace="fragments/custom-questions :: type-1-checkboxes"></div>
</div>
<div th:if="${foo.type} == 'type_2'">
    <div th:replace="fragments/custom-questions :: type-2-checkboxes"></div>
</div>

      

Then the related div is loaded from the custom-questions.html file:

<div th:fragment="type-1-checkboxes">
  //stuff
</div>

<div th:fragment="type-2-checkboxes">
  //stuff
</div>

      

+4


source


Although Joe Essey's solution works the same as I solved with the following code:



<div th:replace="@{'fragments/' + ${template}} :: ${template}"></div>

      

+11


source


I just run into this problem (this is my first time with thymeleaf / spring). Here's what I solved for me:

<div class="col-md-12" th:include="__${template}__ :: body" ...

      

+2


source


The question does not say what the login refers to. whether the login is a separate page or a fragment defined on another html page. Because using the above just results in the below error "template may not exist or may not be available to any of the configured template transformers".

0


source


<div th:insert="${subpage}::fragementName"> 

      

Just change the names of the subpages and you get dynamic behavior in thymleaf

0


source







All Articles