Hacia portales OpenCms en integración continua

20/07/2010

Hace ya muchísimo tiempo que no escribo nada en el blog. La verdad que no ha sido por falta de ganas, si no como suele ocurrir por falta de tiempo. En todo este tiempo he seguido trabajando en el módulo OpenCms Free Balance pero, desde que los amigos de OpenCms Hispano me invitaran como ponente a la 2ª tarde tecnológica de OpenCms, he estado trabajando en algo que por aquellos días solo conseguí esbozar y que la verdad sea dicha me ha costado mucho más de lo que en un principio pensaba, pero creo que los resultado han merecido la pena: un plugin de maven que permite a los desarrolladores, tras compilar el módulo, desplegarlo en OpenCms automáticamente

En un principio esa fue realmente la idea original, para la versión beta, ya que después, dándole una vuelta de turca más en base a mi experiencia en el desarrollo de portales haciendo uso de tecnología OpenCms, se me ocurrió que sería mucho más interesante que el plugin, además permitira el despliegue del módulo en un servidor remoto de forma que hiciera factible la integración continua.

Aunque crear un nuevo plugin en Maven es realmente fácil, los mayores problemas han sido:

  1. Gestionar todas las dependencias necesarias para la obtención de un objeto CmsObject fuera del contexto de OpenCms.
  2. Obtención del propio objeto CmsObject, en función de la versión de OpenCms que se use el modo de obtención de dicho CmsObject será distinto.
  3. Importación y publicación del módulo dentro del contexto de OpenCms.

Solucionar el problema fue fácil aunque muy tedioso ya que el proceso consistió en compilar el módulo ejecutar el plugin y cuando fallaba se busca y declara la dependencia, el resultado final ha sido:

<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>servlet-api</artifactId>
<version>6.0.26</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>oro</groupId>
<artifactId>oro</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>20040616</version>
</dependency>
<dependency>
<groupId>org.safehaus.uuid</groupId>
<artifactId>uuid</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons.digester</groupId>
<artifactId>digester</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>20030211.134440</version>
</dependency>
<dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.htmlparser</groupId>
<artifactId>htmlparser</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jsp-api</artifactId>
<version>6.0.26</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queries</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-snowball</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>commons-email</groupId>
<artifactId>commons-email</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.7</version>
</dependency>
<dependency>
<groupId>com.alkacon</groupId>
<artifactId>simapi</artifactId>
<version>0.9.8</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>

El siguiente problema a que tuve que solucionar fue, como he comentado antes, la obtención de un objeto CmsObject, para ello tuve que apoyarme en el código fuente de varios plugins de eclipse que permiten sincronizar los ficheros físicos con los ficheros de OpenCms, a continuación os dejo algunas de las referencias que me han sido de utilidad:

  1. OpenCms Mod Dev
  2. OpenCms VFS

Y el último problema que tuve que solucionar fue la importación del módulo, importación que para nada es trivial y para solucionarlo una vez más tuve que adentrarme en el código fuente de OpenCms para finalmente encontrar la solución:

String importpath = OpenCms.getSystemInfo().getPackagesRfsPath();

importpath = OpenCms.getSystemInfo().getAbsoluteRfsPathRelativeToWebInf(
importpath + “modules/” + config.getModuleName());

// Se obtiene el módulo
module = CmsModuleImportExportHandler.readModuleFromImport(importpath);

// check the module dependencies
List dependencies = OpenCms.getModuleManager().checkDependencies(module,
CmsModuleManager.DEPENDENCY_MODE_IMPORT);
if (dependencies.size() > 0) {
// some dependencies not fulfilled
StringBuffer missingModules = new StringBuffer();
Iterator it = dependencies.iterator();
while (it.hasNext()) {
CmsModuleDependency dependency = (CmsModuleDependency) it.next();
missingModules.append(”  “).append(dependency.getName()).append(“, Version “).append(
dependency.getVersion()).append(“\r\n”);
}
System.out.println(“[ERROR] ” + module.getName() + “, Version ” + module.getVersion() + missingModules);
}

