4 de diciembre de 2020

:: Liferay. Tip: Cómo saber si mi portlet es instanciable


Para saber si un portlet en una página web es o no instanciable, es decir si puede haber el mismo portlet más de una vez para la misma página, podemos averiguarlo inspeccionando el código. Sobre este buscaremos el literal: INSTANCE, que nos indicará que es instanciable.


30 de noviembre de 2020

PILAR :: Problemas con la herramienta de Análisis y Gestión de Riesgos


Tras haber instalado la aplicación hace unas semanas, a la hora de abrirla para modificar un fichero, en el menú desplegable: "modo" nos aparecen dos entradas (con el mismo texto en inglés) y al pulsar sobre el botón: "análisis cualitativo" la aplicación no parece funcionar.

En la ventana donde tenemos los logs, concretamente en la pestaña "error", podemos comprobar que hace referencia a un fichero: "commons.txt".

Para solucionar este problema, lo que debemos hacer es -en la herramienta pilar- seleccionar la primera entrada de menú, que indica el fichero .mgr cargada y en el menú desplegable, seleccionar "Configuración".

De acuerdo a la captura de pantalla, en nuestro caso será: "STIC_es" > "Configuración".

En esta ventana, debemos seleccionar el fichero ".cer" y guardar. Tras este cambio, la aplicación vuelve a funcionar como se esperaba.



29 de noviembre de 2020

:: Liferay. Portlet instanciable


En Liferay, un portlet instanciable indica que podemos tener el mismo portlet más de una vez en la misma página.

Esta propiedad se define en el fichero: "liferay-portlet.xml"

<portlet>

    <portlet-name>Nombre del porllet</portlet-name>

        ...

    <instanceable>true</instanceable>

        ...

</portlet>


Si necesitamos que un determinado portlet no sea instanciable, deberemos establece el valor:

  <instanceable>false</instanceable>



25 de noviembre de 2020

:: Liferay. Tip: Leer variable del fichero portal-ext.properties


Únicamente a modo de recordatorio, para leer el valor de una variable almacenada en el fichero: "portal-ext.properties", desde nuestra "jsp" deberemos acceder a esta mediante el código siguiente:

String valor = PropsUtil.get("nombre-de-variable")


18 de noviembre de 2020

PILAR :: Herramienta de análisis y gestión de riesgos


PILAR es una aplicación que recopila los activos del sistema, sus relaciones e interdependencias y el valor para la organización. Una vez establecido el inventario de activos, permite introducir las posibles amenazas, calculando los riesgos potenciales.

Aunque visualmente la aplicación utiliza la fuente "Comic Sans" y el aspecto y usabilidad es bastante pobre y anticuado, es la herramienta de referencia en muchos organismos.

El objetivo de la herramienta es:

  • Realizar el análisis de riesgos según la metodología Magerit e ISO/IEC 27005.
  • Diseño del plan de mejora de la seguridad.

Como ventajas del uso de la herramienta podemos señalar:

  • Conocer los riesgos a fin de poder tratarlos.
  • Conocer el grado de cumplimiento de diferentes perfiles de seguridad: 27002, protección de datos de carácter personal, esquema nacional de seguridad, etc.
  • Implementar la metodología Magerit e ISO/IEC 27005

Como desventaja es que se trata de un producto de pago mediante licencia.

Más información: https://administracionelectronica.gob.es/ctt/pilar

23 de septiembre de 2020

TLS :: Herramienta para comprobar qué versión se utiliza


Debido a que en marzo de 2020 los principales navegadores (Google Chrome, Mozilla Firefox, Microsoft Edge y Apple Safari) llegaron a un acuerdo para dejar de dar soporte a TLS 1.0 y TLS 1.1, cuando navegamos por diversos portales, nos aparece: "dominio no seguro".

Para comprobar qué versión de TLS está utilizando una web, podemos hacer uso de la siguiente herramienta:

https://globalsign.ssllabs.com/index.html

6 de agosto de 2020

