Themewebsettings, Personalizacion Web de Temas de Apariencia en Liferay
Themewebsettings, Personalizacion Web de Temas de Apariencia en Liferay
MÁSTER OFICIAL
EN SISTEMAS TELEMÁTICOS E INFORMÁTICOS
THEMEWEBSETTINGS, PERSONALIZACIÓN
WEB DE TEMAS DE APARIENCIA EN LIFERAY
Liferay es una plataforma Web que permite la creación de portales, gestores de contenido y
entornos colaborativos de una manera rápida y sencilla. Está basada en Java, es Open Source y
en estos últimos años ha experimentado un crecimiento casi exponencial, lo que la ha llevado a
ser una alternativa muy interesante en la construcción de portales Web colaborativos.
Entre sus caracterı́sticas, podemos destacar que proporciona unos 60 portlets listos para
usar tras su instalación (incluyendo blog, foro, wiki, correo, contenido web, . . . ), páginas
personalizadas para todos los usuarios, gestión de usuarios y permisos a través de roles,
un Panel de Control (que permite una administración centralizada para todo el contenido,
usuarios, organizaciones, comunidades, roles, recursos de los servidores), drag-and-drop para
la ubicación de los portlets en las páginas, capacidad de búsqueda y etiquetado, CMS, WCM,
Software colaborativo, software social, etc.
Con este proyecto intento contribuir al crecimiento de Liferay, añadiendo una nueva
funcionalidad a la personalización de la apariencia de las páginas mediante la creación de un
nuevo concepto: los “ThemeWebSettings”.
Basándose en los “Settings”, que es una caracterı́stica de los temas de apariencia (themes)
ya implementada, esta nueva funcionalidad añade la posibilidad de controlar el valor de estos a
través del entorno Web.
Constituye, por tanto, una evolución que simplifica y aumenta la personalización de la
apariencia de los portales y páginas de Liferay a través de un nuevo apartado de configuración
en su entorno Web.
Índice general
1. Introducción 3
1.1. Liferay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1. Caracterı́sticas principales . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2. Comunidad Liferay . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.3. Evolución . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.4. Arquitectura o patrón de diseño . . . . . . . . . . . . . . . . . . . . . 7
1.1.5. Análisis mediante la herramienta SLOCCount . . . . . . . . . . . . . . 9
1.2. Experiencias con Liferay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.1. Personalización de la apariencia . . . . . . . . . . . . . . . . . . . . . 10
1.2.2. Desarrollo de temas para Liferay. El Plugin-SDK . . . . . . . . . . . . 12
1.2.3. Conclusiones y problemas detectados . . . . . . . . . . . . . . . . . . 14
1.3. Software libre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3.1. Caracterı́sticas generales . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3.2. Gestión de proyectos de software libre . . . . . . . . . . . . . . . . . . 16
2. Objetivos 18
2.1. Descripción del problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.2. Estudio de alternativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3. Metodologı́a empleada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3. Descripción Informática 23
3.1. Fase 1: Análisis del código fuente e integración en la comunidad de Liferay . . 23
3.1.1. Integración dentro de la comunidad de Liferay . . . . . . . . . . . . . 24
3.1.2. Estructuración del código y la Base de Datos . . . . . . . . . . . . . . 25
1
3.1.3. Funcionamiento de los Settings . . . . . . . . . . . . . . . . . . . . . 27
3.2. Fase 2: Implementación de una versión funcional . . . . . . . . . . . . . . . . 28
3.2.1. Iteración 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2.2. Iteración 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.3. Iteración 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.4. Iteración 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.2.5. Iteración 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.2.6. Iteración 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.3. Fase 3: Contribución al proyecto . . . . . . . . . . . . . . . . . . . . . . . . . 40
4. Conclusiones 43
4.1. Aportación de los ThemeWebSettings a Liferay . . . . . . . . . . . . . . . . . 43
4.2. Dificultades encontradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.3. Logros alcanzados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.4. Posibles trabajos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Bibliografı́a 55
2
Capı́tulo 1
Introducción
1.1. Liferay
Este apartado pretente presentar el proyecto Liferay. Para ello mostraremos sus caracterı́sti-
cas principales, los aspectos fundamentales de su comunidad, la evolución que ha tenido en
estos últimos años y la arquitectura en la que se basa. Terminaremos de presentar Liferay con
los resultados obtenidos tras la realización de un análisis inicial del código de Liferay. Para este
análisis se hizo uso de una herramienta libre [9].
3
1.1.1. Caracterı́sticas principales
Liferay es una plataforma web corporativa basada en Java y de código abierto para la
creación de portales Web, gestores CMS y entornos colaborativos.
Dentro de sus carácterı́sticas, podemos destacar las siguientes [1]:
Sicronización completa con servicios de directorios como LDAP y soporte seguro Single
Sign On.
4
Integra CMS, WCM, Software colaborativo y software social.
Intuitiva: los usuarios pueden arrastrar y pegar portlets para personalizar las preferencias
de un usuario o comunidad.
Rica: los usuarios pueden usar tanto los plugins de temas que vienen incorporados en la
instalación, como los que desarrolla la comunidad, para cambiar el aspecto del portal sin
tener que tocar el código.
Amigable: los miembros de la comunidad pueden tener sus páginas con una URL definida
por el usuario.
Como veremos un poco más adelante, dentro del apartado del Software libre, el concepto
de comunidad en un proyecto de este tipo es muy importante.
El objetivo de todo proyecto es crear una comunidad en torno él para que en algún momento
el nivel de actividad llegue a ser tal que su desarrollo sea autocatalı́tico, es decir, que la propia
comunidad resuelva las necesidades que se plantea por sı́ misma [7].
Alrededor de Liferay existe una comunidad en constante crecimiento que cuenta, en el
momento de la redacción de este proyecto, con más de 34.000 usuarios registrados.
Dentro de su Web [5] proporcionan una serie de herramientas que posibilitan la colaboración
entre sus miembros. Estas son las siguientes:
5
Wiki: con artı́culos escritos por la propia comunidad y estructurados en diferentes
bloques: para iniciarse, para la instalación, para los desarrolladores, etc. Estos permiten,
compartir el conocimiento de unos y el aprendizaje de otros.
También podemos destacar que, tal y como puede verse en la siguiente figura, ofrece una
serie de documentos (entradas de blogs, pdfs, Wikis, etc) sobre distintos temas agrupados en:
Getting started, Administration y Development.
6
Constituye un producto con una comunidad consolidada con más de 13.000 desarrolladores,
más de 2,7 millones de descargas y 250.000 instalaciones en todo el mundo [5].
1.1.3. Evolución
Curiosamente, Liferay nació en el año 2000 como un proyecto personal de Brian Chan
para hacer la web de su iglesia. Después de uno a dos años de desarrollo, Brian lo puso en
sourceforge y tuvo un gran éxito. Le empezaron a pedir servicios como si fuera una empresa,
por lo que finalmente optó por dejar su trabajo y fundó Liferay Inc. (entonces Liferay LLC).
La empresa fue fundada en Los Angeles y hoy tiene presencia también en América del Sur,
Europa y Asia.
Desde entonces su evolución hasta la nueva versión 6 que conocemos hoy en dı́a ha sido
enorme.
Podemos destacar algunos datos actuales:
Existen 34.160 usuarios registrados en liferay.com, de los cuales 13.627 han participado
alguna vez en los foros6 (en 2006 eran unos 2.500).
Todo esto nos da una idea de la magnitud que tiene el proyecto y la evolución que ha
experimentado en pocos años.
7
El patrón que sigue Liferay es el patrón Modelo Vista Controlador, conocido como patrón
MVC. Este patrón divide el proyecto en los siguientes componentes:
Esta separación implica que una petición de un usuario sea procesada como sigue:
1. El navegador, desde el lado del cliente, envı́a la petición de una página al controlador del
servidor.
2. El controlador recupera los datos necesarios del modelo para responder la petición.
8
Dividir una aplicación software en estos tres componentes implica varias ventajas:
Mejora la escalabilidad.
Promueve la reutilización
Gracias a la utilización de SLOCCount [9], una aplicación libre que permite analizar
proyectos software, podemos sacar conclusiones concretas del portal de Liferay.
El programa cuenta las lı́neas fı́sicas de código, separándolas por lenguajes, y realiza una
estimación del coste y del esfuerzo necesario para su desarrollo basándose para ello en el
modelo COCOMO (Modelo Constructivo de Costes).
El resultado podemos verlo en la siguiente tabla:
Los datos que se muestran en la tabla anterior son muy significativos. El primero nos da
una idea de la magnitud que tiene este proyecto, con más de un millón setecientas mil lı́neas de
código. También podemos constatar que está programado casi en su totalidad en java (92,85 %),
utilizando jsp para la presentación y finalmente xml para los ficheros de configuración.
Los siguientes datos también nos dan un contexto en el que ubicar el proyecto. Para realizar
un proyecto de este tipo se estima que se necesitarı́an más 5 años y más de 90 desarrolladores,
teniendo un coste final (estimado) de unos $ 70.550.688, alrededor de 55.586.887 euros.
Esta es una de las grandes ventajas del software libre. Aplicaciones de este tipo solo serı́an
accesibles a grandes empresas u organismos, pero en cambio está abierta a todo el mundo,
permitiendo su utilización, el estudio de su código e incluso la participación en el proyecto.
9
Por último, mostramos el detalle del número de lı́neas de código por directorios, obtenidos
de la herramienta anterior:
En esta tabla podemos comprobar cómo el grueso principal del código se concentra en tres
directorios:
portal-impl
portal-web
portal-service
10
En Liferay se utilizan, para tal efecto, los temas de apariencia o themes. Estos permiten, no
solo la aplicación de una serie de estilos CSS, sino además personalizar la construcción de las
páginas (templates) e incluir código javascript para que sea utilizado por las mismas.
Estos temas de apariencia pueden ser seleccionados desde la Web, a través de la barra
superior, botón Administrar - Página, dentro de una pestaña denomina Apariencia (look-and-
feel). Para poder visualizar esta barra superior es preciso haber iniciado sesión con un usuario
que tenga los permisos adecuados. Ası́ se mostrará la siguiente página de administración:
Tal y como puede verse en la imagen anterior, la apariencia se puede configurar a varios
niveles: a nivel global y/o a nivel de página.
Esta separación de configuración de la apariencia en dos niveles nos va a permitir configurar
un tema de apariencia para todo el sitio Web y dentro de éste establecer un tema de apariencia
diferente para una o varias páginas en concreto. Igual ocurre con la personalización de los CSS.
El funcionamiento podrı́a resumirse de la siguiente forma: Si existe un tema de apariencia
o un CSS definido a nivel de página: se toma ese valor. En otro caso: se aplica el establecido a
nivel de comunidad.
Desde el interfaz Web, por tanto, se podrá seleccionar el tema de apariencia deseado y
además introducir sentencias CSS que modifiquen el estilo del tema sin necesidad de volver a
general el tema.
11
Figura 1.7: Pestaña de Apariencia
También hay que comentar que existe un último nivel en la personalización de la apariencia.
Este nivel de personalización consiste en la configuración de la apariencia de cada uno de los
portlets contenidos en las páginas.
Liferay ofrece a los desarrolladores un plugin para la creación de temas, portlets, hooks y,
desde la nueva versión 6, para implementar nuevas funcionalidades del portal (ext) [4].
Mediante este plugin, podremos desarrollar nuevos temas de apariencia, desde cero o bien
12
basándonos en otro tema ya existente. Realmente nunca se desarrolla un tema desde cero, sino
que se basa sobre uno que se denomina unstyled.
Veamos cómo es la estructura del tema y qué permite personalizar.
css: en esta carpeta estarán todos los archivos necesarios para establecer los estilos del
tema de apariencia.
js: contiene el código javascript que queramos utilizar en las páginas que tengan asignado
este tema de apariencia.
templates: aquı́ se encuentran los ficheros que contruyen cada una de las páginas Web.
Para ello se hace uso de Velocity [8].
diffs: Esta carpeta es muy interesante. Si observamos, dentro de ella vuelven a aparecer
todas las carpetas anteriores. Ya hemos comentado que es posible crear un tema basado en
otro. En Liferay, el desarrollo de temas de apariencia se realiza indicando las diferencias
que queremos introducir en ese tema para crear el nuestro personalizado. Realmente
nunca se modifican los ficheros contenidos en las carpetas anteriores, sino que para
personalizar cualquiera de ellos se copia dentro de esta carpeta diff, en la subcarpeta
correspondiente, y ahı́ se realizan las modificaciones. Al compilar y generar el tema,
estas modificaciones se integran para obtener el tema personalizado.
13
WEB-INF: contiene ficheros de configuración. Entre ellos podemos destacar el liferay-
look-and-feel.xml, en el que se definen todas las propiedades del tema de apariencia.
Es evidente que todo puede ser resuelto mediante Settings. El problema reside en que para
implementar todo esto tendrı́amos que generar distintos temas de apariencias (basados en uno
solo) jugando con la asignación de valores a los distintos Settings que creemos. A esto se añade
14
que cada vez que se quiera cambiar el texto del slogan se tendrı́a que volver a modificar y
desplegar de nuevo el tema.
El resultado final es una gran cantidad de temas (uno por cada combinación de Settings) y la
dependencia hacia el desarrollador del tema de apariencia, que tendrá que ir realizando cambios
que podrı́an ser abordados, con una interfaz web adecuada, por el usuario.
Esto puede unirse a lo siguiente:
Un escenario tı́pico con Liferay es la constitución de portales Web utilizando para ello el
concepto de comunidades. De esta forma, existe un servidor que alberga más de un portal Web,
asignando para cada uno a un administrador de la comunidad.
Este tipo de rol tiene sus inconvenientes, entre ellos la imposibilidad de poder instalar
nuevos temas de apariencia, lo cual limita el margen de maniobra a la hora de desarrollar un
tema. Cada vez que se concluye la actualización del tema de apariencia hay que solicitar que el
administrador del portal lo integre en el servidor.
De esta forma, una mejora interesante serı́a aumentar el grado de personalización del tema
de apariencia a través del entorno web.
Como conclusión, Liferay necesita una nueva funcionalidad: los ThemeWebSettings, que
permitan la personalización de los temas de apariencia en tiempo real y a través de un entorno
Web.
Todo programa que sea considerado software libre debe ofrecer una serie de libertades. Se
resumen en [6]:
Libertad de usar el programa con cualquier fin, sin necesidad de comunicarlo a los
15
desarrolladores.
Libertad de distribuir copias, tanto binarios como código fuente, modificadas o no, gratis
o cobrando por su distribución.
Estas libertades conllevan una serie de factores que están cambiando el desarrollo de
software tradicional. Por ejemplo, permiten que se pueda reutilizar gran cantidad de software
que se encuentra disponible en repositorios públicos de Internet. Y no sólo eso, ya que también
pueden consultarse las listas de correo, los foros y wikis utilizados por los desarrolladores del
proyecto, donde puede encontrarse gran cantidad de información muy valiosa. De esta forma,
el desarrollo de software se acerca a los procesos que se siguen en la investigación cientı́fica en
general.
Liferay inicialmente nació como un proyecto privado, y en un momento dado, su
desarrollador decidió dar un paso que fue decisivo para el proyecto: su liberación.
Esto implica que Liferay debe cumplir las libertades anteriores, permitiendo tanto el acceso
y la modificación del código fuente como la publicación de mejoras para beneficio de la
comunidad y por tanto para la mejora del proyecto. Todo esto supuso un crecimiento importante
para Liferay.
Las libertades que ofrecen los programas libres hacen que a su alrededor se creen
comunidades de usuarios y desarrolladores que colaboran en la detección y corrección de
errores, en la solicitud y programación de nuevas funcionalidades y en otros muchos aspectos
como la traducción de la interfaz o la documentación del proyecto a nuevos idiomas [7].
El objetivo de cualquier nuevo proyecto libre es conseguir una comunidad de usuarios y
desarrolladores entorno al mismo que lo ayuden a crecer, a desarrollarse, de manera que el nivel
de actividad llegue a ser tal que el desarrollo del proyecto sea autocatalı́tico, es decir, que la
propia comunidad resuelva las necesidades que se plantean por sı́ misma.
16
Cómo conseguir esta comunidad no es un problema trivial y, aunque actualmente esta labor
se lleva a cabo sin usar procesos ingenieriles, existen algunas buenas maneras de proceder para
alcanzar este ansiado éxito.
Tal y como se ha comentado en el apartado de Comunidad Liferay, dentro de este capı́tulo
de introducción, Liferay ha conseguido aumentar considerablemente el número de miembros
de su comunidad y, aunque existe un equipo de personas trabajando en la resolución de dudas,
postear en el blog, etc., cada vez más es la propia comunidad la que se encarga de la comunidad,
es decir se está consiguiendo llegar a ser un proyecto autocatalı́tico.
Para la gestión de proyectos de software libre, también son importantes actitudes como [7]:
Mantener un sitio Web bien estructurado y actualizado. En otro caso el usuario tendrá la
sensación de que se corresponde con un proyecto muerto.
Mantener mucha documentación sobre el proyecto y con una estructuración clara. Por
ejemplo: para el usuario y para el desarrollador.
Promocionar el proyecto para conseguir el efecto en red. Para ello podrı́amos dar de alta
el proyecto en el portal Freshmeat, dedicado exclusivamente a informar de las últimas
versiones de programas libres. Asi como llegar a sitios de noticias populares, como
Barrapunto, Libertonia o Slashdot, acudir a conferencias y charlas de software libre, etc.
Con ello nuestro proyecto ganará en audiencia considerablemente.
17
Capı́tulo 2
Objetivos
Una vez presentado el marco general en el que se encuadra este proyecto y la tecnologı́a
utilizada, en este capı́tulo abordaremos los objetivos que se han perseguido durante la
elaboración del mismo. Se realizará una descripción detallada del problema, se resumirá,
posteriormente, el estudio de las distintas alternativas planteadas para su resolución y se
mostrará la metodologı́a seguida en su desarrollo.
Los objetivos principales del proyecto son:
18
Veámoslo con un ejemplo: Imaginemos que tenemos que desarrollar dos temas de apariencia
para una organización. Nos indican que ambas han de ser idénticas a excepción de la cabecera,
que será distinta en cada caso: una para la portada y otra para el resto de páginas. En este caso,
la utilización de los Settings en la construcción del tema de apariencia permitirı́a crear un único
tema que, en función de un Setting que podrı́amos denominar “cabecera”, construyera la página
utilizando una u otra cabecera, dependiendo del valor del Setting definido (que podrı́an ser:
“portada” e “interiores”).
Finalmente tendremos que declarar dos temas de apariencia. Ambos se basarán en el mismo
pero cada uno asignará un valor distinto al Setting declarado anteriormente (“cabecera“).
La sensación para el usuario es que existen dos temas de apariencia distintos, aunque
realmente tan solo exista uno.
Esta utilidad resulta interesante, dado que no es necesario crear y mantener dos temas de
apariencia casi idénticos, sino tan solo uno con los settings necesarios.
El problema que presenta el desarrollo de temas de apariencia con estos Settings radica en
que los valores de los mismos deben establecerse en el momento de generar el tema y no pueden
ser establecidos en tiempo real, a través de la web. De hecho es necesario definir un tema para
cada conjunto de asignación de settings.
Sobre este escenario, supondrı́a una mejora considerable el desarrollo de una nueva
funcionalidad que permita la declaración y asignación de valores a los settings, en tiempo real
a través de la web.
Siguiendo con el ejemplo anterior y con esta nueva funcionalidad, tan solo se tendrı́a
que desarrollar un tema donde el valor del Setting ”cabecera“ pueda seleccionarse por el
administrador a través del interfaz web.
De forma que el administrador del portal podrá, sin tener que volver a modificar y desplegar
el tema y seleccionando los valores correspondientes a través de la interfaz Web, personalizar
al máximo la apariencia de su portal.
19
similar a lo que va a realizar.
Estas nuevas funcionalidades, para que sean integradas en Liferay, deben ser supervisadas y
aprobadas por los miembros responsables del proyecto.
Por ello, Liferay cuenta con una herramienta web (Liferay Issues, basada en JIRA), que
permite tanto la notificación de bugs, como de nuevas funcionalidades que se desarrollen.
Tras comprobar que no existı́a nada, me puse en contacto con el Director General de Liferay
España y Portugal, Jorge Ferrer, quien me constató que podrı́a ser una buena contribución al
proyecto.
Por tanto, el estudio de alternativas se ha basado en la comprobación de que no existı́a nada
parecido a lo que iba desarrollar, mirando para ello en la herramienta anterior, en los foros y
finalmente poniéndome en contacto con Jorge Ferrer.
20
Figura 2.1: El modelo iterativo o espiral
1. Determinar Objetivos: se tienen que definir los objetivos que se desean cumplir en dicha
iteración. Estos, al basarse en una iteración anterior, cada vez serán mayores hasta llegar
al objetivo final.
2. Análisis de Riesgos: es necesario, una vez definidos los objetivos, analizar la mejor forma
de implementarlo en el código, minimizando el riesgo.
La ventaja principal de este modelo es que podemos dividir el objetivo final en pequeños
subobjetivos que pueden ser desarrollados en cada iteración. De esta forma, en cada una de
ellas, tan solo tendremos que preocuparnos de una parte del problema general. Y hasta que no
se verifica su correcto funcionamiento, no se pasa a la siguiente.
Por ello, tras cada iteración obtendremos un prototipo completamente funcional que sirve
de base para el siguiente.
21
Figura 2.2: Iteraciones
22
Capı́tulo 3
Descripción Informática
En este capı́tulo se pretende describir, de una forma más técnica, cuál ha sido la evolución
que ha tenido este proyecto.
Para ello, se ha realizado una división del ciclo de vida del proyecto en las siguientes etapas:
23
Aunque no se incluye en ningún subapartado, podemos ubicar dentro de esta primera fase
la preparación del entorno de trabajo, esto es, la instalación y configuración de las distintas
herramientas necesarias para el desarrollo de temas y nuevas funcionalidades de Liferay, como
Eclipse, Ant, Tomcat, Mysql, Toad, plugin-sdk, etc.
Mantener una reunión y conversaciones, vı́a correos electrónicos, con el director general
de Liferay.
De los pasos anteriores destacarı́a la reunión mantenida con Jorge Ferrer, Director General
de Liferay España y Portugal, en su sede de Madrid. Las contribuciones en este tipo de proyectos
se suelen realizar exclusivamente a través de Internet. Por ello supuso un paso importante para
mi proyecto.
En dicha reunión acordamos qué tipo de contribución podrı́a ser buena para la comunidad y
Jorge Ferrer aceptó ser co-tutor de mi proyecto.
Esto supuso un cambio importante, dado que a raı́z de dicha reunión hemos ido
intercambiando correos electrónicos con la finalidad de ir afinando el resultado hasta obtener lo
descrito en esta memoria.
Por tanto, el objetivo de integrarme dento de la comunidad de Liferay iba por buen camino.
El proyecto a desarrollar habı́a sido consensuado con una figura importante dentro de Liferay y
además iba a integrarse en las futuras versiones del proyecto. Lo cual suponı́a una motivación
importante.
1
http://www.liferay.com
24
Con respecto a la vı́as de comunicación, dada la separación geográfica y la incompatibilidad
de horarios laborales, optamos por utilizar los correos electrónicos. Además se perseguı́a el
objetivo de presentar a la comunidad una nueva funcionalidad madurada. En caso contrario, por
norma general, no solı́a tener mucho éxito.
Por último, comentar que en el transcurso del desarrollo de este proyecto, fui avisado por
Jorge Ferrer de que en foro de Liferay habı́a surgido una propuesta2 relacionada con la nueva
funcionalidad que estaba implementando. Era el momento, pues, de explicar lo que estaba
desarrollando. Hubieron algunos más interesados en ver cómo se resolvı́a este tema.
Aunque lo que se proponı́a en el foro iba relacionado con lo que estaba desarrollando,
iba más allá de los objetivos propuestos para este proyecto. Por ello lo he incluido dentro del
apartado Posibles trabajos futuros, en el capı́tulo de Conclusiones.
25
De forma muy resumida, puede verse que el acceso a los datos por parte de los portlets y
Web Services se realiza a través del Portal-Service. Este a su vez se comunica con el Portal-
Impl, que será el encargado de buscar los datos.
Tal y como se mostró en la introducción, el código de Liferay se estructura principalmente
en tres directorios:
portal-impl: Contiene todo el código fuente de las clases de objetos de Liferay y los
ficheros de configuración (a excepción de los relacionados con el apartado web).
portal-web: Contiene los JSPs, HTMLs, imágenes, y todo lo que relacionado con el
entorno Web del portal.
Con respecto a la base de datos, la última versión 6 de Liferay cuenta con un total de 183
tablas. Entre ellas se encuentran las dos que vamos a utilizar dentro del proyecto:
26
3.1.3. Funcionamiento de los Settings
En este apartado se describe, desde un punto de vista más técnico, una de las funcionalidades
existentes en la creación de temas de apariencia de Liferay, ya comentada anteriormente: los
Settings [4]. Ello consiste en la posibilidad de declarar propiedades que van a personalizar el
tema.
Estos settings se definen en un archivo de nominado liferay-look-and-feel.xml, contenido en
el directorio /docroot/WEB-INF del tema. La estructura a utilizar dentro del fichero xml es la
siguiente:
<settings>
<setting key="my-setting" value="el-valor-deseado">
...
</settings>
De esta forma, dentro de las plantillas del tema podremos acceder a las propiedades
declaradas en este fichero utilizando la siguiente instrucción:
$theme.getSetting("my-setting")
if ($theme.getSetting("tipo-de-cabecera") == "portada" ) {
#parse("$full_templates_path/cabecera_portada.vm")
27
} else {
#parse("$full_templates_path/cabecera_interior.vm")
}
Esto hace que se generen dos temas de apariencia que estarán basados en uno pero con la
cabecera distinta en cada caso.
28
interacción más frecuente con la comunidad.
A continuación se pasan a describir cada una de las iteraciones generadas y los objetivos
que se han ido cumpliendo para llegar a la última versión funcional.
Es importante destacar que en estas iteraciones tan solo mostramos el aspecto técnico
de la programación del proyecto. Evidentemente, un proyecto de este tipo tiene un esfuerzo
importante que no consiste solo en la programación.
3.2.1. Iteración 1
1. Construcción de un tema de apariencia nuevo para las pruebas que muestre el valor de
una propiedad en la cabecera.
2. Estudiar en qué campo de la base de datos se deben almacenar los valores de las
propiedades.
3. Modificación mı́nima del código de liferay para mostrar, permitir modificar y almacenar
el valor de una propiedad.
El primer objetivo fue uno de los más sencillos en conseguir. Gracias a la extensa
documentación que existe en la comunidad de Liferay, pude desarrollar un tema de apariencia
nuevo de forma rápida.
Tras estudiar detenidamente el código, comprobé que dentro del apartado Configuración
de páginas se realizaba algo similar a lo que necesitaba. Se mostraba el valor de tres
propiedades (javascript-1, javascript-2 y javascript-3) y se permitı́a su modificación, tras lo cual
se almacenaba en la base de datos, dentro de un campo denominado typesettings de la tabla
layout.
Eso era justo lo que necesitaba, ası́ que busqué el qué parte del código se implementaba
esa página (en el fichero /portal-web/docroot/html/portal/layout/edit/common.jspf ) y lo mod-
ifiqué para añadir una nueva propiedad. Con ello conseguı́ aprovechar el código existente y
gestionar, a través de la web, el valor de una nueva propiedad.
Lo habı́amos conseguido. A través de la Configuración de páginas podı́amos modificar el
valor de una nueva propiedad, quedando registrado en la base de datos.
29
Tan solo quedaba modificar el tema creado anteriormente para que mostrase el contenido
de la variable en la cabecera. Para ello habı́a que modificar, dentro de la carpeta templates, el
fichero portal normal.vm. De esta forma, para recuperar el valor de la base de datos habı́a que
utilizar la siguiente instrucción:
$layout.getTypeSettingsProperies().getProperty("propiedad")
Realmente, esta primera iteración no era capaz de tomar los settings declarados en el tema,
sino las propiedades que habı́a programado de forma estática en la página de configuración,
pero supuso un logro muy importante y una buena base para las siguientes iteraciones.
3.2.2. Iteración 2
Para el primer objetivo decidı́ definir todos los settings que quisiera mostrar en la web en
uno solo. A este setting lo denominé “custom-fields”.
De esta forma, dentro del fichero liferay-look-and-feel.xml del tema creado en la iteración
anterior, inserté la siguiente declaración del setting:
30
...
</theme>
themeModel.setSetting(key, value);
if (key.equals("custom-fields")){
StringTokenizer tokens=new StringTokenizer(value, ";");
31
while(tokens.hasMoreTokens()){
themeModel.setCustomField(tokens.nextToken(), "");
}
}
else{
themeModel.setSetting(key, value);
}
<%
for (Enumeration e = selLayout.getTheme().getCustomFields().
keys(); e.hasMoreElements();) {
key = (String)e.nextElement();
%>
<textarea class="lfr-textarea" id=’<%= portletDisplay.
getNamespace() + "CustomField_" + key %>’ name=’<%=
"TypeSettingsProperties(" + key + ")"%>’ wrap="soft"
style="display: none; width: 300px;"> <bean:write
name="SEL_LAYOUT" property=’<%= "typeSettingsProperties(" +
key + ")"%>’ /></textarea>
<%
}
%>
3.2.3. Iteración 3
32
1. Insertar editores Wysiwyg asociados a los campos de las propiedades que facilite la
introducción de código html.
33
}
%>
</select>
Con respecto al segundo objetivo, modifiqué directamente el fichero init.vm del tema
unstyled. Este tema viene por defecto en Liferay y se utiliza para crear nuevos temas desde
cero.
Más adelante descubrı́ que ese fichero se generaba automáticamente y por tanto las
modificaciones introducidas se perdı́an.
Finalmente tuve que modificar el procedimiento insertVariables del fichero /portal-impl/src/
com/liferay/portal/velocity/VelocityVariables.java para incluir el siguiente código:
De ahora en adelante, el desarrollador del tema de apariencia podrá utilizar en los templates
las propiedades definidas en el tema a través de su nombre (anteponiendo el carácter $).
El resultado de esta iteración es una gestión web de las propiedades más cómoda y simple
para el usuario, además de facilitar a los desarrolladores de temas de apariencia la utilización
de las propiedades definidas.
34
Figura 3.2: Resultado Iteración 3
Esta iteración 3 termina con la entrega de un parche que contiene el código de las diferencias
entre el ultimo existente en el repositorio y la nueva funcionalidad.
3.2.4. Iteración 4
Esta fue, sin lugar a dudas, la iteración más compleja y costosa de todo mi proyecto. En ella
se replantean los objetivos de iteraciones anteriores y, en algunos casos, se da marcha atrás.
Tras el análisis, por parte de mis tutores, del parche generado en la iteración anterior, se
tomaron algunas decisiones que modificaban sustancialmente el proyecto.
La primera decisión era la reubicación de esta funcionalidad dentro de la web de configu-
ración de páginas. No tenı́a sentido mantenerlo a nivel de página. Por ello estudié elementos
similares, como el que permite la selección de los temas de apariencia o bien la definición de
nuevos estilos CSS. Ambos elementos se encuentran dentro de una pestaña denominada Apari-
encia (look-and-feel). Dado que esta nueva funcionalidad atañe a la configuración de los temas
de apariencia, está claro que su ubicación correcta está dentro de esta pestaña. Por ello vamos a
crear una nueva pestaña al lado de la denominada CSS.
35
Como se vió en la introducción, esta pestaña Apariencia se encuentra en dos niveles, para
cada página y para el portal. En función de dónde se defina el tema y/o las sentencias CSS,
afectará a una página en concreto o bien a todo el portal.
Hasta ahora, en las iteraciones anteriores habı́amos conseguido definir settings para los
temas de apariencia modificables por la web, pero solo a nivel de página. En esta iteración
tenemos que añadir la posibilidad de que pueda ser asignado a nivel de portal.
Internamente, la diferencia entre estos dos niveles está en la tabla en la que se almacenan
las propiedades y la gestión que se realiza para asignar unas u otras: primero se miran a nivel
de página y si no hay ninguna apariencia definida para ella se toma la del portal.
En el caso del nivel de página, las propiedades se almacenan en el campo typeSettings de
la tabla layout, mientras que a nivel de portal se tendrı́an que almacenar en la tabla layoutset.
El problema estaba en que no existı́a ningún campo para almacenar los settings en esta tabla.
Esto fue solucionado por el equipo de Liferay España y Portugal, quienes incluyeron el campo
setting y los procedimientos adecuados para su manejo.
Por tanto, ya tenı́amos claro qué es lo que querı́amos conseguir, ahora nos quedaba
implementarlo.
Como ya habı́amos realizado en iteraciones anteriores, buscamos dónde se encontraba la
codificación de la Apariencia y realizamos la modificación para incluir una nueva pestaña que
contuviera la funcionalidad de los ThemeWebSettings.
En concreto la página de configuración se construye mediante el fichero /portal-
web/docroot/ html/portlet/communities/edit pages.jsp, desde el que se llama al edit pages look
and feel.jsp, ubicado junto al anterior.
En el primero es dónde se define la pestaña de Apariencia y en el segundo se desarrolla el
contenido de ésta. Es en este último dónde se codifican las pestañas Temas y Css, y por tanto
tendremos que modificarlo para ubicar la nueva pestaña.
Tras la codificacion de esta pestaña, este es el aspecto conseguido para un tema con distintos
ThemeWebSettings configurados:
36
Figura 3.3: Resultado Iteración 4
Por último hubo que configurar una nueva acción para que, al pulsar el botón salvar
desencadenara la lectura de los valores introducidos a través de la web y su almacenamiento
en la tabla correcta.
Para ello se creó un nuevo procedimiento dentro del fichero edit pages.jsp y una nueva
acción dentro de /portal-impl/src/com/liferay/portlet/communities/action/EditPagesAction.java
que lo implementara.
De igual forma hubo que modificar la declaración automática de las variables de velocity
para que al obtener los valores de los ThemeWebSettings se determinara cuando se debı́a leer
de la tabla layout (página) o bien de layoutset (portal).
Con respecto al segundo objetivo, se tomó la siguiente decisión:
La denominación “custom-fields”pasa a ser ThemeWebSettings, dado que el concepto
anterior se referı́a a otra funcionalidad dentro de liferay y por ello crearı́a confusión. Por
fin tenı́amos un nombre para esta nueva funcionalidad. A partir de ahora podemos hablar de
ThemeWebSettings, en vez de settings o propiedades.
Finalmente, dada la proximidad del lanzamiento de la nueva versión 6 de Liferay, no tenı́a
sentido sacar una funcionalidad para una versión anterior. Por ello, en esta iteración rehicimos
todas las modificaciones acumuladas hasta el momento sobre el código de esta nueva versión.
37
3.2.5. Iteración 5
1. Definir dos tipos de ThemeWebSettings: uno con valores cerrados y otro abierto a la
introducción de cualquier texto.
1. ThemeWebSettings que deben tomar valores entre algunos predefinidos. Por ejemplo:
Si/No, portada/interiores, etc.
2. ThemeWebSettings que pueden tomar cualquier valor. Estos son los que hemos tenido
hasta ahora.
De esta forma, serı́a interesante poder distinguir estos dos tipos de ThemeWebSettings. En el
primer caso, se deberá mostrar en la web una lista desplegable con los posibles valores, mientras
que en el segundo es necesario dejarlo abierto, utilizando para ello un textarea.
Por tanto, para conseguir el objetivo necesitamos poder distinguir de alguna forma la
definición de los dos tipos de ThemeWebSettings.
38
La solución adoptada es la siguiente: se modifica el significado de los valores establecidos a
los ThemeWebSettings a través del campo “value”de cada setting del fichero liferay-look-and-
feel.xml del tema de apariencia. De forma que si el valor es nulo, en la web se mostrarı́a como
un textarea, mientras que si el valor se corresponde con una lista de opciones separadas por
“;”se mostrarı́a una lista de valores con las opciones introducidas.
Esta decisión establece una diferencia entre los settings y los ThemeWebSettings, dado que
el valor establecido en el value tienen distintas funciones. En los Settings establecen el valor de
la propiedad, mientras que en los ThemeWebSettings definen el tipo (cerrado o abierto) y, en su
caso, los posibles valores de la propiedad.
Por ello se opta por separar la definición de los ThemeWebSettings a un bloque nuevo,
dentro del fichero liferay-look-and-feel.xml, denominado web-settings. La estructura quedarı́a
se la siguiente forma:
3.2.6. Iteración 6
Corrección del comportamiento al establecer la opción “Use the general look and feel
for the public (private) pages“ a ”yes“ en la configuración de la apariencia de cualquier
39
página. En este caso han de tomarse las propiedades establecidas para el portal en vez de
las de la página.
Se añade la “opción por defecto” a los WebSettings con valores cerrados. Esto es, en el
caso de que exista una ThemeWebSetting con valores cerrados, si aún no se le ha asignado
ningún valor (a nivel de portal o bien de página), es decir no existe en la base de datos
ningún valor para ella, se establece con la primera opción que se haya introducido en el
campo “value” al definirla.
40
Para ello, Liferay dentro de su Web4 establece el siguiente procedimiento:
Comentar el objetivo en los foros para que la comunidad pueda opinar acerca de ello.
Crear un parche (patch) con los cambios y adjuntarlo al ticket anterior con las siguientes
recomendaciones:
• Asegurarse que el código cumple las “Liferay’s guidelines: Liferay Core Develop-
ment Guidelines”.
Por último, hacer click en “Resolve issue”. No se debe cerrar, solo resolver.
41
En la siguiente figura puede verse el principio de la contribución, la apertura del ticket.
A partir de aquı́, queda esperar a ver la aceptación que tiene esta nueva funcionalidad de
Liferay a nivel internacional.
42
Capı́tulo 4
Conclusiones
Una vez descritos los objetivos del proyecto y analizada la solución desarrollada, esta
memoria termina resumiendo las ventajas que este proyecto aporta a Liferay, las dificultades
encontradas, los principales logros alcanzados y proponiendo posibles trabajos futuros.
1. Simplicidad.
Tan solo tendremos que definir un tema que podrá ser personalizado con los
diferentes ThemeWebSettings que contenga, a diferencia de los settings, en los que
era necesario definir distintos temas, uno por cada valor de los settings que se deseen
utilizar.
43
2. Máxima personalización. Se podrán personalizar los temas de apariencia tanto a nivel
de comunidades como de páginas. Para cada comunidad, utilizando el mismo tema, se
podrán personalizar los valores de los ThemeWebSettings.
3. Seguridad.
Es posible acotar el valor de las propiedades. De esta forma se mostrará una lista
desplegable con los posibles valores del ThemeWebsetting.
Para establecer el nombre de una clase de un elemento html, como por ejemplo
un div personalizable. En función del valor seleccionado se aplicarán unas u otras
sentencias CSS.
Para mostrar u ocultar algún portlet o bloque html (p.e. un campo de búsqueda en la
cabecera).
Para agrupar múltiples temas en uno solo. Con la selección del ThemeWebSetting
se mostrarı́a uno u otro.
Para introducir texto o bien bloques html en alguna ubicación. Por ejemplo, se puede
introducir una capa de publicidad en la cabecera cuyo contenido sea el valor de un
ThemeWebSetting.
etc.
44
4.2. Dificultades encontradas
La mayor dificultad encontrada en la realización de este proyecto estaba en mi propia
experiencia. Era la primera vez que me integraba en un proyecto tan grande y con estas
tecnologı́as. Por lo cual tuve que dedicar bastante tiempo a ponerme al dı́a. Aunque, realmente,
ya contaba con esta dificultad antes de empezar.
Quitando la anterior, podemos destacar dos dificultades:
45
4.3. Logros alcanzados
A un nivel general, con el desarrollo de este proyecto se ha puesto a disposición de la
comunidad de Liferay una nueva funcionalidad que mejora la personalización de los temas de
apariencia.
Los desarrolladores tienen una nueva funcionalidad en la construcción de los temas de
apariencia que permite aumentar la personalización de los mismos. De esta forma podrán decidir
hasta qué grado quieren que el tema sea configurable por el usuario.
Los usuarios podrán experimentar un aumento del control sobre la personalización de la
apariencia de su Web. Para ello podrán hacer uso de los ThemeWebSettings definidos por los
desarrolladores del tema, sin necesitar para ello ningún tipo de conocimiento adicional y de una
forma sencilla.
Por otro lado, a un nivel más personal, puedo destacar como logros los siguientes:
Finalmente, añadir a modo de conclusión final, que este proyecto ha constituido una
“excusa” para dar el paso de integrarme dentro de una comunidad de software libre y contribuir
a su desarrollo.
Gracias a ello, he adquirido nuevos conocimientos técnicos, nuevos métodos de progra-
mación y también conocimientos acerca de cómo se gestionan este tipo de proyectos, cómo
poder contribuirlos, etc.
Puedo concluir diciendo que, además de cumplir los objetivos descritos en esta memoria, ha
contribuido muy positivamente en mi formación como informático.
46
4.4. Posibles trabajos futuros
1. Añadir la posibilidad de definir distintos tipos de ThemeWebSettings: listas, código
HTML, etc.
4. Desarrollar un editor del aspecto general de los temas de apariencia basado en estos
ThemeWebSettings.
47
Apéndice A
key: se corresponde con el nombre. Es importante destacar que deben ser distintos de
nombres claves en Liferay, como: theme, layout, ...
48
ThemeWebSetting. En el caso de que esté vacı́o se considerará que el valor a tomar puede
ser cualquiera.
A nivel global: afectará, por tanto, a todas las páginas de esa comunidad.
49
Figura A.1: Ubicación de la Apariencia
Dentro de esta pestaña, en ambos casos, se mostrarán todos los ThemeWebSettings del tema.
Si se les establecieron posibles valores en el campo “values”, se mostrará una lista desplegable
con los mismos. En caso contrario se mostrará un textarea para introducir el texto deseado.
Finalmente existe un botón para almacenar en la base de datos los valores introducidos.
50
Apéndice B
Este email es una constestación de Jorge Ferrer a distintas cuestiones que planteo al finalizar
de la Iteración 3, por lo que las recomendaciones que se incluyen van a ser implementadas en
la iteración siguiente.
A continuación se muestra su contenido:
Jorge: Hola José Ignacio,
Yo: Buenas!
ya tengo una versión funcional con todos los bloques html que se deseen integrar. El html
es interpretado correctamente, al igual que el css. De momento, en la Web, lo he colocado en
un bloque desplegable debajo del de javascript en ”Administrar páginas - página“. Jorge, creo
que tendrı́a más sentido hacerlo directamente para el tema, en vez de para una página, ¿no?.
(Tenemos que ver la inserción del campo en la tabla layoutSet, ...)
Jorge: Totalmente de acuerdo. Puedes contar con que ese campo acabará estando. Si no
está a tiempo para que lo uses tu mismo no te preocupes porque lo haremos cuando apliquemos
tu contribución.
Yo: Ahora estoy intentando implementar un procedimiento que facilite al diseñador la
inserción de bloques html, pero no se muy bien cómo hacerlo. Os cuento:
El problema está en que el diseñador del tema tendrá que indicar para cada bloque el nombre
que tiene que aparecer en la web, ası́ como el de la variable que va a utilizar en velocity (y que
se va a almacenar en la BD). Todo ello de una forma sencilla.
Ahora estoy utilizando entradas setting en el look-and-feel.xml, una por cada bloque html
que se quiera introducir. En el ”key“ ponemos el nombre de la variable, mientras que en el value
51
ponemos el nombre para la web. Ej:
Además es necesario definir cada variable en velocity y establecer su valor (si ya está en la base
de datos) en el init custom.vm con el siguiente set:
#set ($html-footer =
$typeSettingsProperties.getProperty("html-footer"))
Con esto ya puede utilizarlo tan solo poniendo el nombre de la variable en el sitio que se desee
del diseño. Por ejemplo, en mi caso lo he colocado en el portal normal.vm, al final, dentro de
un div:
<div id="footer">$html-footer</div>
¿Véis este procedimiento demasiado complejo para un diseñador?. Lo ideal serı́a que tan
solo tuviera que definirlo en el look-and-feel.xml, ¿no?
Si es ası́, se me ocurren dos soluciones:
1. Crear una etiqueta propia para definir en el look-and-feel.xml la lista de bloques (al igual
que settings). Serı́a algo ası́ como ”htmlBlocks“. Esto implica tocar más código (replicar el
mismo comportamiento que con los settings). Con estos definidos ya se perfectamente cuántos
bloques existen.
2. Utilizar las entradas ”Settings“. En este caso tendremos que imponer la nomenclatura de
las variables para saber qué setting se refiere a un bloque html. Por ejemplo, para que sea
interpretada el nombre de la variable (el ”key“ del setting) debe comenzar por una cadena
especı́fica: ”html-“.
Jorge: Yo prefiero la opción 2. Aunque para que el portal pueda identificar cuales son los
settings que el usuario final debe poder ”personalizarçreo que es mejor usar un setting con un
nombre fijo que lista el resto de settings disponibles.
En cualquier caso yo no lo harı́a especı́fico de HTML, porque lo que estás construyendo
puede servir para que el usuario final introduzca otros tipos de personalizaciones (como un
booleano para decidir si algo se muestra o no). Teniendo esto en cuenta podrı́a quedarı́a algo
ası́:
52
Si más adelante queremos añadir información del tipo podrı́amos indicarlo después del
nombre:
<setting key="customization-fields"
value="header[html],footer[html]"/>
En cualquier caso esto lo dejarı́a para más adelante en función del feedback de los usuarios
con lo que hagamos ahora.
Tanto en un caso como en otro, estoy investigando para intentar automatizar los ”set“ de las
variables a utilizar en los velocities (vm), pero aún no tengo una solución... lo ideal es tocar el
init.vm del tema unstyled para incluir un bloque foreach que recorra los bloques establecidos y
que cree una lı́nea set por cada variable (ayuda!!).
En principio esto no deberı́a ser en el init.vm porque el tema de apariencia sobre escribe este
fichero. Deberı́a hacerse desde la clase Java que invoca el tema de apariencia. Probablemente
puedas hacerlo desde VelocityVariables.java. En cualquier caso si no consigues hacer esto
podemos dejarlo con que el usuario introduzca:
<div>$typeSettingsProperties.getProperty("html-footer"))</div>
Que no es tan bonito pero sigue siendo funcional y puede mejorarse más adelante.
Yo: Como véis esto marcha!. Está más avanzado pero estoy un poco atascado con este tema.
¿Aportaciones?
Jorge:
Vas fenomenal :)
Yo:
Espero haberme explicado bien y ...siento la parrafada de email
Por cierto Jorge, aunque pueda ceder todos los derechos de este proyecto a Liferay, ¿en
ningún lado (a excepción de en nuestras mentes) constará mi nombre como desarrollador de
dicha mejora?
Jorge: Por supuesto se mantendrá tu nombre. Lo unico que serı́a necesario ceder son los
derechos de copyright.
Yo: Gracias y un saludo.
Jorge:Gracias a ti,
Jorge
53
–
Jorge Ferrer
Director General, Liferay España y Portugal
General Manager, Liferay Spain and Portugal
Enterprise. Open Source. For Life.
54
Bibliografı́a
[1] Jonas X. Yuan. Liferay Portal 5.2 Systems Development. PACKT Publishing, 2009
[2] Jonas X. Yuan. Liferay Portal Enterprise Intranets. PACKT Publishing, 2008
[3] Richard L. Sezov, Jr. Liferay Portal Administrator’s Guide. Liferay Inc., 2009
[6] González Barahona, Jesús, Senoane Pascual, Joaquı́n y Robles Martı́nez, Gregorio.
Introducción al Software Libre. UOC, 2007.
[7] Amor, Juan José, Herraiz, Israel y Robles, Gregorio. Desarrollo de proyectos de software
libre (segunda edición). UOC, 2007.
55