Blog de Israel Viana

Artículos de Junio de 2009

Tuenti se endurece

25 de junio de 2009 | 1 comentario

Tuenti prohibe enlazar

Hace algunas semanas, nuestros amigos de Tuenti cambiaron las condiciones de uso. Cuando las leí me flipó bastante la cláusula en la que prohiben poner enlaces a Tuenti a todo el mundo, cosa imposible según la ley, ya que los términos de un contrato sólo afectan a las partes que lo suscriben. Esta novedad, junto con la de pedir el DNI a los menores (al estilo portero de discoteca) ha sido lo que más me ha llamado la atención del nuevo acuerdo. Como no tengo tiempo para analizar los términos de forma más detallada, os dejo con la sabiduría de Samuel Parra, al que también le han chocado las dos nuevos cláusulas que he comentado.


Spaghetti a la carbonara

22 de junio de 2009 | 2 comentarios

He aquí un maravilloso ejemplo de código espagueti que he encontrado en... bueno, mejor correr un es-tupido velo.

function revisar_email(correo) {
		var nombre_valido = false;
		var servidor_valido = false;
		var dominio_valido = false;
		var email = correo.value;
		if (email != ""){
			// se comprueba si ha metido algo en el campo
			if (email.indexOf('@') != -1){
				// se comprueba si contiene la @
				var array1 = email.split('@');
				if ((array1[0] != "") && (array1[1]) != ""){
					// se comprueba que tenga caracteres delante y detrás de la @
					if (array1[1].indexOf('.') != -1){
						// se comprueba si tiene . detrás de la @
						var array2 = array1[1].split('.');
						if ((array2[0] != "") && (array2[1]) != ""){
							// se comprueba si tiene 2 partes después de la arroba
							var nombre = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.";
							var dominio = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
							var i, j;
							for (i = 0; i <= array1[0].length; i++){
								if (nombre.indexOf(array1[0].charAt(i)) == -1){
									// revisamos que los caracteres del nombre sean correctos
									nombre_valido = false;
									break;
								}
								else{
									nombre_valido = true;
								}
							}
							for (i = 0; i <= array2[0].length; i++){
								if (nombre.indexOf(array2[0].charAt(i)) == -1){
									// revisamos que los caracteres del servidor sean correctos
									servidor_valido = false;
									break;
								}
								else{
									servidor_valido = true;
								}
							}
							if(array2[1].length > 1){
								// revisamos que la longitud del dominio sea mayor a 1
								for (i = 0; i <= array2[1].length; i++){
									if (dominio.indexOf(array2[1].charAt(i)) == -1){
										// revisamos que los caracteres del dominio sean correctos
										dominio_valido = false;
										break;
									}
									else{
										dominio_valido = true;
									}
								}
							}
						}
					}
				}
			}
			if ((nombre_valido == true) && (servidor_valido == true) && (dominio_valido == true)){
				// si todo es correcto devuelve true
				return true;
			}
			else{
				alert("El formato del email no es correcto.");
				return false;
			}
		}
	}

66 líneas para validar una dirección de email. Vaya, ¿y si usamos una expresión regular?

function revisar_email(correo) {
	var filtro = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	if (!filtro.test(correo)) {
		alert('La dirección de correo electrónico no es correcta');
		return false;
	} else {
		return true;
	}
}

¡Hombre! ¡La misma funcionalidad implementada en 8 líneas! Moraleja:

  • El mal programador es malo en JavaScript, en Java y en cualquier otro lenguaje que toque.
  • Las expresiones regulares son nuestras amigas. Son feas y antipáticas, pero son nuestras amigas.
  • Dice Linus Torvalds que nunca deberían ser necesarios más de 3 niveles de anidamiento. Yo más bien pondría el límite en 5.
  • ¡Por Dios, no llames a tus variables array1 o array2! Utiliza nombres que tengan algún significado
  • Cuantas menos líneas de código, menos probabilidad de errores.
  • Cuantas menos líneas de código, más rápido será el algoritmo.
  • Cuantas menos líneas, más sencillo y fácil de comprender será el código para tus semejantes.
  • Las validaciones de formularios se hacen en el servidor. Por mucho JavaScript que haya puedo usar Tamper Data para enviar directamente datos no válidos.