// check the imported resource types for name / id conflicts
List checkedTypes = new ArrayList();
Iterator i = module.getResourceTypes().iterator();
while (i.hasNext()) {
I_CmsResourceType type = (I_CmsResourceType) i.next();
// first check against the already configured resource types
int externalConflictIndex = OpenCms.getResourceManager().getResourceTypes().indexOf(type);
if (externalConflictIndex >= 0) {
I_CmsResourceType conflictingType = (I_CmsResourceType) OpenCms.getResourceManager()
.getResourceTypes().get(externalConflictIndex);
if (!type.isIdentical(conflictingType)) {
// if name and id are identical, we assume this is a module replace operation
throw new CmsConfigurationException(org.opencms.loader.Messages.get().container(
org.opencms.loader.Messages.ERR_CONFLICTING_MODULE_RESOURCE_TYPES_5,
new Object[] {type.getTypeName(), new Integer(type.getTypeId()), module.getName(),
conflictingType.getTypeName(), new Integer(conflictingType.getTypeId())}));
}
}
// now check against the other resource types of the imported module
int internalConflictIndex = checkedTypes.indexOf(type);
if (internalConflictIndex >= 0) {
I_CmsResourceType conflictingType = (I_CmsResourceType) checkedTypes.get(internalConflictIndex);
throw new CmsConfigurationException(org.opencms.loader.Messages.get().container(
org.opencms.loader.Messages.ERR_CONFLICTING_RESTYPES_IN_MODULE_5,
new Object[] {module.getName(), type.getTypeName(), new Integer(type.getTypeId()),
conflictingType.getTypeName(), new Integer(conflictingType.getTypeId())}));
}
// add the resource type for the next check
checkedTypes.add(type);
}

// Se comprueba si el módulo esta instalado
if(!OpenCms.getModuleManager().hasModule(module.getName())){
OpenCms.getModuleManager().addModule(cmsObject, module);
} else {
OpenCms.getModuleManager().updateModule(cmsObject, module);
}

// reinitialize the resource manager with additional module resource types if necessary
if (module.getResourceTypes() != Collections.EMPTY_LIST) {
OpenCms.getResourceManager().initialize(cmsObject);
}
// reinitialize the workplace manager with additional module explorer types if necessary
if (module.getExplorerTypes() != Collections.EMPTY_LIST) {
OpenCms.getWorkplaceManager().addExplorerTypeSettings(module);
}

// import the module resources
CmsImport cmsImport = new CmsImport(cmsObject,
new CmsShellReport(cmsObject.getRequestContext().getLocale()));
CmsImportParameters parameters = new CmsImportParameters(importpath, “/”, true);
cmsImport.importData(parameters);

cmsObject.publishResource(“/”);

Para la primera versión del módulo, una vez que compruebe el correcto funcionamiento en distintas plataformas el objetivo de esta primera versión estará cumplido, el siguiente paso será que el plugin permita el despliegue remoto de módulos de forma que se permita la integración continua.


Integrando Hibernate y Maven en un módulo de OpenCms

28/04/2010

Una de las tareas que forman parte de la release-beta del módulo opencms-free-balance es llevar a cabo la integración de este módulo con Hibernate para facilitar su interacción con la base de datos, para ejecutar esta tarea he seguido con el enfoque que en GMV seguimos (y que recomiendo encarecidamente) a la hora de trabajar con este gestor de contenidos y sus módulos, utilizar Maven como herramienta de construcción de dichos módulos.

La utilización de Maven como herramienta de construcción en el proceso de desarrollo de los módulos facilita enormemente tareas habituales como: la gestión de  dependecias, generación del desplegable en OpenCms, generación de reportes, ejecución de tests, etc.

