Skip to content

drupal

Migrando a Drupal 5.1

DrupalHe sacado tiempo para hacer una tarea que llevaba un par de meses pendiente, y es que por fin he actualizado la web a la versión 5.1 de Drupal. Le tenía un poco de miedo al ser una release con bastantes cambios en el core, estructura de directorios y demás. Afortunadamente la migración sólo me ha ocupado tiempo, no he tenido que calentarme en exceso la cabeza para que conseguir que todo lo que tenía instalado siguiera funcionando como antes.

El primer cambio importante de esta nueva versión que he visto con respecto a la 4.7 es que ahora los módulos tienen un directorio independiente para cada uno de ellos en vez de estar todos juntos en el directorio «modules». Además, cada módulo viene acompañado con un fichero de texto que indica su nombre, descripción, versión, dependencias, y otra serie de información descriptiva para facilitar la instalación y desinstalación de los mismos. Muy útil, y evita además que Drupal tenga que cargar todos los módulos para obtener información sobre ellos.

También he visto que han desaparecido algunos directorios y que la organización en general es un poco distinta. Lo más llamativo es que los nuevos módulos y temas se deben instalar en el directorio «all» que se encuentra dentro de «sites» en vez de directamente en «modules» y «themes» como se hacía antes. Para evitar problemas y no andar moviendo ficheros a mano lo que he hecho es borrar toda la web (previa realización de copia de seguridad, claro), copiar los nuevos directorios y ficheros de la nueva versión de Drupal, añadir los directorios propios (como «files») y restaurar los parámetros de los ficheros de configuración como «settings.php», «.htaccess», «robots.txt», …

Los cambios de base de datos se realizaron sin problemas durante la ejecución del proceso de update, así que no les preste mayor atención.

Durante la actualización puse el sitio offline y establecí un tema (theme) de los que trae Drupal por defecto. Una vez hecha la migración activé mi tema, aunque tuve que modificar algunos valores de la hoja de estilos porque los enlaces a «comentarios» y «leer más» se veían muy pequeños. El problema es que se han creado nuevas clases CSS para estos campos y yo no los tengo contemplados en mi tema. En realidad el problema es de mi tema, que lo hice yo mismo para aprender y luego no me he molestado en irlo actualizando. Algún día lo cambiaré y empezaré a utilizar alguno estándar para olvidarme de este tipo de cosas.

Respecto a mis módulos, actualmente tengo 3 módulos activos hechos por mí, dejaron de funcionar al hacer la migración. Menos mal que los desactive antes de ejecutar el proceso de actualización. Después de compararlos con los nuevos módulos del core ví que la mayoría de los problemas eran debidos a la nueva disposición de los menús de administración, a que ha cambiado un poco la forma de gestionar los formularios, y a que el hook «nodeapi» admite algunos valores que no estaba teniendo en cuenta. Una vez cambiada esa parte, apenas un par de líneas realmente, empezaron a funcionar otra vez.

Lo único que me ha faltado por hacer es poner los «feeds» a mi gusto. Había hecho unas modificaciones en el core de Drupal que voy a tener que rehacer. No obstante, antes de volver a hacerlas, quiero investigar un poco a ver si puedo conseguir el mismo resultado con algún tipo de módulo.

Problemas de login con Drupal y PHP 5.2

Me he pasado un buen rato intentando hacer login en mi web sin poder conseguirlo. No lo conseguía ni después de aplicar los siempre socorridos trucos de borrar las tablas SESSIONS y CACHE de la base de datos, ni siquiera eliminando las cookies del navegador me dejaba entrar (que por cierto, se me ha ido la mano y las he borrado todas). Ocurría que me aparecía la ventana de login, introducía usuario y password, entraba en el sistema, y cualquier página a la que intentaba acceder a partir de ahí me echaba con el mensaje de permiso denegado.

Al rato de estar probando cosas, y de empezar a volverme un poco loco, he recordado que hace poco mi servicio de hosting (DreamHost) ha actualizado a la versión 5.2.1 de PHP. Entonces he pensado que podía haber alguna incompatibilidad de Drupal con esta versión de PHP y he hecho una búsqueda a ver que encontraba. Y efectivamente, hay problemas. He encontrado una solución rápida en esta página: http://drupal.org/node/102114.

He aplicado la solución más sencilla de todas las que he visto, que es la que figura en el primer comentario de la página que he puesto. Basta con añadir al fichero settings.php la siguiente línea (antes del último «?>»):

register_shutdown_function('session_write_close');

Una vez puesta esa línea he podido entrar otra vez a mi web de la forma normal a la primera. Y por cierto, mi idea era escribir hoy sobre otra cosa, que para eso estaba haciendo el login, pero al final se me ha ido el tiempo localizando el error. Pongo la solución por aquí, porque me consta que hay mucho usuario de Drupal que tiene problemas con el inglés.

