Actualización de portales web basados en Drupal (versión 5.7)

El día de hoy actualicé cuatro de los cinco portales web que tengo desarrollados con Drupal a la versión 5.7.

No encontré ninguna novedad en el protocolo de actualización frente a los pasos de actualización que establecí con las otras versiones.

Lo único particular fue que el módulo Localizer que permite mantener veriones de los nodos en varios idiomas pidió que le agregara la siguiente línea al final del archivo sites/default/settings.php.

include_once('sites/all/modules/localizer/localizer_settings.php');

Sin embargo ese archivo incluido no existe en esa ubicación. Yo realicé la modificación con la siguiente línea.

include_once('modules/localizer/localizer_settings.php');

Plugin CodeHighlighterPlugin de wordpress

Esta semana instalé el plugin CodeHighlighterPlugin para WordPress el cual está basado en GeSHi como su motor genérico para resaltar la sintaxis.

El código fuente a resaltarse se debe encerrar entre etiquetas <pre> las cuales aceptan los siguientes parámetros.

Lenguaje del código fuente (lang=”XXX”). Es obligatoria e indica en que lenguaje se encuentra el snippet de código fuente inscrito. Su valor debe ser una de las siguientes cadenas.

actionscript, ada, apache, asm, asp, bash, c, c_mac, caddcl, cadlisp, cdfg, cpp, csharp, css, delphi, html4strict, java, javascript, lisp, lua, mpasm, nsis, objc, oobas, oracle8, pascal, perl, php, python, qbasic, sas, smarty, vb, vbnet, visualfoxpro, xml

Número de línea (lineno[=d]). Es opcional, si está presente hace que las líneas de código se presenten numeradas. Adicionalmente es posible especificar un valor a partir del cual se numerarán las lineas.

#include < stdio.h >

int main(void)
{
	printf ("Hola Mundo");
}

Otro ejemplo.

function hola($nombre)
{
    return "Hola " . $nombre;
}

Actualización de portales web basados en Drupal

La prueba de que hace rato que no escribía nada en este blog es que ya salió una versión de nueva de Drupal y por poco quedan seguidos los dos registros de actualización.

El día de hoy actualicé los 5 portales web que tengo en este momento basados en Drupal con la nueva versión: 5.6 la cual soluciona hallazgos de seguridad y por lo tanto la actualización es strongly recommended.

Mas información acerca de la actualización en: http://drupal.org/drupal-5.6

El protocolo de actualización que utilice fue el mismo de la vez pasada.

$ mv site site.old

$ tar zxvf $HOME/drupal-5.6.tar.gz

$ mv drupal-5.6/ site

$ mv site/modules/ site/modules.new

$ cp -rf site.old/files site

$ cp -rf site.old/sites site

$ cp -rf site.old/themes/MITEMA site/themes/

$ cp -rf site.old/modules site