La canción del lunes: "Here To Stay" (Pat Metheny)

22 de junio de 2009 | 2 comentarios

Después de mucho pensarlo he decidido escribir también sobre música. Pero poco a poco, no vaya a ser que los que me seguís encontréis en este pequeño foro una fuente más de ruido y no queráis volver a leerme (si es así, te recuerdo que puedes utilizar Yahoo! Pipes para filtrar el feed y eliminar los temas [tags] que no te interesen).

Una canción a la semana me parece un buen comienzo, ¿no? Porque más vale una buena canción el lunes para levantar el ánimo que no un disco entero para pasar toda la tarde del domingo en casa ;-P

Empezaré con uno de mis temas favoritos, y que llevo en mi móvil como tono desde hace tiempo: Here to Stay, de Pat Metheny. Pertenece a un disco, "We Live Here", editado en 1995, que es uno de los más rompedores, smooth-jazz y funky del que quizá haya sido el guitarrista con más influencia en el jazz en el último cuarto del siglo pasado.

La canción empieza sorprendiendo al aficionado habitual de Pat Metheny, por sus teclados de fondo y los samplers de percusión, y sobre todo por el ritmo de la canción. Enseguida entra el sonido único e irrepetible de la cuerpo-hueco de Pat, y el inconfundible y sabroso piano de Lyle Mays. A partir de ahí, cambios de tono, solos y fraseos muy jazzísticos pero muy agradables al oído.

En definitiva, que es uno de esos temas que te aconsejo escuchar bien cómodo en tu sillón, con los ojos cerrados y dejándote llevar por el sentimiento intenso que imprime Pat en cada uno de sus temas. Te invito a que la disfrutes y, si te gusta, te la descargues.

Audio original:

En directo la canción no pierde su magia:


La nueva web de la Universidad Católica

18 de junio de 2009 | 1 comentario
Nueva web de la UCAM

Hoy la Universidad Católica, a la que tengo el honor de pertenecer como alumno (tranquilos, es sólo peloteo en época de exámenes) ha lanzado la nueva version de su web (también en prensa). Un nuevo diseño y unas nuevas tripas, basadas en Plone. Conozco el equipo que está detrás del proyecto (yo mismo estuve involucrado en sus comienzos), el talento que se ha derrochado y la gran cantidad de horas que se han invertido. Desde hace dos años, el Servicio de Actividades Web ha infundido esperanza y ganas de trabajar en un cambio radical para la estructura comunicativa más importante de la Universidad.

Me quito el sombrero ante la transformación que se ha ejercido en la cultura de una empresa como la UCAM y el esfuerzo que ha significado pasar de una cutre y asquerosa página web en HTML estático, sin ninguna estructuración del contenido, sin orden ni diseño... a un diseño bonito, una descentralización de la gestión de los contenidos (vamos, que ahora todos los empleados podrán gestionar su parcela del portal) y una plataforma técnica que puede aguantar tanto la oferta (estructuras de contenido bien diseñadas, jerarquía de los usuarios) y la demanda (información actulizada, interacciones útiles, etc). Y lo que es quizá más importante: se ha pasado de un equipo sin formación específica en desarrollo web ni habilidades comunicativas, a uno suficientemente preparado y lleno de entusiasmo.

Desde este humilde púlpito, mi más sincera felicitación a Samu, Piti, Marco, Lola, Vito, Andrés, Óscar, Víctor, Lola y un interminable etcétera de gente con ganas de trabajar por un cambio que ya se está empezando a notar en la Universidad.

Y ahora, las críticas, ¿o creías que no llegarían? ;-) Me fijaré en el aspecto técnico y de diseño de la nueva web. De todo lo demás, hay poco hay criticable (si acaso que se comunicase a la comunidad universitaria el cambio, habilitar tutoriales que mostrasen las nuevas posibilidades y un canal de feedback).