Eclipse :: JSTL dependencias .jar

En eclipse, a la hora de utilizar en nuestro portlet de Liferay:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

Si no es reconocido, indica que tendremos que añadir las dependencias para los ficheros .jar oportunos. Para ello seguiremos los pasos siguientes:

- Iremos al fichero: liferay-plugin-package.properties 
- En el apartado denominado: "Portal Dependency Jars" pulsaremos el botón: "Add"
- Buscaremos: "jstl"
- Añadiremos los dos ficheros encontrados:
    + jstl-api.jar
    + jstl-impl.jar

De esta manera, el error mostrado en eclipse ya estará solucionado.

18 de junio de 2020

:: Liferay. Modificar los valores mostrados en el paginador


En los paginadores mostrados en Liferay, se muestran las siguientes opciones -en cuanto al nº de elementos por página se refiere:
5,10,20,30,50,75,100
Para este caso, lo que necesitamos es que nuestros paginadores muestren más opciones, por ejemplo hasta 200 elementos por página.
Para ello, añadiremos la siguiente línea al fichero: "portal-ext.properties"
search.container.page.delta.values=5,10,20,30,50,75,100,125,150,200

Tras reiniciar el servicio, estas opciones estarán disponibles a la hora de seleccionar los elementos por página a mostrar.


Si además queremos modificar el nº -por defecto- de elementos a mostrar por página, añadiremos la siguiente línea en el fichero: "portal-ext.properties"

search.container.page.default.delta=300

En este caso se mostrarán por defecto, 30 elementos por página.

14 de junio de 2020

:: Liferay 6.2. Uso de caracteres especiales en el nombrado de ficheros


Como prueba de concepto, el cliente nos indica que a la hora de subir un fichero o nombrar una carpeta dentro de: "Documentos y Multimedia" no quiere permitir los que contengan el caracter: "corchete".
Si creamos un fichero o carpeta nombrado con el caracteres: "[", por ejemplo: "test[1]" o "test[1].txt", tanto la carpeta como el fichero se crean correctamente.


De acuerdo a la documentación de Liferay, existen una serie de caracteres no permitidos o desaconsejados para el nombrado de carpetas y ficheros:
"\\\\""//"":""*""?""\"""<"">""|""[""]""'""..\\""../""\\..""/.."



De esta manera, si no queremos permitir el nombrado de carpetas y ficheros que contengan estos caracteres especiales, tendríamos que añadir la siguiente línea al fichero: "portal-ext.properties"
journal.char.blacklist=&,\',@,\\,],},:,=,>,/,<,[,{,%,|,+,#,`,?,\",;,*,~

