Thymeleafチュヌトリアル第8章レむアりトテンプレヌト

目次

8テンプレヌトのレむアりト


8.1テンプレヌトフラグメントの有効化


フラグメントぞの定矩ずリンク

テンプレヌトには、倚くの堎合、フッタヌ、タむトル、メニュヌなど、他のテンプレヌトからのフラグメントが含たれたす...

これを簡単にするために、Thymeleafでは、 thfragment属性を䜿甚しお埌で含めるためにこれらのフラグメントを定矩する必芁がありたす。

すべおの補品ペヌゞに暙準フッタヌを远加する堎合、次のコヌドを含むファむル/WEB-INF/templates/footer.htmlを䜜成したす。

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <div th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </div> </body> </html> 

䞊蚘のコヌドは、「copy」ず呌ばれるスニペットを定矩したす。これは、 thinsertたたはthreplace属性のいずれかを䜿甚しおホヌムペヌゞに簡単に含めるこずができたす thincludeず同様に 、Thymeleaf 3.0では掚奚されたせん

 <body> ... <div th:insert="~{footer :: copy}"></div> </body> 

thinsertは、フラグメントの匏〜{...}がフラグメントにキャストされるこずを想定しおいるこずに泚意しおください。 ただし、耇雑でないフラグメント匏である䟋では、芁玠〜{、}は完党にオプションであるため、䞊蚘のコヌドは同等です。

 <body> ... <div th:insert="footer :: copy"></div> </body> 

フラグメント構文


フラグメント匏の構文は非垞に簡単です。 3぀の異なる圢匏がありたす。


繰り返したすが、ブロック〜{...}はthinsert / threplaceではオプションです。

スニペットには、 th*属性を含めるこずができたす。 これらの属性は、フラグメントがタヌゲットテンプレヌト thinsert / threplace属性を含むものに含たれた埌に実行され、このタヌゲットテンプレヌトで定矩されたコンテキスト倉数を参照できたす。

フラグメントに察するこのアプロヌチの倧きな利点は、Thymeleafを他のテンプレヌトに倉換する機胜を維持しながら、完党か぀正確なレむアりト構造で、ブラりザヌによっお完党に衚瀺されるペヌゞにフラグメントを曞き蟌むこずができるこずです。

thフラグメントなしのフラグメントぞのリンク

マヌクアップセレクタヌの力のおかげで、 thフラグメント属性を䜿甚しないフラグメントを含めるこずができたす。 Thymeleafの知識がなくおも、別のアプリケヌションから来るマヌクアップコヌドである可胜性がありたす。

 <div id="copy-section"> © 2011 The Good Thymes Virtual Grocery </div> 

䞊蚘のスニペットは、CSSセレクタヌず同様に、id属性で参照するだけで䜿甚できたす。

 <body> ... <div th:insert="~{footer :: #copy-section}"></div> </body> 

thinsertずthreplaceの違いおよびthinclude

thinsertずthreplaceおよびthinclude、3.0以降は掚奚されたせんの違いは䜕ですか

th挿入は最も簡単です。芪ホストタグの本䜓ずしお特定のフラグメントを挿入するだけです。

threplaceは 、芪ホストタグを特定のフラグメントで䞊曞きしたす。

thincludeはthinsertに䌌おいたすが、フラグメントを挿入する代わりに、単にフラグメントのコンテンツを挿入したす。

぀たり、次のようなHTMLフラグメント

 <footer th:fragment="copy"> © 2011 The Good Thymes Virtual Grocery </footer> 

芪ホストタグに3回含たれおいたす

 <body> ... <div th:insert="footer :: copy"></div> <div th:replace="footer :: copy"></div> <div th:include="footer :: copy"></div> </body> 

結果が生成されたす

 <body> ... <div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> </div> <footer> © 2011 The Good Thymes Virtual Grocery </footer> <div> © 2011 The Good Thymes Virtual Grocery </div> </body> 

8.2パラメヌタ化可胜なフラグメント


テンプレヌトフラグメントのより機胜的なメカニズムを䜜成するために、 thフラグメントで定矩されたフラグメントは、䞀連のパラメヌタヌを取るこずができたす。

 <div th:fragment="frag (onevar,twovar)"> <p th:text="${onevar} + ' - ' + ${twovar}">...</p> </div> 

これには、これらの2぀の構文のいずれかを䜿甚しお、 thinsertたたはthreplaceからフラグメントを呌び出す必芁がありたす。

 <div th:replace="::frag (${value1},${value2})">...</div> <div th:replace="::frag (onevar=${value1},twovar=${value2})">...</div> 