Empecemos por el principio: entrando en www.ucam.edu nos encontramos con un diseño suave y vivo con demasiado color azul (en cantidad y variedad). Para mi gusto, el fondo azul de la cabecera se estira más de lo deseable, es más, la altura a la que termina no está alineada con ningún elemento del contenido... vamos, que no hay ninguna razón para que esté ahí. En el área de búsqueda (arriba a la izquierda), los elementos están desordenados: el CSS cross-browser ha dado muchos problemas.

Ni el XHTML ni el CSS son válidos, la maquetación principal se basa en tablas y el CSS es realmente confuso (código espagueti en toda regla): definiciones redundantes, mal uso de la herencia, nula organización del código, sintaxis irregular... y lo mismo se podría decir del XHTML. Si quieres comprobarlo, desactiva el CSS en tu navegador y verás como la página se hace infumable. O prueba también desde el móvil.

Más allá del diseño, el principal error que se ha cometido es la no retrocompatibilidad del sitio, sobre todo en cuanto a URL y que faltan muchos contenidos por migrar. Ya que las direcciones han cambiado, muchos servicios dejarán de funcionar (por ejemplo, el calendario del campus virtual apunta a dirección que ya no existe), y por supuesto el posicionamiento en los buscadores bajará considerablemente. Esto tiene varias soluciones posibles, en mi opinión la más sencilla es utilizar la re-escritura de URL en un proxy web (que de hecho ya tienen para caché), de dos maneras posibles: manteniendo la antigua web bajo un subdominio diferente, y redireccionar todas las URLs antiguas al servidor antiguo; o bien redireccionar las antiguas URL a las correspondientes en el nuevo servidor (claro que eso exigiría tener todos los contenidos migrados). Ah, y en ambos casos añadir la correspondiente cabecera 301 para que los buscadores sepan que las URL están obsoletas.

Sobre la migración de los contenidos, si no ha sido realizada automáticamente, no se explica que se mantengan viejas URL, páginas mal maquetadas, datos incoherentes, información repetida, etc. Un buen ejemplo en la sección de extensión universitaria. Está claro que en cuanto a contenidos, hay mucha tela que cortar. A una marabunta de empleados y deptartamentos subiendo y migrando contenidos tiene que enfrentarse un gabinete de gestión de contenidos que esté domine las áreas de accesibilidad, usabilidad, comunicación, redacción para web, etc.

Y sobre Plone, poco que decir: es un CMS basado en Zope y CMF. En mi opinión, es el gestor de contenidos perfecto para un portal web tan grande y ambicioso como este. Es suficientemente robusto y flexible como para que el día de mañana los servicios de aprendizaje on-line e intranet estén integrados en esta plataforma. También puede sincronizarse con las bases de datos de usuarios que ya tiene la universidad. Además, su arquitectura y la de su base de datos orientada a objetos es perfecta para adoptar metodologías y tecnologías semánticas.

Una vez más, mi felicitación para los artífices de esta ambiciosa obra. Ojalá pudiera volver a colaborar con vosotros.


El patrón Strategy y las llamadas dinámicas en PHP

15 de junio de 2009 | 2 comentarios

Sigo explorando las novedades de PHP 5.3 y, entre ellas están las llamadas dinámicas a métodos estáticos, según he visto en esta interesante presentación de Ilia Alshanetsky. Veamos un ejemplo:

class Aplicacion {

	public static function getVersion() {
		return "1.2";
	}

}

$metodo = "getVersion";

Aplicacion::$metodo(); //Devuelve "1.2"

Se ve claramente que podemos llamar a un método estático cuyo nombre no definimos al escribir el código, sino que está en una variable. Esta característica ya estaba disponible en versiones anteriores de la rama PHP 5, tanto para clases como para métodos, pero no estáticos:

class Conexion {

	public function conectar($servidor, $usuario, $clave) {
		echo "Mira Mamá, me estoy conectando!";
	}

}

$clase = "Conexion";
$método = "conectar";