Para el caso que nos ocupa, la línea a añadir en el fichero: "portal-ext.properties" , será la siguiente, indicando que no puede utilizarse el caracter: "[" y/o "]".
journal.char.blacklist=],[

Una vez iniciado el servicio, al subir el fichero: "test[1].txt" a "Documentos y multimedia" nos mostrará un error indicando que debemos utilizar un nombre válido.

10 de junio de 2020

:: Javascript. Ocultar botón de descarga en un aud

 
 En este caso lo que necesitamos es -desde una plantilla velocity- ocultar la posibilidad de descarga en un elemento: "aui-audio".

Al ubicar un audio en nuestra web, nos aparecerá la opción de descarga, para aquellos dispositivos móviles en los que no sea posible la reproducción:
 
 Para ocultar esta opción, en la plantilla velocity, incluiremos el siguiente código javascript:

var audio=document.getElementsByTagName("audio")[0];
var controles=audio.controlsList.value="nodownload";


De esta manera, el audio insertado nos aparecerá de la siguiente forma:

25 de mayo de 2020

:: Liferay. Tema del que heredamos

A la hora de crear un tema en Liferay, podemos indicarle aquel del que heredamos, mediante la propiedad siguiente, definida en el fichero: build.xml


<property name="theme.parent" value="_styled" />

20 de mayo de 2020

:: Modificar "label" de un formulario desde Javascript

Como prueba de concepto, modificaremos el literal que aparece en el login de un portal web.
En lugar de:
    Dirección de correo:
    Contraseña:

Debe aparecer:
    Email:
    Contraseña:

El código javascript necesario es el siguiente:

var labels = document.getElementsByTagName('label');
for (var i = 0; i < labels.length; i++) {
    if (labels[i].htmlFor == '_58_login') {
labels[i].innerText="Email"
}
}

15 de mayo de 2020

:: Modo oscuro en Chrome

Únicamente a modo de prueba de concepto, para habilitar el modo oscuro en nuestro navegador Chrome, escribiremos en la barra de direcciones:

chrome://flags/enable-force-dark

Una vez en esta página de configuración, habilitaremos el modo oscuro.

12 de mayo de 2020

:: Liferay. Login contra LDAP no funciona


El comportamiento en nuestro portal de Liferay era que los usuarios no podían validarse a pesar de que estos habían sido correctamente importados desde el LDAP.
A la hora de la validación, no se obtenía ningúnmensaje en el log  y unicamente el login en el portal fallaba. 
Habilitamos las trazas siguientes:com.liferay.portal.security.auth.LDAPAuth
Tras habilitar las trazas, el error obtenido en el log era este:
09:19:37,676 DEBUG [ajp-bio-8009-exec-38][LDAPAuth:176] Failed to bind to the LDAP server with 
userDN CN=xxxxxx,OU=xxxxxxx, OU=xxxxx, DC=xxxxxx, DC=LOCAL and password xxxxxxxxxx
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090442, comment: AcceptSecurityContext error, data 531, v3839_] [Sanitized]
        at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3087)
        at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3033)
        at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2835)
        at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2749)
        at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:316)


Para obtener el motivo del fallo en el proceso de login, debemos buscar:
AcceptSecurityContext error, data 531


El motivo por el que los usuarios no pueden loguearse es debido a una restricción impuesta en el propio LDAP:49 / 531 RESTRICTED_TO_SPECIFIC_MACHINES Indicates an Active Directory (AD) AcceptSecurityContext data error that is logon failure caused because the user is not permitted to log on from this computer. Returns only when presented with a valid username and valid password credential.

Más información sobre posibles errores:
https://docs.servicenow.com/bundle/helsinki-platform-administration/page/administer/reference-pages/reference/r_LDAPErrorCodes.html

8 de mayo de 2020

:: Liferay. Cómo determinar el idioma seleccionado desde un script

Como prueba de concepto utilizaremos un script para mostrar la política de cookies en un portal Liferay, en función del idioma seleccionado por el usuario o en el que figura en las preferencias de presentación.

En las páginas del sitio web > javascript insertaremos el script AUI necesario, pudiendo distinguir el idioma mediante la llamada al siguiente método:

themeDisplay.getLanguageId();

De esta manera, podríamos tener algo similar a lo siguiente:
 
var idioma=themeDisplay.getLanguageId();

var txtDescripcion="Lorem ipsum dolor sit amet.";
var txtAceptar="Aceptar";
var txtEnlace="Más información";

if("en_EN"==idioma){
	txtDescripcion="Lorem ipsum dolor sit amet.";
	txtAceptar="Ok";
	txtEnlace="More information";
}
 
 

4 de mayo de 2020

:: Unidades em

En desarrollo web es habitual utilizar unidades "em", para especificar el tamaño de las fuentes utilizadas, ¿pero de dónde viene esta unidad y cuál es su significado?

El em es una unidad que tiene su origen en el diseño tipográfico y equivale al espacio que ocupa el ancho de una letra "M" de un determinado cuerpo y alfabeto.

28 de abril de 2020

::Liferay. Ordenar usuarios desde plantilla velocity

En caso de que necesitemos mostrar la lista de usuarios ordenada desde una plantilla velocity, podemos hacer uso de la variable: $sortTool, a través de su método: sort()

