如何正确在Spring Boot中使用Thymeleaf的layout:fragment功能?

huangapple go评论79阅读模式
英文:

How to use Thymeleaf layout:fragment with Spring Boot properly?

问题

我是你的中文翻译,以下为翻译好的内容:

我是否误解了问题,三天内没有得到任何答案?

在我的项目中,Thymeleaf基本上是有效的,但是layout:fragment在我尝试的方式下无法正常工作。可能是我做错了什么,我阅读了类似的主题,但我需要一些帮助。我希望login.html具有与main.html中定义的相同的导航栏和页脚。

main.html位于/templates/layouts,而login.html位于/templates/auth。

更新

装饰器是main.html,我在body中放置了<div layout:fragment="content">,其中内容应该被放置。
我尝试过在login.html的标签中放置layout:decorator="layouts/main">,并在body标签下放置layout:fragment="content"

login.html

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" lang="en" layout:decorator="layouts/main">

<head>
  <!-- 必需的元标签 -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css">
  <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap.min.css">
  <link rel="stylesheet" type="text/css" href="css/logincss.css">
</head>

<body class="signin-body">
  <div layout:fragment="content">
    <div class="container signin-container">
      <!-- 其他部分已略 -->
    </div>
  </div>
  <!-- 其他部分已略 -->
</body>

</html>

main.html

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<head>
  <!-- 必需的元标签和链接 -->
</head>

<body>
  <div class="main-container">
    <!-- 菜单栏部分已略 -->
    <div layout:fragment="content">
    </div>
  </div>
  <!-- 页脚部分已略 -->
</body>

</html>

WebConf.java

@Configuration
public class WebConf implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("auth/login");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }
}
英文:

Did I take the question wrong that I haven'T gotten any answer for 3 days?

Thymeleaf is working basically in my project but layout:fragment doesn't want to work the way as I tried. Probably I'm doing something wrong and I read similar topics but I'd need some help with that. I'd like the login.html has the same nav bar and footer that's defined in main.html

main.html is in the /templates/layouts and login.html is in /templates/auth

UPDATE

The decorator is the main.html where I put &lt;div layout:fragment=&quot;content&quot;&gt; in the body where the content suppose to get.
What I tried is that I put layout:decorator=&quot;layouts/main&quot;&gt; in the login's html tag and layout:fragment=&quot;content&quot; under the body tag.

login.html

&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xmlns:th=&quot;http://www.thymeleaf.org&quot; xmlns:sec=&quot;http://www.thymeleaf.org/thymeleaf-extras-springsecurity3&quot; xmlns:layout=&quot;http://www.ultraq.net.nz/thymeleaf/layout&quot; lang=&quot;en&quot; layout:decorator=&quot;layouts/main&quot;&gt;

&lt;head&gt;
  &lt;!-- Required meta tags --&gt;
  &lt;meta charset=&quot;utf-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, shrink-to-fit=no&quot;&gt;

  &lt;!-- Bootstrap CSS --&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css&quot;&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap.min.css&quot;&gt;
  &lt;!--We are choosing these two to let the browser to load faster--&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/logincss.css&quot;&gt;
  &lt;!--this is the last one so that we can override previous boostrap styles if we want--&gt;
&lt;head&gt;

