Looking for thymeleaf Answers? Try Ask4KnowledgeBase
Looking for thymeleaf Keywords? Try Ask4Keywords

thymeleafEmpezando con thymeleaf


Observaciones

Thymeleaf es un motor de plantillas, una biblioteca escrita en Java. Permite a un desarrollador definir una plantilla de página HTML, XHTML o HTML5 y luego rellenarla con datos para generar la página final. Por lo tanto, realiza una parte de vista de modelo de un patrón de vista- modelo.

El importante principio de diseño de Thymeleaf es que la propia plantilla debe estar correctamente escrita (X) HTML.

Versiones

Versión Fecha Último lanzamiento Fecha
3.xx 2016-05-08 3.0.6 2017-05-07
2.xx 2012-02-09 2.1.5 2016-07-11

Ajax forma la sumisión con Jquery.

Para enviar el formulario a través de Ajax con Jquery:

    <div id="yourPanel" th:fragment="yourFragment">  
        <form id="yourForm" method="POST" 
              th:action="@{/actions/postForm}"
              th:object="${yourFormBean}">
        <div class="form-group">
            <label for="param1"></label>
            <input class="form-component" type="text" th:field="*{param1}" />
        </div>
        <div class="form-group">
            <label for="param2"></label>
            <input class="form-component" type="text" th:field="*{param2}" />
        </div>
        <div class="form-group">
            <label for="param3"></label>
            <input class="form-component" type="checkbox" th:field="*{param3}" />
        </div>

        <button type="submit" class="btn btn-success">Save</button>
        <a href='#' class="btn btn-default">Cancel</a>
    </form>
    </div>

<script th:inline="javascript">
    /*<![CDATA[*/
    $(document).ready(function () {
        /*[+
         var postUrl = [[@{/actions/postForm(
         additionalParam=${#httpServletRequest.getParameter('additionalParam')}
         )}]]; 
         +]*/
        $("#yourForm").submit(function (e) {
            e.preventDefault();
            $.post(postUrl,
                    $(this).serialize(),
                    function (response) {
                        var isErr = 'hasError';
                        // when there are an error then show error
                        if (response.indexOf(isErr) > -1) {
                            $("#yourPanel").html(response);
                        } else {
                            var formData = $("#yourForm").serializeArray(),
                                    len = formData.length,
                                    urlEnd = '';
                            for (i = 0; i < len; i++) {
                                urlEnd += formData[i].name + '=' + encodeURIComponent(formData[i].value) + '&';
                            }

                            /*[+
                             var urlReplacement = [[@{/another/page(
                             additionalParam=${#httpServletRequest.getParameter('additionalParam')}
                             )}]] + urlEnd;
                             +]*/

                            window.location.replace(urlReplacement);
                        }
                    }
            );
            return false;
        });
    });
    /*]]>*/
</script>
 

Clase de YourFormBean:

@lombok.Getter
@lombok.Setter
@lombok.NoArgsConstructor
public class YourFormBean {
    private String param1;
    private String param2;
    private boolean param3;
}
 

Código del controlador:

@RequestMapping(value = "/actions/postForm", method = RequestMethod.POST) 
public String saveForm(Model model, 
        @RequestParam("additionalParam") Integer additionalParam, 
        @Valid @ModelAttribute("yourFormBean") YourFormBean yourFormBean,
        BindingResult bindingResult,
        RedirectAttributes redirectAttributes) {
    if (bindingResult.hasErrors()) {
        model.addAttribute("hasError", true);
        return "your/template :: yourFragment";
    }
    redirectAttributes.addAttribute("additionalParam", additionalParam);
    
    return "redirect:/another/page";
}
 

Configuración

Para comenzar con Thymeleaf visite la página de descarga oficial .

Dependencia maven

<dependency> 
  <groupId>org.thymeleaf</groupId>
  <artifactId>thymeleaf</artifactId> 
  <version>3.0.1.RELEASE</version> 
</dependency>
 

Dependencia de Gradle

compile group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.1.RELEASE'
 

Ejemplo de configuración

A partir de la versión 3.0, Thymeleaf solo admite la configuración de Java.

public ViewResolver viewResolver() {
    ThymeleafViewResolver resolver = new ThymeleafViewResolver();
    resolver.setTemplateEngine(templateEngine());
    resolver.setCharacterEncoding("UTF-8");
    resolver.setContentType("text/html; charset=UTF-8");
    return resolver;
}
 

