Jan 26

Más de JSTL: core_rt y obtener el locale fijado con fmt:setLocale

Bueno, sigo jugando con JSTL. Un par de cosillas que he descubierto estos días.

JSTL core_rt

En el post anterior mencionaba una posible forma de acceder a las constantes de un bean desde jstl. Otra forma es, en vez de usar el JSTL core, usar el JSTL core_rt, que está pensado para no usar las expresion EL típicas de JSTL core como ${variable}, sino para usar y tener acceso a las mismas variables y expresiones de los scriptlets que van entre <% … %>

Con JSTL core haríamos algo como

<jsp:useBean id="bean" class="com.chuidiang.UnaClase"></jsp:useBean>

<c:out value="${bean.UNA_CONSTANTE}" />

y que requería del método getUNA_CONSTANTE() en el bean UnaClase

Pues bien, otra opción para esto es usar core_rt

<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c_rt"%>

y esto nos permitiría hacer directamente

<c_rt:out value="<%= UnaClase.UNA_CONSTANTE %>"/>

donde hemos podido usar un normalito <%= …. %>

Con core_rt tenemos todos los tags de core, con la diferencia de que usaremos <%= …%> en vez ${ …. }

Obtener el locale fijado con fmt:setLocale

Otro de los grupos de tags de JSTL es para la internacionalización (i18n que dicen ahora, ya que entre la i y la n de "internacionalización" hay 18 letras). Importando la taglib adecuada

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

A partir de ahí tenemos fmt:setBundle para indicar dónde están nuestros ficheros de propiedades con los textos en los distintos idiomas, fmt:message que nos permite mostrar textos al usuario según el idioma seleccionado (por defecto el del navegador) y fmt:setLocale si queremos un idioma distinto del navegador (por ejemplo, para ofrecer al usuario que lo solicita otro idioma distinto). Hay más tag para formateo de fechas y números de acuerdo al idioma elegido.

Pero echo en falta de menos un fmt:getLocale. Si cambiamos el locale con fmt:setLocale, no hay forma simple de saber más adelante cual hemos puesto. Pero sí la hay, un poco rebuscada. Si hacemos este cambio

<fmt:setLocale value="en_UK"/>

el scope por defecto es page y podemos obtener el locale con

<c:out value="${pageScope[‘javax.servlet.jsp.jstl.fmt.locale.page’]}"/>

y si lo cambiamos con scope="session" para que afecte a todas las páginas en la sesión

<fmt:setLocale value="en_UK" scope="session"/>

se puede obtener más adelante o en otra página con

c:out value="${sessionScope[‘javax.servlet.jsp.jstl.fmt.locale.session’]}"/>

¿Y para qué es útil esto?. Pues no lo tengo claro, pero comento para qué me ha hecho falta. La aplicación también tiene javascript y también tiene textos en los javascript (por ejemplo, en las ventanas confirm() o alert() antes de borrar algo). Para internacionalizar javascript suele ser necesario incluir algún fichero .js con los textos. También es habitual que haya un fichero distinto para cada lenguaje, por ejemplo es.js, en.js, etc. Y claro, no vamos a incluir todos estos ficheros en nuestra página, sólo deberíamos incluir el necesario para la visualización concreta que estemos haciendo. Pues una forma de conseguirlo es hacer la inclusión de esta manera

<script src=’path/<c:out value="es.js"/>’  …. ></script>

por supuesto, sin poner es.js a piñón fijo, sino obteniéndolo con el pequeño chorizo anterior. Quedaría tan feo como esto

<script src=’path/<c:out value="${sessionScope[‘javax.servlet.jsp.jstl.fmt.locale.session’]}.js"/>’ ….></script>

 Eso sí, tampoco es tan simple, ya que si no hemos hecho un fmt:setLocale, ese valor no existe y es null. Tenemos que recoger entonces el locale de ${pageContext.request.locale}, que es donde está el locale del navegador. Así que nos tocará hacer un if ….

Entradas relacionadas:

Leave a Reply