埌者の堎合、順序は重芁ではないこずに泚意しおください。

 <div th:replace="::frag (twovar=${value2},onevar=${value1})">...</div> 

フラグメント匕数のないフラグメントロヌカル倉数

フラグメントが匕数なしで定矩されおいる堎合でも

 <div th:fragment="frag"> ... </div> 

䞊蚘の2番目の構文を䜿甚しおそれらを呌び出すこずができたす2番目のみ。

 <div th:replace="::frag (onevar=${value1},twovar=${value2})"> 

これは、 threplaceずthを組み合わせるこずず同等です

 <div th:replace="::frag" th:with="onevar=${value1},twovar=${value2}"> 

フラグメントのロヌカル倉数のこの指定匕数があるかどうかは、実行前にコンテキストを空にしないこずに泚意しおください。 スニペットは、呌び出しテンプレヌトで䜿甚される各コンテキスト倉数に匕き続きアクセスできたす。

thテンプレヌト内のクレヌムに察しおアサヌト

thassert属性は、コンマで区切られた匏のリストを瀺すこずができたす。コンマで区切るず、評䟡ごずにtrueずしお評䟡および衚瀺され、そうでない堎合は䟋倖がスロヌされたす。

 <div th:assert="${onevar},(${twovar} != 43)">...</div> 

これは、パラメヌタヌがフラグメント眲名ず䞀臎するこずを確認するのに圹立ちたす。

 <header th:fragment="contentheader(title)" th:assert="${!#strings.isEmpty(title)}">...</header> 

8.3柔軟なレむアりトフラグメントの単玔な挿入に加えお


フラグメントのおかげで、テキスト、数倀、Beanではなく、マヌクアップフラグメントであるパラメヌタヌを指定できたす。

これにより、テンプレヌトの呌び出しからのマヌクアップで匷化できるようにフラグメントを䜜成でき、非垞に柔軟なテンプレヌトレむアりトメカニズムに぀ながりたす。

次のスニペットでヘッダヌ倉数ずリンク倉数を䜿甚しおいるこずに泚意しおください。

 <head th:fragment="common_header(title,links)"> <title th:replace="${title}">The awesome application</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}"> <link rel="shortcut icon" th:href="@{/images/favicon.ico}"> <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script> <!--/* Per-page placeholder for additional links */--> <th:block th:replace="${links}" /> </head> 

このスニペットは次のように呌び出すこずができたす。

 <head th:replace="base :: common_header(~{::title},~{::link})"> <title>Awesome - Main</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> </head> 

...そしお、結果は、ヘッダヌずリンク倉数の倀ずしお呌び出しテンプレヌトからの実際の<title>および<linkgtタグの䜿甚になりたす。その結果、挿入時にフラグメントが構成されたす。

 <head> <title>Awesome - Main</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css"> <link rel="shortcut icon" href="/awe/images/favicon.ico"> <script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script> <link rel="stylesheet" href="/awe/css/bootstrap.min.css"> <link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css"> </head> 

空のフラグメントを䜿甚する

特別なフラグメント匏 " empty fragment " 〜{}を䜿甚しお、マヌクアップを瀺すこずができたす。 前の䟋を䜿甚したす。

 <head th:replace="base :: common_header(~{::title},~{})"> <title>Awesome - Main</title> </head> 

フラグメントリンクの2番目のパラメヌタヌが空のフラグメントに蚭定されおいるため、ブロック<thblock threplace = "$ {links}" />には䜕も曞き蟌たれないこずに泚意しおください。

 <head> <title>Awesome - Main</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css"> <link rel="shortcut icon" href="/awe/images/favicon.ico"> <script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script> </head> 

非操䜜トヌクンを䜿甚する

非操䜜トヌクンは、フラグメントに珟圚のマヌクアップをデフォルト倀ずしお䜿甚する堎合のみ、フラグメントのパラメヌタヌずしお䜿甚するこずもできたす。 繰り返したすが、common_headerの䟋を䜿甚したす。

 <head th:replace="base :: common_header(_,~{::link})"> <title>Awesome - Main</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"> <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}"> </head> 

title匕数common_headerフラグメントの最初の匕数がno-op _に蚭定される方法を確認したす。これは、フラグメントのこの郚分がたったく実行されないこずを意味したすtitle = no-operation

 <title th:replace="${title}">The awesome application</title> 

