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

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

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

  1. <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">
  2. <head>
  3. <!-- 必需的元标签 -->
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  6. <!-- Bootstrap CSS -->
  7. <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css">
  8. <link rel="stylesheet" type="text/css" href="css/bootstrap-4.3.1-dist/css/bootstrap.min.css">
  9. <link rel="stylesheet" type="text/css" href="css/logincss.css">
  10. </head>
  11. <body class="signin-body">
  12. <div layout:fragment="content">
  13. <div class="container signin-container">
  14. <!-- 其他部分已略 -->
  15. </div>
  16. </div>
  17. <!-- 其他部分已略 -->
  18. </body>
  19. </html>

main.html

  1. <!doctype html>
  2. <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">
  3. <head>
  4. <!-- 必需的元标签和链接 -->
  5. </head>
  6. <body>
  7. <div class="main-container">
  8. <!-- 菜单栏部分已略 -->
  9. <div layout:fragment="content">
  10. </div>
  11. </div>
  12. <!-- 页脚部分已略 -->
  13. </body>
  14. </html>

WebConf.java

  1. @Configuration
  2. public class WebConf implements WebMvcConfigurer {
  3. @Override
  4. public void addViewControllers(ViewControllerRegistry registry) {
  5. registry.addViewController("/login").setViewName("auth/login");
  6. registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
  7. }
  8. }
英文:

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

  1. &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;
  2. &lt;head&gt;
  3. &lt;!-- Required meta tags --&gt;
  4. &lt;meta charset=&quot;utf-8&quot;&gt;
  5. &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, shrink-to-fit=no&quot;&gt;
  6. &lt;!-- Bootstrap CSS --&gt;
  7. &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;
  8. &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;
  9. &lt;!--We are choosing these two to let the browser to load faster--&gt;
  10. &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/logincss.css&quot;&gt;
  11. &lt;!--this is the last one so that we can override previous boostrap styles if we want--&gt;
  12. &lt;head&gt;
  13. &lt;body class=&quot;signin-body&quot;&gt;
  14. &lt;div layout:fragment=&quot;content&quot;&gt;
  15. &lt;div class=&quot;container signin-container&quot;&gt;
  16. &lt;div class=&quot;row&quot;&gt;
  17. &lt;div class=&quot;col&quot;&gt;&lt;/div&gt;
  18. &lt;div class=&quot;col-sm-12 col-md-8&quot;&gt;
  19. &lt;div class=&quot;card signin-card&quot;&gt;
  20. &lt;div class=&quot;card-block&quot;&gt;
  21. &lt;form name=&quot;login&quot; th:action=&quot;@{/login}&quot; method=&quot;post&quot; class=&quot;signin-form&quot;&gt;
  22. &lt;div class=&quot;form-group&quot;&gt;
  23. &lt;h2 class=&quot;form-signin-heading&quot;&gt;Please sign in&lt;/h2&gt;
  24. &lt;div th:if=&quot;${param.error}&quot; class=&quot;alert alert-danger&quot;&gt;Wrong username and password&lt;/div&gt;
  25. &lt;div th:if=&quot;${param.logout}&quot; class=&quot;alert alert-success&quot;&gt;You successfully logged out&lt;/div&gt;
  26. &lt;label for=&quot;username&quot; class=&quot;sr-only&quot;&gt;Username&lt;/label&gt;
  27. &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;
  28. &lt;label for=&quot;password&quot; class=&quot;sr-only&quot;&gt;Password&lt;/label&gt;
  29. &lt;div class=&quot;form-group&quot;&gt;
  30. &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;
  31. &lt;/div&gt;
  32. &lt;/div&gt;
  33. &lt;button class=&quot;btn btn-lg btn-primary btn-block signin-btn&quot; type=&quot;submit&quot;&gt;Login&lt;/button&gt;
  34. &lt;div class=&quot;custom-control custom-checkbox&quot;&gt;
  35. &lt;input type=&quot;checkbox&quot; class=&quot;custom-control-input&quot; id=&quot;customCheck1&quot;&gt;
  36. &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;
  37. &lt;a class=&quot;new-account&quot; href=&quot;/registration&quot;&gt;Create New Account&lt;/a&gt;
  38. &lt;/div&gt;
  39. &lt;/form&gt;
  40. &lt;/div&gt;
  41. &lt;/div&gt;
  42. &lt;/div&gt;
  43. &lt;div class=&quot;col&quot;&gt;&lt;/div&gt;
  44. &lt;/div&gt;
  45. &lt;/div&gt;
  46. &lt;/div&gt;
  47. &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;
  48. &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js&quot;&gt;&lt;/script&gt;
  49. &lt;script src=&quot;css/bootstrap-4.3.1-dist/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
  50. &lt;/body&gt;
  51. &lt;/html&gt;