$sortTool.sort($lista_a_ordenar, 'campo:ordenación')

El código sería algo similar al siguiente:
#set($userLocalServiceUtil = 
  $serviceLocator.findService("com.liferay.portal.service.UserLocalService"))
#set($usuarios = $userLocalServiceUtil.getUsers(-1,-1))

#set($usuariosOrdenados=$sortTool.sort($usuarios, 'lastName:asc'))

22 de abril de 2020

:: Recomendaciones de seguridad en situaciones de teletrabajo

El Centro Criptológico Nacional ha publicado una guía de recomendaciones sobre seguridad, en situaciones de teletrabajo.

Estas acciones o recomendaciones se podrían englobar en cuanto a:
- Usuarios
- Acceso remoto
- Correo electrónico
- Videoconferencia
- Detección y vigilancia
- Otras

Más información: https://www.ccn-cert.cni.es/informes/informes-ccn-cert-publicos/4691-ccn-cert-bp-18-recomendaciones-de-seguridad-para-situaciones-de-teletrabajo-y-refuerzo-en-vigilancia-1/file.html

21 de abril de 2020

:: Cálculo del cuadrado de un número terminado en 5

Para realizar un cálculo rápido del cuadrado de un número terminado en 5, seguiremos el siguiente procedimiento.

Por ejemplo para calcular el cuadrado de 65:

1.- Cogemos la primera cifra (6) y la multiplicamos por el siguiente número (7):

6 x 7 =42

2.- El resultado será el número anterior, seguido del cuadrado de la segunda cifra del número del que queremos calcular su cuadrado (5) y que siempre será: 25

De esta manera el resultado será: 4225

Para el cálculo del cuadrado de una cifra terminada en 5, en realidad tendremos que hacer el cálculo del resto de cifras y posteriormente añadir la cifra 25.



Otro ejemplo: calcular el cuadrado de 105:

1.- Cogemos la primera cifra (10) y la multiplicamos por el siguiente número (11):

10 x 11 = 110

2.- Al resultado anterior le añadimos la cifra 25. Es decir el resultado será: 11025

18 de abril de 2020

:: Multiplicación japonesa

Esté método de cálculo nos permitirá llevar a cabo operaciones de multiplicación contando rayas, cuyo número corresponde a cada uno de los dígitos de las cifras.

Un método, cuanto menos curioso, pero que tiene su base científica, y funciona.








En el siguiente vídeo nos muestran cómo se aplica este método:



4 de abril de 2020

:: Liferay. Error creating Liferay plugin project

Al intentar generar desde el ide Eclipse un tema para Liferay, obteniamos el siguiente error: "Error creating Liferay plugin project".

La solución que encontramos, fue la siguiente:
- Seleccionar en Eclipse: "Window" > "Preferences" > "Compiler"
- En el desplegable: "Compiler compliance level", seleccionamos 1.7 en lugar de 1.8 que es la que venía por defecto.

Probamos a generar un tema, y en esta ocasión todo funcionó correctamente.


31 de marzo de 2020

:: Liferay. Tiempo de sincronización con el LDAP

Como sabemos Liferay permite vincular con el LDAP mediante la definición de las credenciales y mapeo de campos oportuno. Por defecto, desde Liferay se comprobará periódicamente si debe importar algo desde el LDAP; este valor está establecido por defecto a 10 minutos en el fichero: "portal.properties".

En cualquier caso, si necesitásemos modificar este tiempo de comprobación, podríamos hacerlo a través del fichero: "portal-ext.properties" mediante la definición de la siguiente línea:

ldap.import.interval=15


Siendo el valor 15, el número de minutos entre cada comprobación o sincronización.

28 de marzo de 2020

:: Integración de Analytics en nuestro portal. Problema en la generación de informe