$objeto = new $clase();
$objeto->$método("localhost", "pepito", "grill0");
//Imprimirá "Mira Mamá, me estoy conectando!"

Bueno, y esta característica parece interesante, pero ¿cómo podemos aplicarla a la vida real? Uno de los ejemplos más claros que se me ocurre es la implementación del patrón de diseño Strategy. En este sencillo patrón se trata de cargar una u otra implementación de una clase dependiendo de alguna variable o acción del usuario. Por ejemplo, imaginemos que queremos conectarnos a bases de datos Oracle o MySQL, según qué servicio escoja el usuario desde un formulario. Primero definimos una clase abstracta Conexion que declare los métodos que las implementaciones han de desarrollar, y escribimos sendas clases hijas para Oracle y MySQL:

abstract class Conexion {

	private $recurso;

	public function conectar($usuario, $clave) { }
}


class ConexionOracle {

	public function conectar($usuario, $clave) {
		$this->recurso = oci_connect($usuario, $clave);
	}

}

class ConexionMysql {

	public function conectar($usuario, $clave) {
		$this->recurso = mysql_connect("localhost", $usuario, $clave);
	}

}

/*
 * $_POST['dbms'] proviene de un cuadro desplegable (option select) en que se
 * da a escoger entre oracle y mysql.
 * ucfirst() pone en mayúscula la primera letra
 */

$conector = "Conexion" . ucfirst($_POST['dbms']);
$instancia = new $conector;

try {
	$instancia->conectar($_POST['usuario'], $_POST['clave']);
} catch (Exception $e) {
	echo "Lo siento, pero por algún motivo la conexión ha fallado";
}

En fin, esto es todo, creo que es evidente la potencia de esta característica del lenguaje, que viene a intentar evitar el uso de eval() y dar al lenguaje un poco más de elegancia, al estilo del class.forName() de Java. Por cierto, para una descripción más profunda del patrón Strategy te recomiendo este interesante artículo de Jack Herrington sobre patrones implementados en PHP.


Genera tus Entidad/Relación circulares con SchemaBall-PHP

8 de junio de 2009 | 0 comentarios

Gráfico generado con SchemaBall-PHP

Inspirándome en el SchemaBall de Martin Krzywinski este fin de semana he escrito SchemaBall en PHP. Se trata de un generador de gráficos que representan las tablas de una base de datos y sus relaciones, al estilo de un diagrama entidad/relación. Aún está bastante verde, y la mayor carencia que tiene es que no distingue relaciones de cardinalidad N:N, es decir, aquellas donde la relación está expresada en una tabla intermedia y dos claves foráneas. Además, sólo es compatible con MySQL, aunque mi intención es darle compatibilidad con más gestores de bases de datos, e integrarlo en MagiSQL, del que tendrás noticias en breve ;-)

Por lo demás, añadiré al gráfico alguna representación de los campos, para poder visualizar la complejidad de las tablas de algún modo. Además, me gustaría añadirle interactividad, pero para ello habría que cambiar completamente la plataforma gráfica, pasando de imágenes PNG generadas con GD al Canvas de HTML o incluso Flash.

En fin, sólo es un adelanto para una librería que espero que crezca y se convierta en una herramienta útil para los diseñadores/administradores de bases de datos. ¿Opiniones? ¿Sugerencias? ¿Críticas? ¿Insultos racistas? Los comentarios están abiertos y en cuanto el SVN me funcione (hoy los astros se han alineado favorablemente xD) subiré el código.

PD: la librería para generar este tipo de gráficas estará disponible de forma independiente, para que se pueda utilizar para información diferente al esquema de una base de datos.


¡Hemos ganado las elecciones!

8 de junio de 2009 | 7 comentarios

En estos comicios la participación ha vuelto a caer a un mínimo histórico al situarse en el 43,01%, por debajo del 45,47% registrado hace cinco años. Eso significa que la abstención ha aumentado hasta el 57%. En España nos hemos quedado bastante cerca de esa cifra, con un 54%.