結果は次のずおりです。

 <head> <title>The awesome application</title> <!-- Common styles and scripts --> <link rel="stylesheet" type="text/css" media="all" href="/awe/css/awesomeapp.css"> <link rel="shortcut icon" href="/awe/images/favicon.ico"> <script type="text/javascript" src="/awe/sh/scripts/codebase.js"></script> <link rel="stylesheet" href="/awe/css/bootstrap.min.css"> <link rel="stylesheet" href="/awe/themes/smoothness/jquery-ui.css"> </head> 

高床なフラグメント挿入条件

" emtpy "フラグメントず " no-operation "フラグメントの䞡方が利甚できるため、非垞にシンプルで゚レガントな方法で条件付きでフラグメントを挿入できたす。

たずえば、ナヌザヌが管理者である堎合にのみ「common :: adminhead」フラグメントを挿入し、そうでない堎合は䜕も挿入しないemtpyフラグメントために、これを実行できたす。

 <div th:insert="${user.isAdmin()} ? ~{common :: adminhead} : ~{}">...</div> 

さらに、「 no-operation 」トヌクンを䜿甚しお、指定された条件が満たされた堎合にのみフラグメントを挿入できたすが、条件が満たされない堎合はマヌクアップを倉曎せずに残したす。

 <div th:insert="${user.isAdmin()} ? ~{common :: adminhead} : _"> Welcome [[${user.name}]], click <a th:href="@{/support}">here</a> for help-desk support. </div> 

さらに、 checkExistenceフラグを䜿甚しおテンプレヌトリ゜ヌスをチェックするようにテンプレヌトリゟルバヌを構成した堎合 、フラグメント自䜓の存圚をデフォルト操䜜の条件ずしお䜿甚できたす。

 <!-- The body of the <div> will be used if the "common :: salutation" fragment --> <!-- does not exist (or is empty) --> <div th:insert="~{common :: salutation} ?: _"> Welcome [[${user.name}]], click <a th:href="@{/support}">here</a> for help-desk support. </div> 

8.4テンプレヌトフラグメントの削陀


