¿Cómo hacer if-else en Thymeleaf?

132

¿Cuál es la mejor manera de hacer un simple if- elseen Thymeleaf?

Quiero lograr en Thymeleaf el mismo efecto que

<c:choose>
  <c:when test="${potentially_complex_expression}">
     <h2>Hello!</h2>
  </c:when>
  <c:otherwise>
     <span class="xxx">Something else</span>
  </c:otherwise>
</c:choose>

en JSTL

Lo que he imaginado hasta ahora:

<div th:with="condition=${potentially_complex_expression}" th:remove="tag">
    <h2 th:if="${condition}">Hello!</h2>
    <span th:unless="${condition}" class="xxx">Something else</span>
</div>

No quiero evaluar potentially_complex_expressiondos veces. Por eso introduje la variable local condition. Aún así no me gusta usar ambos th:if="${condition}y th:unless="${condition}".

Una cosa importante es que uso dos etiquetas HTML diferentes: digamos h2y span.

¿Puedes sugerir una mejor manera de lograrlo?

Maciej Ziarko
fuente

Respuestas:

208

Thymeleaf tiene un equivalente a <c:choose>y <c:when>: los atributos th:switchy th:caseintroducidos en Thymeleaf 2.0.

Funcionan como es de esperar, utilizando *para el caso predeterminado:

<div th:switch="${user.role}"> 
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
  <p th:case="*">User is some other thing</p> 
</div>

Consulte esto para obtener una explicación rápida de la sintaxis (o los tutoriales de Thymeleaf).

Descargo de responsabilidad : como lo requieren las reglas de StackOverflow, soy el autor de Thymeleaf.

Daniel Fernández
fuente
ok pero..cómo invoco un javascript basado en el tipo de cliente (es decir, anónimo o conectado) ...
Lucky
1
Vea el capítulo sobre "Texto en línea", específicamente la sección "JavaScript en línea" en el tutorial "Uso de Thymeleaf" en thymeleaf.org/documentation.html
Daniel Fernández
¿Y cómo puedo hacer esto: activar un valor iterator.index? Quiero hacer un conjunto de casos cuando el valor es <5, y cambiar al caso predeterminado si el valor es> 5
Loser Coder
@ DanielFernández: ¿puede ayudarme con stackoverflow.com/questions/48499723/… . No pude etiquetarte en la pregunta directamente. Realmente atascado.
embarcadero
98

Intenté este código para averiguar si un cliente ha iniciado sesión o es anónimo. Lo hice usando las expresiones condicionales th:ify th:unless. Una forma bastante simple de hacerlo.

<!-- IF CUSTOMER IS ANONYMOUS -->
<div th:if="${customer.anonymous}">
   <div>Welcome, Guest</div>
</div>
<!-- ELSE -->
<div th:unless="${customer.anonymous}">
   <div th:text=" 'Hi,' + ${customer.name}">Hi, User</div>
</div>
Suerte
fuente
55
Esto no responde la pregunta del OP porque se trataba de evitar la duplicación de expresiones complejas. Y al igual que otras soluciones, esto rompe la idea de "plantillas naturales", que es un importante punto de venta de Thymeleaf. No estoy seguro de qué hacer al respecto, pero solo quería señalarlo en caso de que alguien tenga una respuesta.
Stephen Harrison el
@Lucky esto me da un error EL1007E: (pos 0): No se puede encontrar la propiedad o el campo 'Estado'
Jesse
@Jackie En el ejemplo anterior, el cliente es un objeto y anónimo es un campo booleano en la clase Cliente. Asegúrese de que su objeto no sea nulo y que el nombre del campo sea correcto.
Lucky
25

Me gustaría compartir mi ejemplo relacionado con la seguridad además de Daniel Fernández.

<div th:switch="${#authentication}? ${#authorization.expression('isAuthenticated()')} : ${false}">
    <span th:case="${false}">User is not logged in</span>
    <span th:case="${true}">Logged in user</span>
    <span th:case="*">Should never happen, but who knows...</span>
</div>

Aquí hay una expresión compleja con objetos de utilidad mixtos de 'autenticación' y 'autorización' que producen un resultado 'verdadero / falso' para el código de plantilla de hoja de tomillo.