$ cp -rf site/modules.new/* site/modules

$ rm -rf site/modules.new

(web) $URL/apps/site/update.php

(web) $URL?q=admin/logs/updates

(web) $URL/apps/site/update.php

$ rm $HOME/drupal-5.6.tar.gz

Actualización de portales basados en Drupal

En la mañana de hoy realicé la actualización de los cinco portales web basados en Drupal que estoy desarrollando actualmente. Este software pasó rápidamente de la versión 5.2 que tenía instalada a la nueva 5.5.

A continuación describo el protocolo de actualización que realicé en cada uno de los sitios.

Realizar el inicio de sesión en el Portal Web como un usuario Administrador utilizando un navegador web.

A través de una conexión de SSH realizar las siguientes acciones.

Renombrar el directorio del sitio (site) para conservarlo como copia de seguridad en vivo (además de la copia de seguridad real).

$ mv site site.old

Descomprimir la nueva distribución de Drupal, los archivos resultantes quedarán en el directorio actual.

$ tar zxvf $HOME/drupal-5.5.tar.gz

Renombrar el directorio de Drupal recién descomprimido para convertirse en el nuevo sitio (site).

$ mv drupal-5.5/ site

Renombrar la carpeta de los módulos de la nueva versión para evitar su sobreescritura.

$ mv site/modules/ site/modules.new

Copiar los archivos (files) de la versión instalada a la nueva instalación.

$ cp -rf site.old/files site

Copiar el directorio de los sitios (sites) con la información de conexión a la base de datos.

$ cp -rf site.old/sites site

Copiar los temas personalizados de la versión instalada a la nueva.

$ cp -rf site.old/themes/MITEMA site/themes/

Copiar los módulos del sitio antigüo al nuevo en instalación.

$ cp -rf site.old/modules site

Copiar los nuevos módulos del núcleo (core) al directorio de módulos sobreescribiendo los antigüos.

$ cp -rf site/modules.new/* site/modules

Remover la carpeta con los módulos de núcleo nuevos.

$ rm -rf site/modules.new

Acceder a la siguiente dirección web utilizando un navegador para completar la instalación del sitio. Se deberá reemplazar $URL por la dirección del Portal Web.

$URL/apps/site/update.php

Verificar los requerimientos de actualización de los diferentes módulos instalados según disponibilidad de los mismos. Para esto se debe consultar la siguiente dirección utilizando un navegador web. Se requiere que el Portal Web tenga instalado previamente el módulo Update Status.

$URL?q=admin/logs/updates

Actualizar los módulos que sea necesarios reemplazando sus archivos en el directorio $PATH/modules con las nuevas versiones.

Ejecutar nuevamente el script de actualización del sitio visitando la siguiente dirección con un navegador web.

$URL/apps/site/update.php

Remover el archivo de distribución original de Drupal.

$ rm $HOME/drupal-5.5.tar.gz

Terminar.

Jugando con InnerHTML (3)

Al ejemplo anterior de tablas dinámicas utilizando JavaScript que permitía agregar y eliminar filas dinámicamente del lado del cliente le hice algunas modificaciones que encontré necesarias cuando lo utilicé en un caso práctico. El ejemplo permite ahora agregar un documento de identidad que actuará como llave primaria del registro. El documento se muestra como texto estático y además se incluye como campo oculto (hidden) para que sea reconocido por la aplicación del lado del servidor.

Los demás campos son presentados en la tabla como campos editables (input) para permitir su modificación por parte del usuario hasta el momento de hacer el envío.

El ejemplo puede consultarse en el siguiente enlace: Test InnerHTML 3

Menú de opciones con bordes redondeados

Uno de los portales que se están desarrollando en la Fundación tenía una barrita de menú con botones redondeados. Los amantes del Flash dijeron rápidamente que ellos lo hacían fácilmente en Flash que no me preocupara; todo quedó así … hasta hoy. Hoy lo estuvieron pensando y se dieron cuenta que era muy difícil y dispendioso crear las imágenes y tratar de cambiar de color el botoncito según esté seleccionado o no. Por suerte yo ya estoy superando esta gripa y amanecí con ganas de un poco de carpintería.

Lo primero que hice fue buscar la librería de JavaScript Nifty Corners que ya había visto con anterioridad para tal fin, sin embargo en la búsqueda también encontré una segunda y dejé que la revisión de los ejemplos determinara cual iba a utilizar. Resulta que Curvy Corners si permite darle un borde al botón redondeado … o al menos si lo muestra en un ejemplo, así que la escogí.

Creo algunos DIV de clase miBoton con IDs boton1, boton2, boton3, … Ahí es donde entra a jugar Curvy Corners.

Se incluye la librería de Javascript.

<script type="text/JavaScript" src="rounded_corners_lite.inc.js"></script>

En la función onLoad de la página se especifican las propiedades de la redondez y se asocia esta con los elementos de la clase miBoton.

settings =
{
tl: { radius: 10 },
tr: { radius: 10 },
bl: { radius: 10 },
br: { radius: 10 },
antiAlias: true,
autoPad: true,
validTags: ["div"]
}

var myBoxObject = new curvyCorners(settings, "miBoton");
myBoxObject.applyCornersToAll();

Por mi parte creo la función cargarBotones() que establece la referencia global a los botones incluyendo el objeto HTML y enlace a donde se deberá dirigir el navegador cuando le hagan click.

Igualmente implementé la función colorearBotones() que le pone el fondo verde a los botones no seleccionados y naranja a los seleccionados.

La solución fue muy sencilla. Lo bueno es que hasta ahora cumple con lo que necesitaba el cliente y se desarrolló bastante rápido la solución. Lo malo fue que, como cosa rara, cuando verifiqué que funcionara con IE7 … todo se derrumbó.

Inicialmente sólo aparecía la cajita de los botones, vacía y cuadrada. Nada funcionaba. Lo probé en mi equipo que tiene instalado el JavaScript Debugger de Microsoft y se quejaba de una linea de la librería de CurvyCorners … ni idea porqué. Verifiqué el ejemplo y este funcionaba sin problemas así que comparé mi código con el del ejemplo … nada extraño. Hice una copia y empecé a convertir mi código en el código de ejemplo hasta que lo hice funcionar … no había nada raro … solamente el color de los botones. Había puesto que fueran green normalmente y orange si los habían seleccionado; pues parece que IE no entiende inglés, sólo hex.

Cambié la especificación de los colores y todo empezó a fallar extrañamente, a ratos, sin sentido. Quité los llamados de colorearBotones() y algunos botones se coloreaban y otros no. Obra de satanás. Comenté el código de la función y coloreamiento se detuvo.

Tuvo que pasar otro rato para que me diera cuenta que ese útil navegador no estaba refrescando bien la página cada vez que yo le daba F5 y me estaba mostrando versiones antiguas. Conclusión con IE es mejor darle siempre CTRL-F5 para que refresque completamente.

Se puede consultar el código fuente del ejemplo haciendo click en el siguiente enlace: test_curvycorners

Jugando con InnerHTML (2)

Bien, encontré una mejor forma de hacerlo … con DOM.

Insertar una nueva fila en una tabla (destino) es fácil, sólo es establecer donde se quiere e insertarla.

var nuevo_indice = destino.rows.length;
fila = destino.insertRow(nuevo_indice);

Después es necesario especificar el contenido de las celdas, para el ejemplo, un checkbox y dos valores de texto.

celda = fila.insertCell(0);
valor = document.createElement("input");
valor.type = "checkbox";
valor.id = "marca";
valor.name = "marca";
valor.value = nuevo_indice;
celda.appendChild(valor);

celda = fila.insertCell(1);
valor = document.createTextNode(nombres + " - " + nuevo_indice);
celda.appendChild(valor);

celda = fila.insertCell(2);
valor = document.createTextNode(apellidos);
celda.appendChild(valor);

Para remover las filas obtengo una referencia a los elementos que sean input y pertenezcan a la tabla.

var inputs = origen.getElementsByTagName("input");

Después filtro los que sean checkbox y sean los que me interesan (id=’marca’). Los almaceno en un arreglo.

for (i=0; i<inputs.length; i++)
{
if (inputs[i].type == "checkbox" &&
inputs[i].id == "marca" &&
inputs[i].checked)
{
checkboxes[chk_cuenta] = inputs[i];
chk_cuenta ++;
}
}

Después de filtrados procedo a eliminarlos.

for (i=0; i<checkboxes.length; i++)
{
origen.deleteRow(checkboxes[i].value - 1*i);
}

En este punto encontré un serio problema. El value de los checkboxes seleccionados me indica cuales son las filas que deseo remover, pero después de remover la primera de ellas la continuidad de las filas se altera ya que se eliminó un elemento. Para compensar esto se disminuye 1*i el índice de la fila, siendo 0 para el primer caso cuando no se ha alterado, 1 cuando se ha removido una fila y así sucesivamente.

La solución anterior soluciona el problema durante un procedimiento de eliminación de filas, sin embargo al terminar la tabla queda con sus índices alterados y por consiguiente va a fallar la siguiente eliminación y posiblemente la adición de filas también va a ser confusa. Para esto tuve que corregir los índices de las filas tan pronto como se termina la remoción.

for (i=0; i<inputs.length; i++)
{
if (inputs[i].type == "checkbox" &&
inputs[i].id == "marca")
{
inputs[i].value = i + 1;
}
}

El archivo fuente del ejemplo se puede descargar del siguiente enlace: test_inner2.html

Jugando con InnerHTML

Con este ejemplo muy sencillo es posible agregar filas de una tabla en el lado del cliente sin hacer un requerimiento al servidor y ahorrarse uno la consabida lentitud, útil en momentos de agregar items a una lista. Obviamente, a diferencia de Ajax, los elementos sólo viven en el lado del cliente hasta que se envían, en un sólo requerimiento, hacia el servidor donde son almacenados en la base de datos.

La idea es crear una tabla (info) que va a contener los datos.

<table id="info" name="info" class="tabla">
<tr class="titulos">
<td>
Nombres
</td>
<td>
Apellidos
</td>
</tr>
</table>

Un formulario desde el cual se agregarán nueva información.

<form id="datos" name="datos" onsubmit="return agregar_fila(this)">
Nombres: <input type="text" id="nombres" name="nombres" value="" size="25" />
Apellidos: <input type="text" id="apellidos" name="apellidos" value="" size="25" />

<input type="submit" id="agregar" name="agregar" value="Agregar" />
</form>

Y una función de JavaScript que agregará la nueva información (nombres y apellidos) a la tabla.

function agregar_fila(origen)
{
nom = origen.nombres.value;
apl = origen.apellidos.value;

document.getElementById("info").innerHTML += "<tr class='fila'>
<td>
" + nom + "
</td>
<td>
" + apl + "
</td>
</tr>";

return false;
}

El archivo de ejemplo puede descargarse desde el siguiente enlace: test_inner.html

Por fin un ejemplo de Box Model entendible (2da. parte)

Bueno, no me aguanté las ganas de seguir haciendo pruebas. Esta vez con Layout #13 de Layout Gala.

El ejemplo anterior tomado de Matthew Levine estaba elegante pero no quiso funcionar en IE.

Simplifiqué un poco el ejemplo y esto fue lo que obtuve.

test_div2a.gif

Me hace falta lograr que las columnas izquierda (azul) y derecha (rojo) ocupen tanto espacio como ocupe la columna central (salmón), sin embargo si utilizo height: 100% intentan tomar el alto de la pantalla.

Por ahora este es un gran paso para -mi- humanidad en la lucha contra las cajas.

El archivo de prueba puede descargarse del siguiente enlace: test_div2a.html.

Por fin un ejemplo de Box Model entendible

Hace hace muy poco no había querido trabajar con CSS. Siempre encontraba una rápida respuesta para mejor hacerlo de la manera convencional … es mas rápido, no tengo tantos problemas, no se complica tanto, etc. En el último par de meses en los que he estado de webmaster adaptando la presentación de algunos portales a la provista por el publicista de la Fundación he aprendido algunas cositas y como todo lo que aprendo, me ha terminado gustando mucho.

Una de las cosas de las que en realidad no he logrado entender completamente es el box model (modelo de cajas) de CSS. Yo quiero hacer lo que la teoría sugiere: en el HTML dejar sólo el contenido y en CSS especificar como se va a presentar esa información. Según esto, yo quiero que el layout (distribución) de mi página esté dada por el CSS con DIVs y no en el HTML con TABLE. Pero ah que cosa mas extraña para mi.

Le he sacado tiempo en varias oportunidades pero no lo he logrado. Lo mas cerca que he estado funcionaba perfecto en Firefox pero se corría inexplicablemente en IE … como siempre.

Hoy amanecí con ganas de volver a intentarlo y encontré un par de enlaces muy interesantes. Entre ellos me gustó In Search of the Holy Grail de Matthew Levine quien se toma su tiempo para explicar la implementación de una página con tres columnas, dos de ellas de ancho fijo y el centro líquido (consume el tamaño complementario) y con una estructura de DIVs simple, tal y como yo la quería.

<div id="header">Este es el header</div>
<div id="container">

<div id="center" class="column">Este es el centro</div>
<div id="left" class="column">Esta es la izquierda</div>
<div id="right" class="column">Esta es la derecha</div>
</div>
<div id="footer">Estos son los pies</div>

Este código HTML produce el siguiente resultado después de ser mezclado con el CSS correspondiente.

demo_css_div

Como siempre … en Firefox funciona perfecto, lo acabo de probar en IE7 y se enloquece, a pesar de que el autor menciona que funciona en los principales navegadores.

El archivo de prueba que utilicé se puede descargar del siguiente enlace: test_div.html.

Espero mas adelante tener un poco mas de tiempo y hacerlo funcionar ya que no quiero seguir haciendo páginas basadas en TABLEs.

Otro enlace relacionado con el tema que se ve prometedor es Layout Gala (http://blog.html.it/layoutgala/) en el que se presentan varios diseños basados en columnas.