Hacking Drupal

Una de las cosas que nunca me ha acabado de convencer de Drupal es la forma en que compone los feeds. Creo que debería invertirse un poco más de tiempo en mejorar una característica que hoy en día resulta básica. El programa debería hacer un mejor trabajo por sí solo como hacen otros CMS. Ya se mejoró algo en la versión 4.7 y espero que siga haciéndose en la 5 que se publicará a lo largo de este año.

El principal inconveniente que le veo es que basa la composición de los feeds en el ‘teaser’, esa parte del contenido de los nodos (posts, artículos, …) que se marca con una etiqueta <!–break–> para que se corte justo en ese punto, a modo de resumen, y se muestre junto el típico enlace de «leer más» o «leer el artículo completo». Si bien me parece una forma rápida y adecuada de afrontar el tema para la mayoría de las situaciones, hay veces en que esa solución no resulta la más conveniente, como por ejemplo cuando los nodos son pequeños y carece de sentido cortarlos. Pero sobre todo no me convence porque para mí son cosas distintas. Una cosa es el aspecto que quiero que tengan los posts en mi web y otra muy distinta es como deberían aparecer en los feeds.

La ventaja de utilizar programas de código abierto es que uno puede modificarlos si tiene el conocimiento y paciencia necesarios. En el caso de Drupal además resulta fácil, está escrito en PHP y su código fuente es muy claro, de lo mejor que hay por ahí. Aunque no conviene modificar el núcleo y es mejor hacer un módulo independiente esta vez he optado por la solución más rápida. Cosas de la vida moderna. Mi idea ha sido la de crear una etiqueta <!–feed–> realizando el corte para los feeds de igual forma que se hace para el teaser. En un post como este: «<!–feed–>En un lugar de la Mancha<!–feed–> de cuyo nombre no quiero acordarme<!–break–> hacía tiempo que …» sólo se incluiría la primera parte (En un lugar de la Mancha) en los feeds, y el teaser seguiría funcionando como hasta ahora (En un lugar de la Mancha de cuyo nombre no quiero acordarme). He utilizado dos etiquetas para los feed para tener una mayor control.

El código fuente que he tenido que modificar es el que se encuentra en el fichero node.module, en la función node_feed, concretamente en el switch sobre $item_length (es fácil de localizar), y lo que he hecho ha sido poner las siguientes líneas en el case para ‘teaser’:

$item_text = $item->teaser;
$parts = explode('', $item_text);
if (count($parts) == 3){
  $item_text = $parts[1] . "[...]";
}

Este código lo que hace es dividir el contenido de los nodos utilizando la etiqueta <!–feed–> como punto de corte y se queda con la parte central. Sencillo, ¿no?.

Prefijado de nombres y referencias externas

Una de las cosas más importantes que tiene que hacerse para garantizar que los programas resulten fáciles de desarrollar y posteriormente darles mantenimiento es utilizar estándares de nomenclatura. El problema es que esta práctica sólo se suele asociar al nombre de los ficheros y al estilo del código fuente, pero hay otras áreas en las que también resultan de crucial importancia. Hoy me estaba fijando en los nombres de los objetos en Base de Datos, como las tablas por ejemplo.

Es bastante frecuente, sobre todo en aplicaciones web sencillas, tener tablas con nombres comunes como CLIENTES o FACTURAS. Esto resulta claro y conciso durante el diseño y desarrollo, pero a la larga puede traer problemas. Por ejemplo, no se pueden instalar dos aplicaciones distintas en una misma instancia de Base de Datos para un mismo usuario si los nombres de las tablas que utilizan son iguales, y usando nombres tan comunes es bastante normal que antes o después se den conflictos. Pero sobre todo resulta problemático cuando se tiene que dar mantenimiento a la aplicación y se tiene que medir de forma rápida el impacto de una modificación importante sobre una tabla bastante utilizada como puede ser CLIENTES. En la mayoría de los casos lo que se hace es buscar la palabra «CLIENTES» en todos los fuentes, y ocurre que aparece en comentarios, nombres de variables, nombres de funciones, cadenas de texto, sentencias SQL, etc. siendo difícil discriminar de forma rápida las modificaciones concretas que habrá que realizar.

Una mejor estrategia de nomenclatura es prefijar los nombres de los objetos con unas siglas identificativas del proyecto. Por ejemplo, si se está elaborando el sistema SuperGes 1.0, basta con anteponer al nombre de las tablas un prefijo tal como «SGE_», pasando entonces las tablas a llamarse «SGE_CLIENTES» o «SGE_FACTURAS».

