Thymeleaf: Layout de dialeto + Spring Boot 2

O dialeto Layout é um dialeto Thymeleaf que permite aos usuários criar layouts e modelos para reutilizar o código HTML. Ele tem uma abordagem hierárquica e usa um modelo de decorador para "decorar" arquivos de layout. O Dialect de layout é um projeto independente e não é fornecido com o Thymeleaf. No entanto, é de código aberto, disponível no GitHub, está bem documentado e parece também ser mantido em boas condições.

Instalação


Precisamos adicionar o pacote inicial do Thymeleaf ao seu pom Spring Boot:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 

No entanto, começando com o Spring Boot 2, isso não é mais suficiente. O dialeto Pom não faz parte do Spring Boot, e devemos adicioná-lo:

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

Os exemplos de código também usam o Bootstrap, portanto, você também precisa adicionar arquivos da web:

  <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.0.0</version> </dependency> 

Como etapa final, precisamos criar um bean LayoutDialect na classe anotada @Configuration.

  @Bean public LayoutDialect layoutDialect() { return new LayoutDialect(); } 

Vamos mais longe.

Exemplo de dialeto de layout


Este exemplo mostra como podemos usar o Dialeto de layout para definir layouts para nossas páginas, para que possamos reutilizar melhor o código: usando a página index.html, que usa layout.html como layout. O nome Layout.html é arbitrário e pode ser qualquer coisa. Mais alguns arquivos são adicionados lá, mas são apenas para demonstração.



A imagem mostra a estrutura da pasta de recursos. O Spring Boot encontrará automaticamente todos os modelos Thymeleaf no diretório resources / templates.

Layout.html


 <!DOCTYPE html> <html> <head> <title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">Igorski.co</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <link th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.min.css}" rel="stylesheet" media="screen" /> </head> <body> <div th:replace="fragments/header :: header"> This header content is going to be replaced.</div> <div class="container"> <div class="row"> <div class="col-2" layout:fragment="sidebar"> <h1>This is the layout's sidebar</h1> <p>This content will be replaced if the page using the layout also defines a layout:fragment="sidebar" segment.</p> </div> <div class="col" layout:fragment="content"> <h1>This is the Layout's main section</h1> <p>This content will be replaced if the page using the layout also defines a layout:fragment="content" segment. </p> </div> </div> </div> <footer th:insert="fragments/footer :: footer" class="footer"> This content will remain, but other content will be inserted after it. </footer> </body> </html> 

Layout.html usa dois dos cinco processadores fornecidos pelo Dialeto de layout. O primeiro é o layout: o processador do modelo de cabeçalho . O processador do modelo de cabeçalho ajuda o usuário a determinar o melhor título para a página resultante. Neste exemplo, define o título final como uma combinação do título da página e do cabeçalho do layout. Para isso, são usados ​​dois tokens especiais, apresentados no Dialeto de layout, $ LAYOUT_TITLE e $ CONTENT_TITLE .

Da maior importância em layout.html estão dois espaços reservados (ou fragmentos) definidos pelo layout: processador de fragmentos . Esse processador nos permite definir espaços reservados para conteúdo em nossos layouts. O conteúdo desses espaços reservados posteriormente será substituído pelo conteúdo das páginas usando o layout. O exemplo define dois fragmentos diferentes, um para a barra lateral e outro para o conteúdo principal. No entanto, podemos ter quantos fragmentos quisermos, desde que todos tenham nomes diferentes.

Index.html


  <!DOCTYPE html> <html xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="~{layouts/layout}"> <head> <title>Home Page</title> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link th:href="@{/css/core.css}" rel="stylesheet" media="screen" /> </head> <body> <div class="container"> <div class="row"> <div class="col-2" layout:fragment="sidebar"> <h1>Sidebar</h1> <a href="#">Login</a> </div> <div class="col" layout:fragment="content"> <h1>Welcome to the Index page</h1> <br>This content is replacing the content of the layout:fragment="content"<br> placeholder in layout.html</p> </div> </div> </div> </body> </html> 

Declaramos que index.html usa layout.html como layout com o processador layout: decorate. Feito isso, declaramos que index.html utilizará o modelo layout.html. A coisa mais importante aqui é o uso do processador de fragmentos . Indica o conteúdo que será usado em vez do conteúdo dos fragmentos do layout com o mesmo nome. Outra coisa que vale a pena mencionar é a manchete . Na página index.html resultante, que obtemos, após o processamento, o cabeçalho será uma combinação de dois cabeçalhos, um do index.html e outro do layout. Eles serão combinados.

Layout.html e index.html podem ser visualizados no navegador sem qualquer processamento. Mas após o processamento, vemos que o index.html é muito diferente. O conteúdo de index.html é usado para estilizar o layout e colocar o conteúdo dentro do layout com base no que o layout define.

Dois outros elementos estão presentes no exemplo: o cabeçalho e rodapé. No entanto, eles usam os processadores Thymeleaf Standard Layout th: replace e th: insert. Muito parecido com os dois últimos dos cinco processadores apresentados no Layout Dialect, layout: insert e layout: replace . Eles mais ou menos fazem o mesmo. Ao contrário dos processadores anteriores que discutimos, esses dois não usam uma abordagem hierárquica, mas inclusiva. Isso é mais característico da forma Thymeleaf.



A imagem mostra a visualização da página final. Ele possui cabeçalho e rodapé, embora nenhum deles seja mencionado na marcação index.html.

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


All Articles