Como describimos en otro post (https://netic360.blogspot.com/2016/03/integracion-de-analytics-en-nuestro.html), es posible llevar cabo la integración de nuestra cuenta de Analytics en un portal web. Sin embargo, debido a un bug, es posible que a la hora de crear un nuevo informe con el plugin (Analytics) no se cargue el formulario para llevar a cabo la parametrización oportuna.


Para solventar este problema, lo que debemos hacer es repetir el proceso desde una ventana de incógnito; es decir, accederemos a nuestra cuenta de Google Drive desde una ventana de incógnito y seguiremos los pasos descritos en el post indicado anteriormente.

25 de marzo de 2020

:: Liferay. Error Configuración de autenticación a través del LDAP: invalid attribute description; remaining name

En Liferay es posible definir el proceso de autenticación a través de nuestro Directorio Activo Corporativo (LDAP). En este caso, u únicamente a modo de recordario sobre un problema -que al final era una tontería- pero que nos llevó un poco de tiempo localizar.

Tras llevar a cabo la definición -desde el panel de control de Liferay- del servidor LDAP y mapeo de los campos correspondientes, verificando que la prueba de conexión era correcta, a la hora de pulsar el botón: "Probar la configuración de usuarios LDAP", no devolvía ningún resultado y los logs se observaba la siguiente traza:


ERROR [ajp-bio-8009-exec-19][IncludeTag:129] Current URL /group/control_panel/manage?p_p_id=130&p_p_lifecycle=0&p_p_state=exclusive&p_p_mode=view&refererPlid=22323&_130_struts_action=%2Fportal_settings%2Ftest_ldap_users generates exception: javax.naming.directory.InvalidSearchFilterException: invalid attribute description; remaining name 'OU=Plantilla, OU=XXXXXXXX, DC=XXXXXXXX, DC=XXXXX'

javax.naming.directory.InvalidSearchFilterException: invalid attribute description; remaining name 'OU=Plantilla, OU=XXXXXXXX, DC=XXXXXXXX, DC=XXXXX'

        at com.sun.jndi.ldap.Filter.encodeSimpleFilter(Filter.java:446)

        at com.sun.jndi.ldap.Filter.encodeFilter(Filter.java:146)

        at com.sun.jndi.ldap.Filter.encodeFilterString(Filter.java:74)

        at com.sun.jndi.ldap.LdapClient.search(LdapClient.java:547)

        at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1985)

        at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1847)

        at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1772)

        at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:386)

        at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:356)

        at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:339)

        at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:267)

        at com.liferay.portal.security.ldap.PortalLDAPUtil.searchLDAP(PortalLDAPUtil.java:820)

        at com.liferay.portal.security.ldap.PortalLDAPUtil.getUsers(PortalLDAPUtil.java:617)

        at org.apache.jsp.html.portlet.portal_005fsettings.test_005fldap_005fusers_jsp._jspService(test_005fldap_005fusers_jsp.java:677)

        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)

        at com.liferay.portal.servlet.DirectRequestDispatcher.include(DirectRequestDispatcher.java:57)

        at com.liferay.portal.servlet.ClassLoaderRequestDispatcherWrapper.doDispatch(ClassLoaderRequestDispatcherWrapper.java:78)

        at com.liferay.portal.servlet.ClassLoaderRequestDispatcherWrapper.include(ClassLoaderRequestDispatcherWrapper.java:53)

        at com.liferay.taglib.util.IncludeTag.include(IncludeTag.java:295)


En nuestro caso el problema era que en el campo: "Filtro de búsqueda para la importación", habíamos puesto -debido a una modificación-: "((objectClass=Person))", cuando debería ser: "(objectClass=Person)", es decir, sobraría el "doble paréntesis".


12 de marzo de 2020

:: Coronavirus. Herramienta de seguimiento en tiempo real


En estos días, estamos preocupados por la evolución de la pandemia del coronavirus y la cantidad de información que recibidos a través de todos los medios.
Mediante una herramienta gráfica podemos seguir minuto a minuto la evolución de esta creciente infección global.

Acceso: https://www.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6

14 de febrero de 2020

:: Java. Determinar si dos fechas pertenecen al mismo día