Este simple método anula completamente la probabilidad de conflicto de nombres con los distintos proyectos que desarrollemos dentro de nuestra empresa, pero no anula la probabilidad de conflicto con aplicaciones de otras empresas que pueden estar siguiendo nuestro mismo método de nomenclatura. Una solución más completa, utilizada en algunos paquetes de software libre, es decidir el prefijo de las tablas en el momento que se realiza la instalación de la aplicación.

Drupal por ejemplo permite que los nombres de las tablas se prefijen como se quiera al crear la Base de Datos durante el proceso de instalación, y que se ponga en un fichero de configuración el prefijo escogido. Esto resulta especialmente útil cuando se tienen varias versiones instaladas a un mismo tiempo, ya que nos permite tener varios conjuntos de unas mismas tablas pero prefijadas de forma distinta para evitar conflictos, como «drp468_» y «drp472_» por ejemplo.

La magia del asunto consiste en que dentro del código fuente de Drupal los nombres de las tablas en las sentencias SQL se escriben encerradas por llaves, como en «SELECT nid FROM {node}». De esta forma la capa de acceso a Base de Datos puede detectar la referencia a cada tabla y anteponerle el prefijo escogido. Si el sobrecoste que implica sustituir en tiempo de ejecución una cadena de texto por otra resulta prohibitiva, cosa que dudo ya que en comparación el tiempo de acceso a Base de Datos será siempre de varios órdenes de magnitud mayor, se puede optar por sustituir los nombres de las tablas dentro de los propios ficheros fuentes durante el proceso de instalación del software, algo plausible si se utiliza algún lenguaje como PHP por ejemplo, que normalmente es interpretado.

Hablando de Base de datos, otra práctica bastante común en algunos desarrollos web sencillos es el obviar el uso de foreign keys. A veces simplemente porque no hay más remedio, por ejemplo porque el gestor de Base de Datos que se está utilizando no lo permite, pero la mayoría de las veces es por pura dejadez y una cierta aversión al uso de las mismas. No sé, es como si tuvieran mala fama o se pensase que resultan totalmente inútiles. Las excusas hablan de que ralentizan el funcionamiento, que dificultan los imports parciales, y que en general no sirven para nada cuando las relaciones son evidentes. Todas excusas vanas. Lo único cierto y verdad es que sólo implican una carga extra para el servidor cuando se insertan o borran registros, no cuando se hacen consultas, que es lo que hace el 99% del tiempo una aplicación web típica. Tampoco dificultan los imports, todo lo contrario, ayudan a que no quede información incoherente en Base de Datos que de otra forma podría ser difícil de depurar. Y por supuesto sí sirven para algo, sobre todo cuando tenemos que enfrentarnos a modelos que constan de 300 o 400 tablas, y no las 6 ó 7 de una aplicación pequeña y que hemos desarrollado completamente nosotros. Obtener la estructura puede ser sencillo, pero averiguar el uso y la intención es normalmente una labor más compleja, por lo que toda ayuda resulta poca.

Artículos de IBM sobre Drupal

Leo como noticia en la página principal de Drupal una nota acerca de la lista de artículos que está elaborando IBM sobre Drupal, el CMS que utilizo para mi web.

La serie que están elaborando desde IBM lleva ya un tiempo en construcción y recordaba haber leído una de las primeras entradas de la misma, concretamente la que exponía las razones por las que se decidían finalmente a utilizar Drupal después de haber estudiado un conjunto de software de similares características. Recordad que Drupal es software libre, de código abierto, y no un producto propio de IBM.

Los artículos, en inglés, son bastantes completos y francamente buenos. Entre ellos me gustaría destacar el que es sin duda el mejor artículo que he leído acerca de cómo construir un módulo para Drupal:

http://www-128.ibm.com/developerworks/ibm/library/i-osource6/

Es un tutorial que muestra de forma detallada el proceso completo a seguir para la construcción de un módulo, concretamente un recordatorio de eventos para la web. Un ejemplo muy acertado que enseña muchos de los motivos por los que Drupal resulta una herramienta tal versátil y fácil de extender. El módulo explicado cubre una gran cantidad de hooks, explicando la utilidad de cada uno de ellos, el momento preciso en que Drupal los llama, cómo utilizarlos para añadir atributos propios a los nodos, cómo mantenerlos sincronizados en todo momento con estos, y cómo personalizar la presentación de los mismos en la web, hasta cómo añadir bloques propios y ejecutar tareas periódicas a través del cron. Muy recomendable.

Después de leerlo me han entrado ganas de traducirlo al español, aunque luego he pensado que podría tener problemas con la licencia de IBM y al final no me he molestado ni en buscarla.