&lt;body class=&quot;signin-body&quot;&gt;
  &lt;div layout:fragment=&quot;content&quot;&gt;
    &lt;div class=&quot;container signin-container&quot;&gt;
      &lt;div class=&quot;row&quot;&gt;
        &lt;div class=&quot;col&quot;&gt;&lt;/div&gt;
        &lt;div class=&quot;col-sm-12 col-md-8&quot;&gt;
          &lt;div class=&quot;card signin-card&quot;&gt;
            &lt;div class=&quot;card-block&quot;&gt;
              &lt;form name=&quot;login&quot; th:action=&quot;@{/login}&quot; method=&quot;post&quot; class=&quot;signin-form&quot;&gt;
                &lt;div class=&quot;form-group&quot;&gt;
                  &lt;h2 class=&quot;form-signin-heading&quot;&gt;Please sign in&lt;/h2&gt;
                  &lt;div th:if=&quot;${param.error}&quot; class=&quot;alert alert-danger&quot;&gt;Wrong username and password&lt;/div&gt;
                  &lt;div th:if=&quot;${param.logout}&quot; class=&quot;alert alert-success&quot;&gt;You successfully logged out&lt;/div&gt;
                  &lt;label for=&quot;username&quot; class=&quot;sr-only&quot;&gt;Username&lt;/label&gt;
                  &lt;input type=&quot;text&quot; id=&quot;username&quot; name=&quot;username&quot; class=&quot;form-control&quot; placeholder=&quot;Username&quot; required=&quot;true&quot;&gt;
                  &lt;label for=&quot;password&quot; class=&quot;sr-only&quot;&gt;Password&lt;/label&gt;
                  &lt;div class=&quot;form-group&quot;&gt;
                    &lt;input type=&quot;password&quot; id=&quot;password&quot; name=&quot;password&quot; class=&quot;form-control&quot; placeholder=&quot;Password&quot; required=&quot;true&quot;&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
                &lt;button class=&quot;btn btn-lg btn-primary btn-block signin-btn&quot; type=&quot;submit&quot;&gt;Login&lt;/button&gt;
                &lt;div class=&quot;custom-control custom-checkbox&quot;&gt;
                  &lt;input type=&quot;checkbox&quot; class=&quot;custom-control-input&quot; id=&quot;customCheck1&quot;&gt;
                  &lt;!-- &lt;label class=&quot;custom-control-label&quot; for=&quot;customCheck1&quot;&gt;Remember me &lt;a href=&quot;#&quot;&gt; Need help?&lt;/a&gt;&lt;/label&gt; --&gt;
                  &lt;a class=&quot;new-account&quot; href=&quot;/registration&quot;&gt;Create New Account&lt;/a&gt;
                &lt;/div&gt;
              &lt;/form&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;col&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;script src=&quot;https://code.jquery.com/jquery-3.3.1.slim.min.js&quot; integrity=&quot;sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;css/bootstrap-4.3.1-dist/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;

main.html