Bueno, pues manos a la obra. El primer paso para integrar Hibernate en un módulo de OpenCms es declarar las dependecias necesarias en el pom.xml del módulo, a continuación se deberán declarar en el fichero manifest.xml para que sean incluidas en el directorios WEB-INF/lib de OpenCms. También se tendrá que configurar el fichero hibernate.cfg.xml con los datos de conexión con la base de datos, anotar convenientemente las entidades que interacutarán con la base de datos y por último se tendrá que implementar la interfaz DAO que se haya definido (si es que se ha definido). Adjunto el módulo para que os sirva como ejemplo/punto de partida (es el proyecto eclipse completo, para generar el instalable, como siempre, ejecutar “mvn clean install”).

Esta posible solución es válida en aquellos módulos, como es el caso del módulo opencms-free-balance, que deben ser lo más autocontenidos, fáciles de instalar e independientes. En otros escenarios, en los que se está llevando a cabo un desarrollo a medida, con varios módulos accediendo a la base de datos, es mejor otro tipo de aproximaciones como la propuesta por Saga con su módulo de integración (de propósito general) entre OpenCms e Hibernate.

Lo maravilloso de aprender es que nadie puede arrebatárnoslo.


Sincronización de instancias de OpenCms

08/02/2010

Uno de los temas sobre los que más se habló en la tarde tecnológica de OpenCms fue sobre los problemas que existían a la hora de poner OpenCms en clúster sin contar con el módulo de pago OCEE, pues bien, desde hace algún tiempo vengo trabajando, en mis ratos libres, en un módulo para este CMS que permita disponer de varias instancias del gestor de contenidos, consumiendo los datos de una base de datos común, de forma que los cambios que realice en una instancia se propaguen a las demás. Por defecto, OpenCms dispone de una serie de funcionalidades de caché que no permiten el comportamiento anterior, dificultando de esta forma la posibilidad de disponer de un clúster de instancias de OpenCms.

Para paliar este problema he desarrollado el módulo “org.opencms.free.balance” cuya base de funcionamiento es sencilla, cada vez que se realice una modificación de los contenidos, desde cualquiera de las instancias de OpenCms, todas las demás se actualizan, a través de un servicios web, de forma que el contenido está disponible y listo para ser servido por cualquiera de los nodos.

La anatomía del módulo es la siguiente:

  1. admin: Componente encargado de llevar a cabo la administración de los nodos, en esta primera versión alpha sólo CRUD de los nodos del cluster.
  2. action: Componente encargado de interceptar las acciones que se realizan sobre OpenCms y en función de dicha acción creación, modificiación, etc le pedirá a los demás nodos del clúster que se actualicen para que puedan disponer de los cambios realizados.
  3. client: Componente que se encarga de realizar la llamada de sincronización del servicio web.
  4. webservice: Componente que se encarga de atender las peticiones de los clientes y de sincronizar, borrando la caché de OpenCms del servidor que se encuentra alojado.

Para llevar a cabo su instalación es necesario, además de desplegar el módulo, instalar un servicio web en el contexto de OpenCms.

He creado un proyecto en Google Code donde os podréis descargar el módulo, por supuesto, cualquiera que se anime a colaborar será bienvenido 😉


Tarde Tecnológica OpenCms

14/01/2010

Esta tarde he tenido la oportunidad de poder asistir a un evento organizado por OpenCms Hispano e Ingenia titulado “Tarde Tecnológica OpenCms“.

Respecto al evento y a todo lo que él se ha hablado y tratado sólo puedo tener palabras de alabanza. Ha sido una reunión en la que muchos profesionales del sector que nos dedicamos al desarrollo web basado en OpenCms hemos expuesto nuestras experiencias e impresiones y en la que se han puesto de manifiesto una serie de ideas que pueden dar como resultado, con el esfuerzo de todos, un cambio en la dirección en la que se mueve actualmente la comunidad de OpenCms.

A todos los asistentes muchas gracias y en especial a los organizadores del evento, Sergio Raposo y Alejandro Alves, sólo espero que pronto podamos volver a vernos todos y continuar tratando temas tan interesantes y útiles como los que hemos tratado hoy.

Personalmente me ha encantado la idea que Sergio a propuesto de reunirnos para hacer un sprint.

A todos muchas gracias.


