Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thymeleaf layout dialect and th:replace in head causes title to be blank

I'm following this tutorial: http://www.thymeleaf.org/doc/layouts.html (got to Thymeleaf Layout Dialect section). In there you can find an example:

<!DOCTYPE html>
<html>
  <head>
  <!--/*  Each token will be replaced by their respective titles in the resulting page. */-->
    <title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Task List</title>
    ...
  </head>
  <body>
    <!--/* Standard layout can be mixed with Layout Dialect */-->
    <div th:replace="fragments/header :: header">
    ...
    </div>
    <div class="container">
      <div layout:fragment="content">
      ...
      </div>
      <div th:replace="fragments/footer :: footer">&copy; 2014 The Static Templates</div>
    </div>
  </body>
</html>

Footer and header are replaced by th:replace tag in above example, while <head> has <title> tag in layout file.

Basically, I want to replace whole <head> tag with th:replace. Therefore, I have:

My layout file:

<!DOCTYPE html>
<html>
<head th:replace="/html/components/head :: head">
</head>
<body>
     <div layout:fragment="content">
     </div>
...
     <div th:replace="/html/components/footer :: footer" />
</body>
<html>

My content file:

<!DOCTYPE html>
<html layout:decorator="/html/layouts/layout">
<head>
    <title>My content title</title>
</head>
<body>
      <div layout:fragment="content">
      ...
      </div>
</body>
</html>

And finally my /html/components/head.htm file:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head th:fragment="head">
<meta charset="utf-8" />
<title layout:title-pattern="$CONTENT_TITLE">Layout Title should be replaced by Content Title!</title>
...
</head>
<body>
</body>
</html>

Content is alright. Footer and head are included (replaced) from files as expected but page title is blank!

I get:

<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title></title>
...

What's wrong?

like image 526
iaforek Avatar asked Oct 29 '14 16:10

iaforek


2 Answers

Finally, I've found a way to achieve what I wanted.

In layout file <title> tag must stay. All other tags I grouped with <object> tag and annotated it as follows:

<head>
  <title layout:title-pattern="$CONTENT_TITLE">Layout Title will be replaced by Page Title!</title>
  <object th:include="/html/components/head :: head" th:remove="tag" />
</head>

In my html/components/head.htm file I had to remove <title> tag so it won't be duplicated after include.

<head th:fragment="head">
  <meta charset="utf-8" />
  <!-- NO TITLE TAG HERE -->
  ...
</head>

This way head fragment is included in <object> tag and thanks to th:remove="tag" <object> tag gets removed and my final HTML output is:

<head>
  <title>My content title</title>
  <meta charset="utf-8" />
  <!--  NO TITLE TAG HERE -->
  ...
</head>

Obviously, I removed NO TITLE TAG HERE message too, once I got it working.

like image 72
iaforek Avatar answered Sep 17 '22 20:09

iaforek


I think I found a slightly less verbose way to for using th:replace and th:fragment together, e.g. to include common <head> metadata and static resource includes in your pages.

Put the th:remove="tag" in the fragment definition, so you don't have to repeat the th:remove="tag" everytime including it.

fragment_head.html

<thymeleaf xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" 
    th:fragment="head" th:remove="tag">

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" th:href="@{/css/vendor/bootstrap.min.css}"/>

</thymeleaf>

mypage.html

<head>
    <thymeleaf th:replace="fragment_head :: head" />
</head>
like image 44
user2704917 Avatar answered Sep 17 '22 20:09

user2704917