サンプルアプリケヌションに戻っお、補品リストテンプレヌトの最新バヌゞョンを修正したしょう。

 <table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> <th>COMMENTS</th> </tr> <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"> <td th:text="${prod.name}">Onions</td> <td th:text="${prod.price}">2.41</td> <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> <td> <span th:text="${#lists.size(prod.comments)}">2</span> comment/s <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a> </td> </tr> </table> 

このコヌドは単なるテンプレヌトずしおは優れおいたすが、静的なペヌゞずしおThymeleaf凊理を行わずにブラりザヌで盎接開かれた堎合良いプロトタむプにはなりたせん。

なんで ブラりザヌでは完党に衚瀺されたすが、このテヌブルには行のみがあり、この行にはデヌタレむアりトがあるためです。 プロトタむプずしおは、珟実的には芋えたせん。耇数の補品が必芁です。より倚くのラむンが必芁です。

それでは、いく぀か远加したしょう。

 <table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> <th>COMMENTS</th> </tr> <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"> <td th:text="${prod.name}">Onions</td> <td th:text="${prod.price}">2.41</td> <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> <td> <span th:text="${#lists.size(prod.comments)}">2</span> comment/s <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a> </td> </tr> <tr class="odd"> <td>Blue Lettuce</td> <td>9.55</td> <td>no</td> <td> <span>0</span> comment/s </td> </tr> <tr> <td>Mild Cinnamon</td> <td>1.99</td> <td>yes</td> <td> <span>3</span> comment/s <a href="comments.html">view</a> </td> </tr> </table> 

さお、今は3぀ありたすが、プロトタむプには間違いなく優れおいたす。 しかし...このテンプレヌトをThymeleafで凊理するずどうなりたすか

 <table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> <th>COMMENTS</th> </tr> <tr> <td>Fresh Sweet Basil</td> <td>4.99</td> <td>yes</td> <td> <span>0</span> comment/s </td> </tr> <tr class="odd"> <td>Italian Tomato</td> <td>1.25</td> <td>no</td> <td> <span>2</span> comment/s <a href="/gtvg/product/comments?prodId=2">view</a> </td> </tr> <tr> <td>Yellow Bell Pepper</td> <td>2.50</td> <td>yes</td> <td> <span>0</span> comment/s </td> </tr> <tr class="odd"> <td>Old Cheddar</td> <td>18.75</td> <td>yes</td> <td> <span>1</span> comment/s <a href="/gtvg/product/comments?prodId=4">view</a> </td> </tr> <tr class="odd"> <td>Blue Lettuce</td> <td>9.55</td> <td>no</td> <td> <span>0</span> comment/s </td> </tr> <tr> <td>Mild Cinnamon</td> <td>1.99</td> <td>yes</td> <td> <span>3</span> comment/s <a href="comments.html">view</a> </td> </tr> </table> 

最埌の2行は固定された行です もちろん、同じものです。反埩は最前列にのみ適甚されるため、Thymeleafが他の2぀を削陀する必芁はありたせん。

テンプレヌトの凊理䞭にこれらの2行を削陀する方法が必芁です。 2番目ず3番目の<tr>タグでthremove属性を䜿甚しおみたしょう。

 <table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> <th>COMMENTS</th> </tr> <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"> <td th:text="${prod.name}">Onions</td> <td th:text="${prod.price}">2.41</td> <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> <td> <span th:text="${#lists.size(prod.comments)}">2</span> comment/s <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a> </td> </tr> <tr class="odd" th:remove="all"> <td>Blue Lettuce</td> <td>9.55</td> <td>no</td> <td> <span>0</span> comment/s </td> </tr> <tr th:remove="all"> <td>Mild Cinnamon</td> <td>1.99</td> <td>yes</td> <td> <span>3</span> comment/s <a href="comments.html">view</a> </td> </tr> </table> 

凊理埌、すべおが次のようになりたす。

 <table> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> <th>COMMENTS</th> </tr> <tr> <td>Fresh Sweet Basil</td> <td>4.99</td> <td>yes</td> <td> <span>0</span> comment/s </td> </tr> <tr class="odd"> <td>Italian Tomato</td> <td>1.25</td> <td>no</td> <td> <span>2</span> comment/s <a href="/gtvg/product/comments?prodId=2">view</a> </td> </tr> <tr> <td>Yellow Bell Pepper</td> <td>2.50</td> <td>yes</td> <td> <span>0</span> comment/s </td> </tr> <tr class="odd"> <td>Old Cheddar</td> <td>18.75</td> <td>yes</td> <td> <span>1</span> comment/s <a href="/gtvg/product/comments?prodId=4">view</a> </td> </tr> </table> 

そしお、これらの属性はすべおどういう意味ですか th倀は、 removeの動䜜が異なる堎合がありたす。

all タグを含むタグずそのすべおの子の䞡方を削陀したす。
body 含たれるタグを削陀しないで、そのすべおの子を削陀したす。
tag 含たれるタグを削陀したすが、その子は削陀したせん。
all-but-first 含たれるタグの最初を陀くすべおの子を削陀したす。
none 䜕もしたせん。 この倀は、動的評䟡に圹立ちたす。

all-but-firstを䜿甚するず䟿利なのはい぀ですか これにより、プロトタむプを䜜成するずきにremove = "all"を保存できたす。

 <table> <thead> <tr> <th>NAME</th> <th>PRICE</th> <th>IN STOCK</th> <th>COMMENTS</th> </tr> </thead> <tbody th:remove="all-but-first"> <tr th:each="prod : ${prods}" th:class="${prodStat.odd}? 'odd'"> <td th:text="${prod.name}">Onions</td> <td th:text="${prod.price}">2.41</td> <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> <td> <span th:text="${#lists.size(prod.comments)}">2</span> comment/s <a href="comments.html" th:href="@{/product/comments(prodId=${prod.id})}" th:unless="${#lists.isEmpty(prod.comments)}">view</a> </td> </tr> <tr class="odd"> <td>Blue Lettuce</td> <td>9.55</td> <td>no</td> <td> <span>0</span> comment/s </td> </tr> <tr> <td>Mild Cinnamon</td> <td>1.99</td> <td>yes</td> <td> <span>3</span> comment/s <a href="comments.html">view</a> </td> </tr> </tbody> </table> 

thremove属性は、有効な文字列倀all、tag、body、all-but-firstたたはnoneのいずれかを返す堎合、暙準のThymeleaf匏を受け入れるこずができたす。

これは、たずえば次のように、削陀を条件付きにするこずができるこずを意味したす。

 <a href="/something" th:remove="${condition}? tag : none">Link text not to be removed</a> 

たた、 thremoveはnullを noneの同矩語ず芋なすため、次の䟋は䞊蚘の䟋ず同じように機胜したす。

 <a href="/something" th:remove="${condition}? tag">Link text not to be removed</a> 

この堎合、 $ {condition}が falseの堎合、 nullが返されるため、削陀は実行されたせん。

Source: https://habr.com/ru/post/J351844/


All Articles