Software libre, de verdad

03/08/2009

Hace algún tiempo comenzamos con el desarrollo de un proyecto utilizando tecnología OpenCms, como fruto de este trabajo hemos liberado cinco nuevos módulos que esperamos sea de utilidad para la comunidad (los módulos están modelados con maven y documentados con docbook):

RestrictedVFSWidget

Este módulo es una evolución del wdiget de exploración de OpenCms, con él se modelará el comportamiento de un árbol de exploración del directorio virtual de OpenCms en el que tan sólo se mostrarán los directorios y aquellos tipos de contenidos que se hayan configurado en la declaración del tipo de contenido que lo use.

SurveyModule

Con este módulo se amplía el funcionamiento del módulo Alkacon OAMP Survey Module, de manera que se ofrece la posibilidad de generar las gráficas de los informes en flash mediante Open Flash Chart.

Modulo Alfresco

El objetivo de este módulo es proporcionarle a los usuarios de OpenCms una herramienta con la que asignar recursos de un gestor documental Alfresco para ser utilizados en el portal. De esta forma se consigue separar la capa de gestión de contenidos de la capa de gestión documental, pudiendo aprovechar todas las funcionalidades que un gestor documental como Alfresco proporciona.

Georeference

Este módulo permite llevar a cabo la geolocalización de puntos a través de Google Maps, estableciendo las localizaciones directamente sobre un mapa que se muestra en el formulario de alta/edición de contenidos de OpenCms.

Thesaurus

El objetivo de este módulo es proporcionarle a los usuarios de OpenCms una herramienta con la que etiquetar los contenidos (noticias, eventos, etc) que se utilicen en el portal.

El software es como el sexo, es mejor cuando es libre. Linus Torvalds


Puntos de administración en OpenCms 7.0.5

25/05/2009

Hace ya algo menos de un año que comencé a trabajar con el gestor de contenidos OpenCms 7.0.5, durante este tiempo he desarrollado nuevos tipos de contenidos, widgets personalizados y puntos de administración, para el desarrollo de estas tareas me he servido de muchos recursos online pero sobre todo me ha sido de gran utilidad el foro de la comunidad de OpenCmsHispano, es por ello que he decidido realizar este tutorial cuando el otro día me encontré con este mensaje, manos a la obra.

Un punto de administración en OpenCms es una entrada en la vista de administración del gestor de contenidos con la que podremos realizar ciertas operaciones, OpenCms trae en su distribución básica una serie de entradas de administración con la que se podrán llevar a cabo tareas de administracion de usuarios, módulos, caché, etc, así como los mecanismos necesarios para extender con nuevas entradas estas funcionalidades de administración

Vista de administración del workplace

Vista de administración del workplace

Para crear un nuevo punto de administración en OpenCms deberemos crear la correspondiente estructura de directorios en /system/workplace/admin es en este directorio donde se definen los puntos de administración a través de la creación y edición de propiedades de los directorios.

Correspondencia con la zona de administración

Correspondencia con la zona de administración

En este tutorial vamos a crear un nuevo punto de administración en OpenCms denominado “Personas” que nos permitirá hacer CRUD de entidades de tipo persona, para ello he desarrollado un nuevo módulo que he denominado “PersonManagement”. Como veréis cuando instaléis el módulo (y reincieis el servidor de aplicaciones) el módulo genera un nuevo directorio /system/workplace/admin, si accedemos a las propiedades de este directorio veremos que se encuentran editadas las siguientes propiedades:

  • Description: Establece el texto que se mostrará en la caja “Ayuda” de la zona de administración.
  • NavImage: Establece la imagen que se mostrará en la zona de administración.
  • NavInfo: Establece el nombre del grupo al que pertenecerá el nuevo punto de administración.
  • NavPos: Establece con un número real (float) la posición que ocupará el icono del nuevo punto de administración.
  • NavText: Establece el texto que aparecerá bajo el icono del punto de administración.
  • Title: Establece el título del directorio aunque no es de utilidad dentro de la zona de administración.
  • admintoolhandler-class: Establece la clase que se ejecutará para hacer la gestión de los permisos de acceso al punto de administración.
  • default-file: Establece la página jsp que se ejecutará cuando accedamos a ese directorio.