No sé si por desinterés o desencanto, pero la mayoría de los europeos no hemos votado. La mayoría de los europeos nos hemos resistido a participar en un gran circo que aúna ultraderechistas, manipuladores, vividores y masones a partes desiguales.

Y, al participar menos de la mitad de los ciudadanos, las elecciones pierden todo su sentido. Por eso el sistema mal llamado democrático al que estamos resignados se ha reído de nosotros a la cara, proclamando que los parlamentarios representan a una mayoría cuando ni siquiera ha habido una proporción mínima. Hoy la Democracia, la de verdad, ha vuelto a fracasar.


Patrones de desarrollo web: componentes HTML reutilizables

2 de junio de 2009 | 0 comentarios

Cuando construimos aplicaciones con muchos formularios u otras secciones con fragmentos repetitivos, a veces utilizamos componentes, como puede ser un cuadro desplegable (combo box u option select, llámale como quieras) para elegir una ciudad. Ya que las páginas se generan en el servidor (PHP, Java, Ruby...), se han inventado diversos artificios para reutilizar estos componentes: simples funciones o variables que devuelven el código HTML deseado, mini-plantillas (Smarty), elements de CakePHP, etc.

Pero ¿y si no estamos generando esos formularios en el servidor, sino dinámicamente en JavaScript? La solución en el cliente es disponer de componentes de diseño como fragmentos de HTML invocables por AJAX. Así de sencillo.

Por ejemplo, imaginemos que nuestra aplicación/web tiene muchos formularios en los que elegir una ciudad en un control option select. Si estamos generando formularios a través de JavaScript, sería muy útil disponer de una URL invocable a través de AJAX que nos devolviese algo como

<select>
	<option value="1">Vigo</option>
	<option value="2">Murcia</option>
	<option value="3">Sevilla</option>
</select>

Y si agregamos algunas opciones...

<?php $opciones = array("Vigo", "Murcia", "Sevilla") ?>
<select name="<?php echo $_GET['nombre'] ?>">
<?php foreach ($opciones as $n=>$nombre) { ?>
	<option value="<?php echo $n ?>" <?php if ($_GET['valor'] == $n) echo "selected=\"\"" ?>><?php echo $nombre ?></option>
<?php } ?>
</select>

Entonces tenemos algo como form_ciudades.php?nombre=xxx&valor=yyy que nos devolverá un option select de nombre xxx con el valor yyy seleccionado por defecto.

Si combinamos esto con alguna función que envuelva peticiones AJAX y nos devuelva el contenido requerido de forma sencilla, conseguiremos un código fácilmente legible. Aquí va un ejemplo real, que estoy utilizando para una práctica de la universidad:

$("#detalles > table").html(
	   "<tr><td>Aerolínea:</td><td>" 
	   + ajax("sn_aerolineas.php?nombre=aerolinea&valor=1") 
	   + "</td></tr>"
	   + "<tr><td>Origen:</td><td>" 
	   + ajax("sn_localidades.php?nombre=origen&valor=1") 
	   + "</td></tr>"
	   + "<tr><td>Destino:</td><td>" 
	   + ajax("sn_localidades.php?nombre=destino&valor=1") 
	   + "</td></tr>");

Para quien no conozca jQuery, la función $("#detalles > table") devuelve la tabla que hay dentro del elemento del contenedor "detalles", y la función html() cambiará su innerHTML. ajax es una pequeña y sucia función que me devuelve directamente una respuesta AJAX.

Este patrón se puede aplicar para muchos más casos, como selectores de fecha (input + calendario), o incluso llamadas que devuelvan datos mucho más pequeños, como la foto de un usuario o una lista de categorías. Pero recuerda que este patrón debe ser aplicado sólamente cuando se generan elementos dinámicamente. Es decir, usa AJAX sólo cuando sea necesario para mejorar la usabilidad y/o el rendimiento de tu sitio.


israelviana.es es propiedad de Israel Viana, escrito en Murcia (España). Puedes ponerte en contacto conmigo a través de la dirección de e-mail .com.
Información en RDF Metadatos Dublin Core Creative Commons License