30 de septiembre de 2019

:: Liferay. Servir ficheros .xml

En Liferay 6.2 podemos configurar los ficheros que nos servirá, en lugar de descargarlos. Por ejemplo, ante la necesidad de servir un fichero .xml sin que se lo descargue, podemos revisar la línea siguiente, presente en el fichero "portal-ext.properties":

mime.types.content.disposition.inline=flv,gif,jpg,pdf,png,wmv


En esta línea añadiremos el mimetype del fichero que necesitamos. De esta manera, la línea quedará como sigue:

mime.types.content.disposition.inline=flv,gif,jpg,pdf,png,wmv,xml


Será necesario reiniciar el servicio para que los cambios surtan efecto.

24 de septiembre de 2019

:: Tip CSS. Ser específico

Cuando realizamos por ejemplo un desarrollo web, necesitamos hacer uso de CSS (Cascading Style Sheets) y es posible que en muchas ocasiones hayamos utilizado reglas "abreviadas"; Si queremos cambiar el color de fondo de un elemento, podríamos utilizar el siguiente código:







background:red;

Esta versión abreviada, aunque nos ahorra tiempo, automáticamente se están definiendo estas otras propiedades:

background-color : red;
background-repeat : repeat;
background-origin : padding-box;
background-image : none;
background-position : 0% 0%;
background-size : auto auto;
background-clip : border-box;
background-attachment : scroll;

Por lo tanto, la mejor opción sería ser lo más específico posible, en este caso:

background-color:red;

18 de septiembre de 2019

:: Tip CSS. Regla para marcar lo que ocupa un elemento

Únicamente como un detalle para marcar lo que ocupa un elemento cuando estamos maquetando, podríamos aplicarle los estilos css siguientes.
De esta manera, nos ayudará a darnos cuenta de lo que realmente está sucediendo en nuestra maqueta.





outline: 2px dotted red

10 de septiembre de 2019

:: Velocity. Obtener la fecha y hora actual

Para obtener la fecha y hora actual en una plantilla Velocity, por ejemplo para mostrar el año de Copyright en un portal Liferay, el código es el mostrado a continuación:

## Obtener fecha actual
#set ($fecha = $dateUtil)
#set ($fechaActual = $fecha.getCurrentDate())
#set ($anioActual = $fecha.getCurrentDate("yyyy", $locale))

Para mostrar el año actual, el marcado sería:
<div id="pie">
Todos los derechos reservados © $anioActual
</div>

6 de septiembre de 2019

:: Tip Alfresco. Aumentar el tiempo de sesión

En el caso de que necesitemos modificar el tiempo de sesión en Alfresco, esta tarea se realiza a nivel de: Tomcat, Alfresco y Share.

La línea a añadir es la siguiente:
<session-timeout>20</session-timeout>

Los ficheros a modificar son los siguientes:
<alfresco_home>/tomcat/conf/web.xml
<alfresco_home>/tomcat/webapps/alfresco/WEB-INF/web.xml
<alfresco_home>/tomcat/webapps/share/WEB-INF/web.xml
</alfresco_home></alfresco_home></alfresco_home>

Más información: https://community.alfresco.com/thread/205313-cambiar-tiempo-sesi%C3%B3n

3 de septiembre de 2019

:: Liferay. PermissionChecker not initialized

Un error que se producía en un portlet desarrollado en Liferay 6.2, a la hora de consultar un campo personalizado, era el siguiente: "PermissionChecker not initialized"


com.liferay.portal.kernel.messaging.MessageListenerException: java.lang.RuntimeException: com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initialized
        at com.liferay.portal.kernel.scheduler.messaging.SchedulerEventMessageListenerWrapper.receive(SchedulerEventMessageListenerWrapper.java:86)
        at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72)
        at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:71)
        at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682)
        at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initialized
        at com.liferay.portlet.expando.model.impl.ExpandoBridgeImpl.getAttribute(ExpandoBridgeImpl.java:219)
        at com.liferay.portlet.expando.model.impl.ExpandoBridgeImpl.getAttribute(ExpandoBridgeImpl.java:199)
        at sun.reflect.GeneratedMethodAccessor6456.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.liferay.portal.kernel.bean.ClassLoaderBeanHandler.invoke(ClassLoaderBeanHandler.java:67)
        at com.sun.proxy.$Proxy1399.receive(Unknown Source)
        at com.liferay.portal.kernel.scheduler.messaging.SchedulerEventMessageListenerWrapper.receive(SchedulerEventMessageListenerWrapper.java:77)
        ... 5 more
Caused by: com.liferay.portal.security.auth.PrincipalException: PermissionChecker not initialized
        at com.liferay.portal.service.BaseServiceImpl.getPermissionChecker(BaseServiceImpl.java:82)
        at com.liferay.portlet.expando.service.impl.ExpandoValueServiceImpl.getData(ExpandoValueServiceImpl.java:125)
        at sun.reflect.GeneratedMethodAccessor1874.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115)
        at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
        at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51)
        at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
        at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
        at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
        at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56)
        at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111)
        at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175)
        at com.sun.proxy.$Proxy228.getData(Unknown Source)
        at com.liferay.portlet.expando.service.ExpandoValueServiceUtil.getData(ExpandoValueServiceUtil.java:107)
        at com.liferay.portlet.expando.model.impl.ExpandoBridgeImpl.getAttribute(ExpandoBridgeImpl.java:208)
        ... 14 more


Este error se lanzaba a la hora de consultar el valor del campo personalizado desde una tarea programada:

user.getExpandoBridge().getAttribute("nombre-del-campo-personalizado");


La solución a este problema, documentado en los foros de Liferay fue el siguiente:

try{
//Backup del permiso actual
PermissionChecker permissionCheckerBackup= PermissionThreadLocal.getPermissionChecker();

//Recupera el valor del del campo personalizado
PrincipalThreadLocal.setName(user.getUserId());
PermissionChecker permissionChecker;
permissionChecker = PermissionCheckerFactoryUtil.create(user);
PermissionThreadLocal.setPermissionChecker(permissionChecker);

campoPersonalizado=(boolean) user.getExpandoBridge().getAttribute("nombre-del-campo-personalizado");

//Restablece el permiso inicial
PermissionThreadLocal.setPermissionChecker(permissionCheckerBackup);
}catch(Exception ex){
ex.printStackTrace();
}


Más información: https://liferay.dev/forums/-/message_boards/message/48763277

:: 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...