Primeros pasos con la hoja de tomillo
Configuración
Para comenzar con Thymeleaf, visite [página de descarga oficial] (http://www.thymeleaf.org/download.html).
Dependencia de 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'
Configuración de ejemplo
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, p. codificación y 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 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;
}
Mire el setter para ver el prefijo y el sufijo en el método templateResolver()
. Le dice a Thymeleaf que, cada vez que el controlador devolverá la vista, Thymeleaf buscará estos nombres que html en el directorio webapp/views/
y agregará el sufijo .html
para usted.
Ejemplo
@RequestMapping(value = "/")
public String homePage() {
return "foo/my-index";
}
Thymeleaf buscará el html denominado my-index.html
en el directorio webapp/views/foo/
. De acuerdo con la configuración del ejemplo anterior.
Usar casillas de verificación
Método de ejemplo en el controlador
@RequestMapping(value = "/test")
public String showCheckbox(Model model) {
boolean myBooleanVariable = false;
model.addAttribute("myBooleanVariable", myBooleanVariable);
return "sample-checkbox";
}
Ver: muestra-checkbox.html
<input
type="checkbox"
name="myBooleanVariable"
th:checked="${myBooleanVariable}"/>
No use th:name
para casillas de verificación, solo name
Envío de formulario
Objeto de formulario
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";
}
}
Formularioamigos.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>
Envío de formulario Ajax 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 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";
}
Reemplazando fragmentos con ajax
Si desea reemplazar partes de su sitio web, ajax es una manera fácil de hacerlo.
El sitio web.html donde 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 deseas incluir según el 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";
}
}