Interacting with a Thymeleaf template

Having put Thymeleaf on the classpath, an entire reactive view resolver has already been configured for us. The last step in putting together the web layer for our social media platform is to create the Thymeleaf template itself. We can do that by putting the following content into index.html underneath /src/main/resources/templates:

    <!DOCTYPE html> 
    <html xmlns:th="http://www.thymeleaf.org"> 
    <head> 
      <meta charset="UTF-8" /> 
      <title>Learning Spring Boot: Spring-a-Gram</title> 
      <link rel="stylesheet" href="/main.css" /> 
    </head> 
    <body> 
 
    <h1>Learning Spring Boot - 2nd Edition</h1> 
 
    <div> 
      <table> 
        <thead> 
        <tr> 
            <th>Id</th><th>Name</th><th>Image</th><th></th> 
        </tr> 
        </thead> 
        <tbody> 
        <tr th:each="image : ${images}"> 
            <td th:text="${image.id}" /> 
            <td th:text="${image.name}" /> 
            <td> 
                <a th:href="@{'/images/' + ${image.name} + '/raw'}"> 
                    <img th:src="@{'/images/'+${image.name}+'/raw'}" 
                        class="thumbnail" /> 
                </a> 
            </td> 
            <td> 
                <form th:method="delete" 
                      th:action="@{'/images/' + ${image.name}}"> 
                    <input type="submit" value="Delete" /> 
                </form> 
            </td> 
        </tr> 
        </tbody> 
      </table> 
 
      <form method="post" enctype="multipart/form-data" 
                                        action="/images"> 
        <p><input type="file" name="file" /></p> 
        <p><input type="submit" value="Upload" /></p> 
      </form> 
    </div> 
 
    </body> 
    </html> 

Key parts of the preceding template are described here:

  • All of the Thymeleaf directives are tagged with a th prefix, making the entire template HTML compliant
  • <tr th:each="image : ${images}" /> is Thymeleaf's for-each directive, where we read images from the template model and iterate over it, forming one table row element per image
  • <a th:href="@{'/images/' + ${image.name} + '/raw'}"> shows how to create a link by splicing together strings with the image.name attribute
  • The whole thing builds a table with a row for each image, showing ID, name, image, and a delete button
  • At the bottom is a single upload form for creating new images

A critical thing to remember is that the name of the template must be index.html, matching our controller's return of Mono.just("index") combined with the default configuration settings of Spring Boot for Thymeleaf.

Spring Boot autoconfigures view resolvers based on the templating solution we pick. Spring Boot supports many including Thymeleaf, Mustache, Groovy Templates, and even Apache FreeMarker. By default, they all come with a conventional location to put templates, in this case, src/main/resources/templates/<template name>.html.

Since we want a bare amount of CSS, we can drop the following into src/main/resources/static/main.css:

    table { 
      border-collapse: collapse; 
    } 
 
    td, th { 
      border: 1px solid #999; 
      padding: 0.5rem; 
      text-align: left; 
    } 
 
    .thumbnail { 
      max-width: 75px; 
      max-height: 75px; 
    } 

Let's tear the preceding small bit of CSS apart:

  • The borders of the table are collapsed
  • A little spacing is defined for the table entries
  • A special class is created to render images with a small thumbnail size

Of course, this is primitive CSS, but our focus is to learn about Spring Boot not CSS3. The important thing to observe here is that Spring Boot will automatically serve up all content underneath src/main/resources/static as web resources. We can put CSS, JavaScript, favicons, and images for our site. Anything that needs to be statically served can be put here, and will be available from the root of the web application's context path.

Throughout this book, we'll add to this web page, enhancing the user experience. But for now, we should have enough to get off the ground.

The only thing remaining is to code a public static void main(); however, we don't have to! The Spring Initializr site has already created one for us, which is as follows:

    @SpringBootApplication 
    public class LearningSpringBootApplication { 
 
      public static void main(String[] args) { 
        SpringApplication.run( 
          LearningSpringBootApplication.class, args); 
      } 
 
      @Bean 
      HiddenHttpMethodFilter hiddenHttpMethodFilter() { 
        return new HiddenHttpMethodFilter(); 
      } 
 
    } 

This last code is almost identical to the application class we created in Chapter 1, Quick Start with Java. But there is one difference--we must add a HiddenHttpMethodFilter Spring bean to make the HTTP DELETE methods work properly.

DELETE is not a valid action for an HTML5 FORM, so Thymeleaf creates a hidden input field containing our desired verb while the enclosing form uses an HTML5 POST. This gets transformed by Spring during the web call, resulting in the @DeleteMapping method being properly invoked with no effort on our end.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.168.211