Únicamente como recordatorio para determinar si dos fechas son del mismo día (00:01 a 23:59), podemos hacer uso de la siguiente función "isSameDay" de la clase "DateUtils":


if (DateUtils.isSameDay(date1, date2)) {
    System.out.println("Fechas en el mismo día");
} else if (date1.before(date2)) {
    System.out.println("Fecha1 es anterior a la fecha2");
} else {
    System.out.println("Fecha1 es posterior a la fecha2");
}


10 de febrero de 2020

:: Liferay. Comentarios en un workflow

En la definición de un workflow en Liferay, en el que necesitamos que al rechazar una solicitud se envíe un correo al usuario, adjuntando además los motivos, podemos hacer uso de la variable: $taskComments

Dentro del fichero .xml de definición del workflow, tendremos el código al que llamaremos, por ejemplo:


<state>
  <name>reject</name>
  <metadata> <![CDATA[{"xy":[356,225]}]]> </metadata>
  <actions>
   <action>
    <name>denied</name>
    <description/>
    <script> <![CDATA[Packages.com.liferay.portal.kernel.workflow.WorkflowStatusManagerUtil.updateStatus(Packages.com.liferay.portal.kernel.workflow.WorkflowConstants.toStatus("denied"), workflowContext);]]> </script>
    <script-language>javascript</script-language>
    <execution-type>onEntry</execution-type>
   </action>
   <!-- correo al usuario rechazado -->
   <notification>
    <name>Review Notification</name>
    <description>Denegación de solicitud</description>
    <template><![CDATA[<html>

       #set ($workflowHandlerRegistryUtil = $portal.getClass().forName("com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil"))
       #set ($locale = $localeUtil.getDefault())
       #set ($timeZone = $timeZoneUtil.getDefault())
       #set ($workflowHandler = $workflowHandlerRegistryUtil.getWorkflowHandler($entryClassName))
       #set ($classPK = $getterUtil.getInteger($entryClassPK))
       #set ($assetRenderer = $workflowHandler.getAssetRenderer($classPK))
       #set ($emailUser = $assetRenderer.getEmailNotificationDenied($locale, $timeZone, $taskComments))
              
      </html>]]> </template>
    <template-language>velocity</template-language>
    <notification-type>email</notification-type>
    <execution-type>onEntry</execution-type>
   </notification>
  </actions>
 </state>


En la función encargada de realizar el envío de correo tras ser rechazada la solicitud, 
añadiremos los comentarios al cuerpo del mensaje.

5 de febrero de 2020

:: Accesibilidad web. Enlaces adyacentes

Dentro del análisis de accesibilidad web, uno de los puntos comprobados es la existencia de enlaces adyacentes que apuntan al mismo destino.

Se consideran enlaces adyacentes aquellos que están separados por un carácter y/o conjunto de espacios en blanco, o por alguna etiqueta que no pertenezca al grupo de etiquetas en línea: a, abbr, acronym, b, big, code, cite, dfn, em, font, img, ins, label, q, s, small, span, strike, strong, sub, sup, u.


NOTA: No se tienen en cuenta los enlaces que apunten al destino: #

31 de enero de 2020

:: Accesibilidad web. Cambio de contexto

En accesibilidad se llevan a cabo una serie de validaciones, entre las que podemos señalar la existencia de: "Cambios de contexto".

¿Pero a qué hace referencia este término?.

Se entiende por cambio de contexto: una nueva página, ventana, pestaña, aplicación o un cambio de foco (window.location, window.history, window.open, window.focus).

De esta manera, a la hora de evaluar la accesibilidad en un portal web, deberemos tener en cuenta el uso de estas técnicas, para obtener la máxima puntuación posible en los informes.


  • Verificar que no se produzca ningún cambio de contexto en los eventos: onfocus y onblur
  • Verificar que no se produzca ningún cambio de contexto nada más cargarse la página: onload
  • Verficar que no se produzca ningún cambio de contexto en el evento onchange de los elementos select