Propiedades del directorio

Propiedades del directorio

Si accedemos a este directorio veremos que podemos encontrar tres páginas jsp person_list.jsp (genera el listado de los elementos), person_edit.jsp (genera el formulario de edición de los elementos de tipo persona) y person_new.jsp (genera el formulario de creación de elementos de tipo persona), si accedemos a cada una de estas páginas veremos cómo podemos encontrar un fragmento de código que sigue el siguiente patrón:

<%@page import=”paquete.de.la.clase.*”%>
<%
NmbreClase admin = new NmbreClase(pageContext, request, response);
admin.displayDialog();
%>

Como podemos observar para generar el formulario solo necesitamos una clase, que extenderá las correspondientes clase de OpenCms, y que se encargará de generar todo el código html necesario para
generar un listado o un formulario de edición o de alta.

En estas páginas jsp también es necesario editar las propiedades para que el contenido de dichas páginas se muetren correctamente.

También me gustaría haceros un par de recomendaciones para el desarrollo de funcionalidades con OpenCms:

Código del módulo

La información compartida progresa y mejora, de manera que su valor sólo puede aumentar. El conocimiento acaparado simplemente se detiene. Paul Jones, director de ibiblio.


Openfire y OpenCms se conocen

28/04/2009

En el proyecto en el que actualmente estoy trabajando tiene la necesidad de incorporar un servicio de mensajería instantánea (IM), como punto de partida mi compañero Manu me recomendó que empezara estudiando la tecnología que había desarrollada alrededor del protocolo Jabber (protocolo libre IM basado en XML).

Alrededor de este protocolo hay toda una comunidad de software libre que se dedica al desarrollo tanto de servidores como de clientes XMPP. Entre todos los servidores que estuve evaluando me decanté por uno que por su extensibilidad, tecnología y comunidad me convenció, Openfire. Se trata de un servidor de código abierto basado en Java, extensible a través de plugins y desarrollado por la comunidad bajo licencia GPL.

Como comentaba antes en el proyecto existía la necesidad de integrar un servidor de mensajería instantánea, la integración de Openfire con Opencms, el CMS que estamos utilizando, consistía en la autenticación de los usuarios. Para conseguirlo hemos tenido que hacer dos cosas, una del lado de OpenCms y otra de Openfire.

OpenCms

Hemos desarrollado un módulo de OpenCms que ofrece un servicio web con dos operaciones para realizar la autenticación de usuario, a este servicio web solo hay que pasarle el usuario y la contraseña encriptada, él se encargará de comprobar que el usuario y la contraseña son correctos así como de chequear toda la lógica de negocio, devolviendo un objeto en el que se indica si el proceso ha sido correcto.

Openfire

En este caso hemos desarrollado un plugin que cuenta con un cliente para el servicio web y que es el encargado de hacer la petición. Para que Openfire realice la autenticación utilizando la clase que hemos desarrollado, y que ha de implementar la interfaz (AuthProvider), en el método de inicialización del plugin hemos de cambiar la propiedad provider.auth.className para indicarle que utilice nuestra clase, es sumamente importante que previo a este paso hayamos registrado en el classpath del plugin dicha clase.

Una vez hecho esto, OpenCms y Openfire ya se conocen ;-p

No hay lugares remotos. En virtud de los medios de comunicación actuales, todo es ahora. Herbert Marshall Mcluhan


Web Services sobre OpenCms

18/01/2009

En este post voy a explicar un tema muy específico: cómo generar un módulo de OpenCms 7.0.5 que despliegue un web service sobre mismo contexto de OpenCms 7.0.5.

Para ello me recomendaron que me basara en la arquitectura Axis2 de Apache.

Antes de comenzar es muy importante que se haya comprendido cómo se ha de trabajar con un módulo de OpenCms 7.0.5 y Maven, para ello me gustaría recomendaros el estupendo post que en su día escribió mi compañero Antonio Manuel Muñiz respecto a este tema.