&lt;!doctype html&gt;
&lt;html xmlns:th=&quot;http://www.thymeleaf.org&quot; xmlns:sec=&quot;http://www.thymeleaf.org/extras/spring-security&quot; xmlns:layout=&quot;http://www.ultraq.net.nz/thymeleaf/layout&quot;&gt;
&lt;head&gt;
&lt;!-- Required meta tags --&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
&lt;!-- &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css&quot;&gt; --&gt;
&lt;!-- &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://kit.fontawesome.com/2dafcd6f62.js&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;!-- Bootstrap CSS // Let&#39;s connect the CSS to the grid system --&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap.min.css&quot;&gt;
&lt;!--CSS--&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/style.css&quot; th:href=&quot;@{css/style.css}&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css&quot; th:href=&quot;@{css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css}&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/bootstrap-4.3.1-dist/css/bootstrap.min.css&quot; th:href=&quot;@{css/bootstrap-4.3.1-dist/css/bootstrap.min.css}&quot;&gt;
&lt;link href=&quot;https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css&quot; rel=&quot;stylesheet&quot; integrity=&quot;sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN&quot; crossorigin=&quot;anonymous&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;main-container&quot;&gt;
&lt;!-- ########## MENU BAR ########## --&gt;
&lt;nav class=&quot;navbar navbar-expand-sm bg-dark navbar-dark sticky-top&quot;&gt;
&lt;a class=&quot;navbar-brand&quot; href=&quot;#&quot;&gt;MENU&lt;/a&gt;
&lt;button class=&quot;navbar-toggler&quot; type=&quot;button&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#navbarNavDropdown&quot; aria-controls=&quot;navbarNavDropdown&quot; aria-expanded=&quot;false&quot; aria-label=&quot;Toggle navigation&quot;&gt;
&lt;span class=&quot;navbar-toggler-icon&quot;&gt;&lt;/span&gt;
&lt;/button&gt;
&lt;div class=&quot;collapse navbar-collapse&quot; id=&quot;navbarNavDropdown&quot;&gt;
&lt;ul class=&quot;navbar-nav&quot;&gt;
&lt;li class=&quot;nav-item active&quot;&gt;&lt;/li&gt;
&lt;li class=&quot;nav-item&quot;&gt;
&lt;a class=&quot;nav-link&quot; href=&quot;#&quot; th:text=&quot;${references}&quot; target=&quot;_blank&quot;&gt;some text...&lt;/a&gt;
&lt;/li&gt;
&lt;li class=&quot;nav-item dropdown&quot;&gt;
&lt;a class=&quot;nav-link dropdown-toggle&quot; href=&quot;#&quot; id=&quot;navbarDropdownMenuLink&quot; role=&quot;button&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot; th:text=&quot;${qualifications}&quot;&gt;
qualification or something
&lt;/a&gt;
&lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;navbarDropdownMenuLink&quot;&gt;
&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot; th:text=&quot;${it}&quot;&gt;Some text...&lt;/a&gt;
&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot; th:text=&quot;${vaadin}&quot;&gt;Some text...&lt;/a&gt;
&lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot; th:text=&quot;${java}&quot;&gt;Some text...&lt;/a&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;nav-item dropdown&quot;&gt;
&lt;a class=&quot;nav-link dropdown-toggle&quot; href=&quot;#&quot; id=&quot;navbarDropdownMenuLink&quot; role=&quot;button&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot; th:text=&quot;${myproject}&quot;&gt;
some text...
&lt;/a&gt;
&lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;navbarDropdownMenuLink&quot;&gt;
&lt;a class=&quot;dropdown-item&quot; href=&quot;pdf/modulzaro.pdf&quot; th:text=&quot;${exam}&quot;&gt;some text...&lt;/a&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;form th:action=&quot;@{/logout}&quot; method=&quot;post&quot;&gt;
&lt;input class=&quot;button-logout&quot; type=&quot;submit&quot; value=&quot;Log Out&quot; /&gt;
&lt;/form&gt;
&lt;/nav&gt;
&lt;div layout:fragment=&quot;content&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!--FOOTER--&gt;
&lt;footer class=&quot;footer bg-dark&quot;&gt;
&lt;!--we can put here our own container--&gt;
&lt;div class=&quot;container-fluid&quot;&gt;
&lt;div class=&quot;row&quot;&gt;
&lt;div class=&quot;col-sm-12 col-lg-3 socialWrapper&quot;&gt;
&lt;p class=&quot;contact&quot;&gt;Email:
&lt;br&gt;Phone: &lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;col-sm-12 col-lg-9 footer-font-icons&quot;&gt;
&lt;a href=&quot;#&quot; target=&quot;_blank&quot;&gt;
&lt;!--target=&quot;_blank&quot; will open our github page on a new page--&gt;
&lt;i class=&quot;fa fa-github-square fa-3x&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt;&lt;/a&gt;
&lt;a href=&quot;#&quot; target=&quot;_blank&quot;&gt;
&lt;i class=&quot;fa fa-stack-overflow fa-3x&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/footer&gt;
&lt;!-- Optional JavaScript --&gt;
&lt;!-- jQuery first, then Popper.js, then Bootstrap JS --&gt;
&lt;script src=&quot;https://code.jquery.com/jquery-3.3.1.slim.min.js&quot; integrity=&quot;sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js&quot; integrity=&quot;sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;css/bootstrap-4.3.1-dist/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

WebConf.java

@Configuration
public class WebConf implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController(&quot;/login&quot;).setViewName(&quot;auth/login&quot;);
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}

答案1

得分: 1

好的,我找到了问题的根源:

我忘记添加以下依赖项:

<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

现在它可以正常工作了。

英文:

Ok, I found the source of the issue:

I forgot to add the following dependency:

&lt;dependency&gt;
&lt;groupId&gt;nz.net.ultraq.thymeleaf&lt;/groupId&gt;
&lt;artifactId&gt;thymeleaf-layout-dialect&lt;/artifactId&gt;
&lt;/dependency&gt;

Now it works.

huangapple
  • 本文由 发表于 2020年4月8日 00:08:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/61084415.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定