En el método viewResolver() puede configurar, por ejemplo, la codificación y el tipo de contenido para las vistas. más información

public TemplateEngine templateEngine() {
    SpringTemplateEngine engine = new SpringTemplateEngine();
    engine.setTemplateResolver(templateResolver());
    return engine;
}
 

En templateEngine() , puede agregar dialectos personalizados. Por ejemplo, para agregar el dialecto Spring Security, puede hacer esto como este engine.addDialect(new SpringSecurityDialect());

public ITemplateResolver templateResolver() {
    SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
    resolver.setApplicationContext(applicationContext);
    resolver.setPrefix("/views/");
    resolver.setSuffix(".html");
    resolver.setTemplateMode(TemplateMode.HTML);
    resolver.setCharacterEncoding("UTF-8");
    return resolver;
}
 

Busque en el configurador el prefijo y el sufijo en el método templateResolver() . Le dice a Thymeleaf que, cada vez que el controlador devuelva vista, Thymeleaf buscará estos nombres que html en webapp/views/ directory y .html sufijo .html .

Ejemplo

@RequestMapping(value = "/")
public String homePage() {
    return "foo/my-index";
}
 

Thymeleaf buscará html llamado my-index.html en el directorio webapp/views/foo/ . Según la configuración de ejemplo anterior.

Envío de formulario

Forma objeto

package formSubmission;

public class Person {

    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name= name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

}
 

Controlador

package formSubmission;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class FriendsController {

    @GetMapping("/friends")
    public String friendForm(Model model) {
        model.addAttribute("personForm", new Person());
        return "friendsForm";
    }

    @PostMapping("/friends")
    public String submissionResult(@ModelAttribute("personForm") Person person) {
        return "result";
    }

}
 

friendsForm.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Friend form</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>Friend Form</h1>
    <form th:action="@{/friends}" th:object="${personForm}" method="post">
        <p>Name: <input type="text" th:field="*{name}"/></p>
        <p>Age: <input type="number" th:field="*{age}"/></p>
        <p><input type="submit" value="Submit"/></p>
    </form>
</body>
</html>
 

resultado.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Submission result</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <h1>th:text="'My friend ' + ${personForm.name} + ' is ' + ${personForm.age} + ' years old'"</h1>
</body>
</html>
 

Sustitución de fragmentos por ajax.

Si desea reemplazar partes de su sitio web, ajax es una forma fácil de hacerlo.

El sitio web.html en el que desea reemplazar el contenido según el valor seleccionado:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:th="http://www.thymeleaf.org">

    <head>
        <title>Index</title>
    </head>

    <body>
        <select id="selection">
            <option>Content 1</option>
            <option>Content 2</option>
        </select>

        <div id="replace_div">
            Content goes here
        </div>

        <!-- JQury from Google CDN -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

        <script>
            $(document).ready(function () {

                //call function when page is loaded
                getContent();

                //set on change listener
                $('#selection').change(getContent);

                function getContent() {

                    //create url to request fragment
                    var url = /content/;
                    if ($('#selection').val() === "Content 1") {
                        url = url + "content1";
                    } else {
                        url = url + "content2";
                    }

                    //load fragment and replace content
                    $('#replace_div').load(url);
                }
            })
        </script>
    </body>
</html>
 

Y el content.html con los fragmentos que desea incluir en función del valor seleccionado:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
    <head>
    </head>

    <body>
        <div th:fragment="content1">
            This is Content 1
        </div>

        <div th:fragment="content2">
            This is Content 2
         </div>
    </body>
</html>
 

Por último, pero no menos importante, Spring MVC ContentController.java :

@Controller
@RequestMapping("content")
public class ContentController {

    @RequestMapping("")
    public String loadContent() {
        return "website";
    }

    @RequestMapping("content1")
    public String getContent1() {
        return "content :: content1";
    }

    @RequestMapping("content2")
    public String getContent2() {
        return "content :: content2";
    }
}
 

Usando casillas de verificación

Ejemplo de método en el controlador

@RequestMapping(value = "/test")
public String showCheckbox(Model model) {
    boolean myBooleanVariable = false;
    model.addAttribute("myBooleanVariable", myBooleanVariable);
    return "sample-checkbox";
}
 

Ver: sample-checkbox.html

<input 
      type="checkbox" 
      name="myBooleanVariable" 
      th:checked="${myBooleanVariable}"/>
 

No use th:name para checboxes, solo name