main.html

  1. &lt;!doctype html&gt;
  2. &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;
  3. &lt;head&gt;
  4. &lt;!-- Required meta tags --&gt;
  5. &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  6. &lt;!-- &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css&quot;&gt; --&gt;
  7. &lt;!-- &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js&quot;&gt;&lt;/script&gt; --&gt;
  8. &lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
  9. &lt;script src=&quot;https://kit.fontawesome.com/2dafcd6f62.js&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  10. &lt;!-- Bootstrap CSS // Let&#39;s connect the CSS to the grid system --&gt;
  11. &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;
  12. &lt;!--CSS--&gt;
  13. &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;
  14. &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;
  15. &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;
  16. &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;
  17. &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;
  18. &lt;/head&gt;
  19. &lt;body&gt;
  20. &lt;div class=&quot;main-container&quot;&gt;
  21. &lt;!-- ########## MENU BAR ########## --&gt;
  22. &lt;nav class=&quot;navbar navbar-expand-sm bg-dark navbar-dark sticky-top&quot;&gt;
  23. &lt;a class=&quot;navbar-brand&quot; href=&quot;#&quot;&gt;MENU&lt;/a&gt;
  24. &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;
  25. &lt;span class=&quot;navbar-toggler-icon&quot;&gt;&lt;/span&gt;
  26. &lt;/button&gt;
  27. &lt;div class=&quot;collapse navbar-collapse&quot; id=&quot;navbarNavDropdown&quot;&gt;
  28. &lt;ul class=&quot;navbar-nav&quot;&gt;
  29. &lt;li class=&quot;nav-item active&quot;&gt;&lt;/li&gt;
  30. &lt;li class=&quot;nav-item&quot;&gt;
  31. &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;
  32. &lt;/li&gt;
  33. &lt;li class=&quot;nav-item dropdown&quot;&gt;
  34. &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;
  35. qualification or something
  36. &lt;/a&gt;
  37. &lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;navbarDropdownMenuLink&quot;&gt;
  38. &lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot; th:text=&quot;${it}&quot;&gt;Some text...&lt;/a&gt;
  39. &lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot; th:text=&quot;${vaadin}&quot;&gt;Some text...&lt;/a&gt;
  40. &lt;a class=&quot;dropdown-item&quot; href=&quot;#&quot; th:text=&quot;${java}&quot;&gt;Some text...&lt;/a&gt;
  41. &lt;/div&gt;
  42. &lt;/li&gt;
  43. &lt;li class=&quot;nav-item dropdown&quot;&gt;
  44. &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;
  45. some text...
  46. &lt;/a&gt;
  47. &lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;navbarDropdownMenuLink&quot;&gt;
  48. &lt;a class=&quot;dropdown-item&quot; href=&quot;pdf/modulzaro.pdf&quot; th:text=&quot;${exam}&quot;&gt;some text...&lt;/a&gt;
  49. &lt;/div&gt;
  50. &lt;/li&gt;
  51. &lt;/ul&gt;
  52. &lt;/div&gt;
  53. &lt;form th:action=&quot;@{/logout}&quot; method=&quot;post&quot;&gt;
  54. &lt;input class=&quot;button-logout&quot; type=&quot;submit&quot; value=&quot;Log Out&quot; /&gt;
  55. &lt;/form&gt;
  56. &lt;/nav&gt;
  57. &lt;div layout:fragment=&quot;content&quot;&gt;
  58. &lt;/div&gt;
  59. &lt;/div&gt;
  60. &lt;!--FOOTER--&gt;
  61. &lt;footer class=&quot;footer bg-dark&quot;&gt;
  62. &lt;!--we can put here our own container--&gt;
  63. &lt;div class=&quot;container-fluid&quot;&gt;
  64. &lt;div class=&quot;row&quot;&gt;
  65. &lt;div class=&quot;col-sm-12 col-lg-3 socialWrapper&quot;&gt;
  66. &lt;p class=&quot;contact&quot;&gt;Email:
  67. &lt;br&gt;Phone: &lt;/p&gt;
  68. &lt;/div&gt;
  69. &lt;div class=&quot;col-sm-12 col-lg-9 footer-font-icons&quot;&gt;
  70. &lt;a href=&quot;#&quot; target=&quot;_blank&quot;&gt;
  71. &lt;!--target=&quot;_blank&quot; will open our github page on a new page--&gt;
  72. &lt;i class=&quot;fa fa-github-square fa-3x&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt;&lt;/a&gt;
  73. &lt;a href=&quot;#&quot; target=&quot;_blank&quot;&gt;
  74. &lt;i class=&quot;fa fa-stack-overflow fa-3x&quot; aria-hidden=&quot;true&quot;&gt;&lt;/i&gt;&lt;/a&gt;
  75. &lt;/div&gt;
  76. &lt;/div&gt;
  77. &lt;/div&gt;
  78. &lt;/footer&gt;
  79. &lt;!-- Optional JavaScript --&gt;
  80. &lt;!-- jQuery first, then Popper.js, then Bootstrap JS --&gt;
  81. &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;
  82. &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;
  83. &lt;script src=&quot;css/bootstrap-4.3.1-dist/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
  84. &lt;/body&gt;
  85. &lt;/html&gt;

WebConf.java

  1. @Configuration
  2. public class WebConf implements WebMvcConfigurer {
  3. @Override
  4. public void addViewControllers(ViewControllerRegistry registry) {
  5. registry.addViewController(&quot;/login&quot;).setViewName(&quot;auth/login&quot;);
  6. registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
  7. }
  8. }

答案1

得分: 1

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

我忘记添加以下依赖项:

  1. <dependency>
  2. <groupId>nz.net.ultraq.thymeleaf</groupId>
  3. <artifactId>thymeleaf-layout-dialect</artifactId>
  4. </dependency>

现在它可以正常工作了。

英文:

Ok, I found the source of the issue:

I forgot to add the following dependency:

  1. &lt;dependency&gt;
  2. &lt;groupId&gt;nz.net.ultraq.thymeleaf&lt;/groupId&gt;
  3. &lt;artifactId&gt;thymeleaf-layout-dialect&lt;/artifactId&gt;
  4. &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:

确定