El primer paso que debemos dar para poder desplegar servicios web sobre el contexto de OpenCms, a través de un módulo, es preparar la instancia de OpenCms para tal propósito, para ello crearemos dentro del directorio “WEB-INF” un nuevo directorio “services” tal y como se muestra en la siguiente ilustración:

Estructura de directorios

Estructura de directorios

A continuación deberemos modificar el fichero web.xml de OpenCms para declarar el servlet de Axis2 que se encargará de atender las peticiones a los servicios web que declaremos.

<servlet>
—-<servlet-name>AxisServlet</servlet-name>
—-<display-name>Apache-Axis Servlet</display-name>
—- <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
—-<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
—-<servlet-name>AxisServlet</servlet-name>
—-<url-pattern>/services/*</url-pattern>
</servlet-mapping>

Una vez hecho esto, crearemos un módulo de OpenCms y modificaremos las directivas “<exportpoint />” del fichero “manifest.xml” para que OpenCms copie en el directorio “/WEB-INF/services” los servicios web desplegados como ficheros .aar

<exportpoint uri=”/system/modules/com.test.webservice.regard/services/” destination=”WEB-INF/services/”/>

Lo que tenemos que hacer a continuación es generar el fichero pom.xml necesario para que realice dos tareas fundamentales: obtener las librerías necesarias para que los servicios web puedan funcionar sobre la instancia de OpenCms y para que genere el fichero .aar a partir de los fuentes que le indiquemos.

Una vez hecho todo lo anterior tendremos listo el módulo para poder generar servicios web que corran dentro del mismo contexto que el OpenCms sobre el que se despliegan y, por tanto, puedan acceder a su información, para ello lo último que tendremos que hacer será generar un Singleton o un método dentro de la propia clase que se encargue de iniciar un objeto de la clase CmsObject que será el objeto a partir del cual podremos realizar todas las operaciones necesarias. Para llevar a cabo el desarrollo del servicio web para Axis2 os recomiendo el siguiente post.

Una vez hecho todo lo anterior ya solo nos quedará desplegar el módulo OpenCms y probar el nuevo servicio web a través de algún programa de generación de clientes.

0021

Respuesta positiva

Respuesta negativa

Respuesta negativa

Aquí dejo el módulo por si os es de utilidad.


Gestión de contenidos. OpenCms 7 y Drupal 6.

13/11/2008

Después de todo este tiempo sin escribir me gustaría hablar de dos gestores de contenidos con los que he estado trabajando durante este tiempo, OpenCms 7 y Drupal 6.

Alguien me enseñó que en los proyectos de gestión de contenidos a la hora de seleccionar el CMS con el que vamos a trabajar nos interesa tener en cuenta, entre otros, tres factores: comunidad que existe tras el producto, facilidad para modificar la funcionalidad que el CMS nos proporciona y facilidad para modificar su aspecto visual para adaptarlo a la entidad corporativa del cliente, analicemos estos factores para los dos gestores de contenido que nos ocupan.

OpenCms 7 es un gestor de contenidos open source desarrollado por la empresa Alkacon Software haciendo uso de Java y XML. Para su instalación necesita un contenedor de aplicaciones como Tomcat y un SGBD como MySQL. El proceso de instalación es fácil, ya que tras su despliegue en el contendor de aplicaciones tan solo es necesario seguir un gestor de instalación que nos irá solicitando los datos necesarios para llevar a cabo la instalación del CMS. La idea de OpenCms va un poco más allá, además de proporcionar el propio gestor de contenidos, este CMS intenta proporcionar un IDE a través del cual poder realizar nuestros desarrollos.

Drupal 6 es un gestor de contenidos open source que fue originalmente desarrollado por Dries Buytaert y es usado para impulsar los sitios web Debian Planet, Spread Firefox, Kernel Trap y más. Para su instalación necesita un servidor web como Apache y un SGBD como MySQL, al igual que ocurre con OpenCms, Drupal proporciona un gestor de instalación paso a paso.

Estos dos CMS tienen en común que proporcionan un marco de trabajo con una serie de funcionalidades básicas y la capacidad de extender dichas funcionalidades básicas a través del desarrollo de nuevos módulos, funcionales, de contenido y de visualización (skins), a partir de aquí todo es distinto, veámoslo:

Comunidad

Cuando empezamos a utilizar estos dos gestores de contenidos vemos, a la luz de las búsquedas, que existe una gran diferencia entre las comunidades de OpenCms y de Drupal, podríamos fijarnos en el número de módulos que la comunidad de Drupal a aportado y el número de módulos de la comunidad de OpenCms.

Extensión funcional

La extensión funcional de estos dos CMS´s se realiza a través de la creación de módulos, ya sean funcionales o de contenido. La creación de un tipo de contenido para OpenCms es, a priori, más ventajosa que la de Drupal, pero ahí está el matiz, a priori, si lo que queremos crear es un tipo de contenido nuevo simple, por ejemplo, una noticia, con validaciones simples, comprobar si los campos están rellenos, OpenCms nos lo pone más fácil que Drupal, pero esa facilidad es un arma de doble filo cuando queremos hacer algo más complicado, por ejemplo una validación que no se pueda realizar con expresiones regulares, por ejemplo, que la fecha de alta de la noticia no sea posterior al día actual, ahí es donde Drupal le saca ventaja a OpenCms, mientras que con OpenCms tendríamos que crear una clase que X’ que heredara de la clase X y que implementa la interfaz Y, con Drupal tan solo tendríamos que tomar el valor del campo en el correspondiente hook y realizar la validación mencionada, esto para tipos de contenidos, el caso más fácil, pero si complicamos el caso, por ejemplo con la creación de un módulo funcional de administración, empezaremos a tener problemas, incluso en el propio desarrollo. Me explico, la idea de OpenCms de proporcionar un marco desde el que poder implementar, ahora mismo la considero hilarante, teniendo en cuenta el estado actual del mercado de IDE´s, suponiendo que no vamos a usar OpenCms para desarrollar nos encontramos con el problema del versionado, ¿cómo lo hacemos?. Cuando tenemos un módulo de contenidos versionamos el módulo y listo, pero cuando desarrollamos un módulo funcional, mucho de los ficheros y estructura de directorios han de ubicarse en una carpeta específica del VFS, para solventar este problema, un posible solución pasaría por replicar en el módulo los directorios VFS y mantener el fichero manifest.xml para que al importar el módulo lo mapee correctamente. Con Drupal no nos encontramos con este problema, los módulos, ya sean de contenidos o funcionales tienen una ubicación específica y desde ahí pueden trabajar, no necesitan declarar ninguna propidad y el versionado es trivial.

Apariencia

En este apartado las cosas están más o menos igual. En OpenCms 7 tenemos el Workspace desde donde podremos crear los contenidos y administrarlos con una apariencia similar a la de un sistema operativo. Para generar la interfaz del portal, podemos, de manera opcional, instalar y usar el Template Two, configurando esta plantilla podremos generar, de forma ágil, el skin de nuestro portal. En el otro lado tenemos los themes de Drupal, con ellos podemos modificar, con unos pocos golpes de ratón, completamente la apariencia de nuestro portal, sin existir una ruptura abrupta en la interfaz como ocurre con OpenCms, además estos themes, al igual que el Template Two, son totalmente transparentes con otras características como las URL´s amigables. El problema existiria si decidiéramos hacer uso de nuestras propias templates, en ese caso tendremos que programas nosotros esas características.

Horizontalmente a estos existen otros problemas, como por ejemplo la necesidad de tener un OpenCms para poder generar los instalables de los módulos a partir de los fuentes del repositorio, por suerte, siempre hay quien se preocupa de poner remedio a este tipo de eventualidades.

Nada es verdad ni es mentira; todo es según el color del cristal con que se mira. Ramón de Campoamor.