Los objetos de utilidad 'autenticación' y 'autorización' provienen de la biblioteca springsecurity3 de thymeleaf extras . Cuando el objeto 'autenticación' no está disponible O autorización.expression ('isAuthenticated ()') se evalúa como 'falso', la expresión devuelve $ {false}, de lo contrario $ {true}.

Blandger
fuente
19

Puedes usar

If-then-else:  (if) ? (then) : (else)

Ejemplo:

'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

Podría ser útil para las personas nuevas que hacen la misma pregunta.

Jad B.
fuente
11

Otra solución: puede usar la variable local:

<div th:with="expr_result = ${potentially_complex_expression}">
    <div th:if="${expr_result}">
        <h2>Hello!</h2>
    </div>
    <div th:unless="${expr_result}">
        <span class="xxx">Something else</span>
    </div>
</div>

Más sobre variables locales:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html#local-variables

jareks
fuente
Creo que ha agregado un signo "=" adicional en su código. Por favor verifíquelo nuevamente y corríjalo si tengo razón.
Lucky
En mi opinión, el código está bien. No sé a qué signo '=' adicional te refieres.
jareks
Sí, el código está bien. Lo siento, lo confundí con el lugar th:eachdonde tiene la expresión en :lugar de=
Lucky
Pero esta respuesta está muy cerca de mi solución. Mientras hago el th: con expresión me parece redundante. Básicamente, esta solución utiliza th: if y th: a menos que las declaraciones condicionales.
Lucky
Creo que no es redundante. Si usa solo th: if y th: a menos que la expresión compleja se ejecute dos veces ...
jareks
9

En un caso más simple (cuando las etiquetas html son iguales):

<h2 th:text="${potentially_complex_expression} ? 'Hello' : 'Something else'">/h2>
Grigory Kislin
fuente
¿Sabes cómo agregar traducciones para 'Hola' y 'Algo más' en esta expresión?
Laura
@Laura Puede utilizar la internacionalización y cargar diferentes traducciones de idiomas según la ubicación del archivo de propiedades. Ver looksok.wordpress.com/tag/internationalization , marcelustrojahn.com/2016/12/…
Lucky
7

Otra solución es simplemente usar notpara obtener la negación opuesta:

<h2 th:if="${potentially_complex_expression}">Hello!</h2>
<span class="xxx" th:if="${not potentially_complex_expression}">Something else</span>

Como se explica en la documentación , es lo mismo que usar th:unless. Como han explicado otras respuestas:

Además, th:iftiene un atributo inverso th:unless, que podríamos haber usado en el ejemplo anterior en lugar de usar un no dentro de la expresión OGNL

El uso nottambién funciona, pero en mi humilde opinión, es más fácil de usar en th:unlesslugar de negar la condición not.

Pau
fuente
2
<div th:switch="${user.role}"> 
<p th:case="'admin'">User is an administrator</p>
<p th:case="#{roles.manager}">User is a manager</p>
<p th:case="*">User is some other thing</p> 
</div>


<div th:with="condition=${potentially_complex_expression}" th:remove="tag">
<h2 th:if="${condition}">Hello!</h2>
<span th:unless="${condition}" class="xxx">Something else</span>
</div>
Daria Yu
fuente
1
<div style="width:100%">
<span th:each="i : ${#numbers.sequence(1, 3)}">
<span th:if="${i == curpage}">
<a href="/listEmployee/${i}" class="btn btn-success custom-width" th:text="${i}"></a
</span>
<span th:unless="${i == curpage}">
<a href="/listEmployee/${i}" class="btn btn-danger custom-width" th:text="${i}"></a> 
</span>
</span>
</div>

ingrese la descripción de la imagen aquí

Tứ Nguyễn Duy
fuente
1

Usar th:switchcomo unif-else

<span th:switch="${isThisTrue}">
  <i th:case="true" class="fas fa-check green-text"></i>
  <i th:case="false" class="fas fa-times red-text"></i>
</span>

Usar th:switchcomoswitch

<span th:switch="${fruit}">
  <i th:case="Apple" class="fas fa-check red-text"></i>
  <i th:case="Orange" class="fas fa-times orange-text"></i>
  <i th:case="*" class="fas fa-times yellow-text"></i>
</span>
Yatendra Goel
fuente