I want to be able to take a thymeleaf fragment, use all the content inside it, but then, sometimes, add extra content from the page that consumes it. Typical case: I have a footer template which contains a script ref that I want on every page. On some pages I want to add another script ref, but not all.
I have the following setup (reduced complexity to focus on the point) in my web application:
layout.html:
<html>
<body>
<div class="container">
<div fragment="content"></div>
</div>
<div th:replace="shared/footer :: footer"></div>
</body>
</html>
shared/footer.html
<html>
<body>
<div th:fragment="footer" th:remove="tag">
<script th:src="{@/scripts/a.js}"></script>
</div>
</body>
</html>
index.html
<html>
<body>
<div th:fragment="content" class="myClass">
<h1>Oh hello</h1>
</div>
<!-- what do i put here?!!! -->
</body>
</html>
What I would like to do is be able to add some extra content to footer, from the index.html:
e.g.:
<div th:addExtraStuff="footer">
<script th:ref="@{scripts/b.js"></script>
</div>
so final result looks like this:
<html>
<body>
<div class="container">
<div class="myClass">
<h1>Oh hello</h1>
</div>
</div>
<div>
<script src="/scripts/a.js"></script>
<script src="/scripts/b.js"></script>
</div>
</body>
</html>
Obviously th:addExtraStuff doesn't exist - but you get the idea. I want the existing content, and to be able to supply my own content. I think it will start to get too complicated if I put ALL possibilities in the fragment and then use evaluations to decide whether to actually include that possibility. I could be wrong though.
One way I've solved this, without using a custom dialect, is to use arguments on the fragment I use as my layout template which I call 'main-layout'. This example allows you to leave out elements you don't need to override but any you provide will be added to whatever is in the 'main-layout' fragment.
The basic template looks like this
main-view.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:fragment="main-layout">
<head>
<title>Template Head Title</title>
<th:block th:replace="${head} ?: ~{}" />
</head>
<body>
<header>
Common Template Header Here
<th:block th:replace="${contentHeader} ?: ~{}" />
</header>
<main>
Common Template Content Here
<th:block th:replace="${content} ?: ~{}" />
</main>
</body>
<footer>
Common Template Footer Here
<th:block th:replace="${footer} ?: ~{}" />
</footer>
</html>
And using it looks like
<!DOCTYPE HTML>
<html th:replace="main-view.html :: main-layout (head=~{:: head}, contentHeader=~{:: header}, content=~{:: main}, footer=~{:: footer})">
<head th:remove="tag">
<title>Greeting Head</title>
</head>
<body>
<header th:remove="tag">
Greeting Content Header
</header>
<main th:remove="tag">
Greeting Content
</main>
</body>
<footer th:remove="tag">
Greeting Footer
</footer>
</html>
I am not sure if I understand what you want to do, but how about this.
index.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
Hello World
</body>
<!-- Calling default scripts + custom scripts -->
<div th:replace="fragments/script :: base_script(~{::script})">
<script th:src="@{js/customjs1.min.js}"></script>
<script th:src="@{js/customjs2.min.js}"></script>
<script th:src="@{js/customjs3.min.js}"></script>
</div>
<!-- If you want to call only default scripts -->
<!--<head th:replace="fragments/script :: base_script(null)"></head>-->
</html>
The default js files are called by default but you can add additional scripts.
templates/fragments/script.html:
<html xmlns:th="http://www.thymeleaf.org">
<div th:fragment="base_script(scripts)">
<!-- /* default js files */ -->
<script th:src="@{js/defaul1.min.js}"></script>
<script th:src="@{js/defaul2.min.js}"></script>
<script th:src="@{js/defaul3.min.js}"></script>
<th:block th:if="${scripts != null}">
<th:block th:replace="${scripts}" />
</th:block>
</div>
</html>
Both of default js files and custom js files will be called in index.html.
<!DOCTYPE html>
<html>
<body>
Hello World
</body>
<!-- Calling default scripts + custom scripts -->
<div>
<!-- /* default js + custom js files */ -->
<script src="/js/defaul1.min.js"></script>
<script src="/js/defaul2.min.js"></script>
<script src="/js/defaul3.min.js"></script>
<script src="/js/customjs1.min.js"></script>
<script src="/js/customjs2.min.js"></script>
<script src="/js/customjs3.min.js"></script>
</div>
</html>
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