27 de enero de 2020

:: Velocity. Directivas

En Apache Velocity existen una serie de directivas que podemos utilizar:

set

Utilizada para estableer el valor de una referencia. Este valor se puede asignar a una variable o a una propiedad
#set($variable="hola mundo")
#set($noticia.titulo=$variable)

if else

Utilizada para definir enunciados condicionales dentro de una plantilla velocity
#if ($valor>10)
   Valor mayor que 10
#elseif
  Valor menor o igual que 10
#end

foreach

Utilizada para definir bucles
#foreach($noticia in $noticias)
   $noticia.titulo
#end

include

Utilizada para incluir un fichero correspondiente a una plantilla, pero que no será parseado por el motor de velocity
#include("plantilla.html")

parse

Utilizada para hacer uso de una plantilla, y esta será parseada por el motor de velocity y rederizará su contenidos
#parse("cabecera.vm")

stop

Utilizada para detener la ejecución del motor de plantillas
#stop

20 de enero de 2020

:: Velocity. ¿Qué es una plantilla?

Una plantilla velocity es un fichero con extensión .vm, que contiene el código correspondiente, compuesto por: directivas, condicionales, bucles, variables,...

Por ejemplo a la hora de desarrollar un tema en Liferay 6.2 podemos tener varios ficheros .vm encargados de  mostrar la información oportuna.

Las plantillas velocity - en tiempo de ejecución- son traducidas por el motor de velocity a código html que un navegador puede entender.

<html>
<body>
#set( $foo = "Velocity" )
¡Hola Mundo $foo!
</body>
<html>
</html>

13 de enero de 2020

:: Liferay. Deshabilitar la creación de sitios personales

Liferay crea sitios personales para los usuarios definidos en el CMS, así como para aquellos usauarios que se registran.
De esta manera, a través del fichero: "portal-ext.properties" es posible llevar a cabo una configuración, de forma que no se creen los sitios personales de los usuarios.

Deshabilitar los sitios personales de los usuarios

layout.user.public.layouts.enabled=false
layout.user.private.layouts.enabled=false


Deshabilitar la creación de sitios personales

layout.user.public.layouts.auto.create=false
layout.user.private.layouts.auto.create=false


5 de enero de 2020

:: Ejemplo de notificación HTML5 en el navegador

Las notificaciones son mensajes que últimamente en muchos portales nos solicitan que habilitemos.
El código correspondiente al envío de notificaciones sería algo similar al siguiente:


<html>
<head>
<script>
//simple function to create a notification
function notificar(title, body) {
  new Notification(title, { 
    body: body,
    icon: '/img/favicon.png'
  });
};

switch(Notification.permission) {
  //El usuario no acepta las notificaciones
  case "denied":
    window.alert('Permiso denegado. Por favor cambia la configuración del navegador para permitir a esta página recibir notificaciones');
  //el usuario ha aceptado las notificaciones
  case "granted":
    notificar('Permitir notificación', 'Has dado permiso para recibir notificaciones');
    break;
  //En cualquier otro caso
  default:
    Notification.requestPermission((status) => {
      if (status === "granted") notificar('Permitir notificación', 'Gracias por permitir recibir notificaciones');
    });
}
</script>
</head>
<body>
<p>Ejemplo de notificación</p>
<script>notificar("titulo","cuerpo del mensaje");</script>
</body>
</html>

Al cargar esta página, nos aparecerá un mensaje emergente en el que deberemos permitir o denegar las notificaciones. En el caso de aceptarlas, se nos mostrarán dos ventanas en la esquina inferior derecha con la siguiente información:
- Has dado permiso para recibir notificaciones
- Cuerpo del mensaje

Este es un ejemplo sencillo de su implementación, si bien existen distintas librerías javascript.

:: Cookies de nuestra página web. ¿Para qué sirve cada una?

A menudo una pregunta que nos hacen es qué cookies se están utilizando en mi página y para qué sirven. Para ver las cookies, podemos selecci...