I have a common layout which, by default, should display a (basic) search form on each page excepted the search page itself which contains a (more advanced) search form already.
Is it possible to pass a parameter from my search page to the layout in order to not display the default search form?
Here is an example of what I would like to do:
layout.html
<html layout:???="displayShowForm = true">
...
<form action="search" th:if="${displayShowForm}">...</form>
...
<div layout:fragment="content">...</div>
home.html (show the default search form)
<html layout:decorator="layout">
...
<div layout:fragment="content">...</div>
search.html (hide the default search form)
<html layout:decorator="layout (displayShowForm = false)">
...
<div layout:fragment="content">
...
<form action="advancedSearch">...</form>
Yes, it's entirely possible, even though Thymeleaf's documentation doesn't clearly state it.
All you have to do is pass your param using the th:with attribute. There may be other methods, but this seems to be the most straight-forward.
Here's a stripped down version of my implementation:
Default decorator - fragments/layout/default.html
<!doctype html>
<html xmlns:layout="http://www.thymeleaf.org" xmlns:th="http://www.thymeleaf.org">
<body>
<div th:replace="fragments/header :: main"></div>
<div layout:fragment="content">
main content goes here
</div>
</body>
</html>
Header fragment - fragments/header.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="main">
<nav>
<ul>
<li><a href="#" th:classappend="${currentPage == 'home'} ? 'active'">Home Page</a></li>
<li><a href="#" th:classappend="${currentPage == 'about'} ? 'active'">About</a></li>
</ul>
</nav>
</div>
</body>
Home Page file - home.html
<!doctype html>
<html layout:decorator="layout/default" th:with="currentPage='home'"
xmlns:layout="http://www.thymeleaf.org/" xmlns:th="http://www.thymeleaf.org">
<body>
<div layout:fragment="content">
This is my home page content... thrilling, isn't it?
</div>
</body>
</html>
Here, in the home.html file, you can see I include the default decorator and pass my parameter using the th:with attribute. I don't actually use my parameter in my layout decorator, but I use it in header.html, which is included from the decorator. No need to pass it from the decorator to the header.html fragment, since it's already in scope.
There was also no need to do a NULL check on the currentPage variable in header.html. The active CSS class was simply not appended when removing the parameter from home.html.
If I were to render home.html, I would expect to see the following output:
<!doctype html>
<html>
<body>
<nav>
<ul>
<li><a href="#" class="active">Home Page</a></li>
<li><a href="#">About</a></li>
</ul>
</nav>
<div>
This is my home page content... thrilling, isn't it?
</div>
</body>
</html>
Yes, it is possible to pass parameters but you need to use layout:include
instead of layout:decorator
or layout:fragment
.
Similar to Thymeleaf's
th:include
, but allows the passing of entire element fragments to the included page. Useful if you have some HTML that you want to reuse, but whose contents are too complex to determine or construct with context variables alone.
Source : https://github.com/ultraq/thymeleaf-layout-dialect
You should take a look at this documentation which will give you details about the way to use it.
In your case, it could look like :
<div layout:include="form" th:with="displayShowForm=true"></div>
And in the layout page of form
:
<div layout:fragment="form">
<div th:if="${displayShowForm} == true">
<form action="basicSearch"></form>
</div>
<div th:if="${displayShowForm} == false">
<form action="advancedSearch"></form>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With