Hace un par de días comencé a notar una cosa. Primero fue con twitter y su nueva funcionalidad (que al parecer por el momento la han deshabilitado) de actualizar el sitio cada vez que hay twitts nuevos. Me encantaba por que solo dejaba la ventana abierta y en cualquier momento el titulo de la pestaña cambiaba para indicar cuantos twitts nuevos había. Es mucho más fácil estar al tanto de twitter (y esclavizase a él) de esa manera sin tener que tener otra app abierta. Después comencé a notarlo con otros sitios. Por ejemplo, http://scobleizer.com/ actualiza su barra lateral cada cierto tiempo. Llegó el momento que me dije a mi mismo, Gush! este sitio está vivo!. No es la primera vez que veo que un sitio se mueve por si solo. He visto cientos de rolling menus, y sitios que de una u otra forma “se mueven”, pero eso no me impresiona. Después de todo, todo eso que se mueve no es más que un loop, algo que alguien programó antes y que no cambia-un .gif programado. Sin embargo, estos sitios están no solo moviéndose, sino auto actualizándose para mostrarte el nuevo contenido y es eso precisamente lo que causa la sensación de WOW!

Como programador que soy, se que todo lo que hay detrás no es más que ajax, pero la verdad aun así me impresionó. Probablemente sea por que es una de las primeras veces que veo ajax empleado de forma usable, amigable y responsable, o quizá solo me agarró desprevenido y me sorprendió. Cualquiera que sea la razón, la verdad que por un momento me hizo sentir que estaba viendo algo vivo, algo que se movía, y me produjo la sensación que te produce ver cuando un recién nacido mueve una mano-simplemente increíble. Posiblemente esté exagerando, después de todo ajax ya está creciendo barba. Sin embargo, es agradable ver que finalmente los desarrolladores están aprendiendo a usarlo de forma benéfica y no solo para impresionar damiselas. Seguro que la web nos depara muchas sorpresas todavía. Apps como wave se abren paso y cada vez la web deja de ser ese papel lleno de formularios que proveen la única forma de interacción. En lo personal no me emociona las animaciones ni los drag and drop.  Eso lo veo más bien como simples trucos de feria. Los verdaderos avances en la materia son aquellos que no se notan, que han sido tan bien calculados, planeados y desarrollados que se introducen de forma natural de modo que el usuario nunca se da cuenta que lo está usando y por lo tanto nunca tiene que aprender algo nuevo ni adaptarse aun nuevo método de interacción. Way to go, pero la web es cada vez más excitante y nos exige a notros, lo programadores que de cierta manera somos participes en esa evolución web, cada vez mejores y más responsables metodologías para el uso y la aplicación de las nuevas tecnologías. Ahora solo tenemos dos caminos, sentarnos a esperar más avances en la materia, o se nosotros mismos quienes impulsemos eso avances. Tu cual escoges?

Continuando con la serie sobre ajax, veamos esta ocasión un ejemplo sencillo de la creación y el uso del objeto XMLHttpRequest, o XHR como se le conoce para abreviar. Quiero hacer notar que debido a la creciente actividad anti IE6 no quiero tratar los métodos de creación del objeto XMLHttpRequest en IE6, que generalmente requiere un try… catch. A partir de IE7, XMLHttpRequest es soportado de forma nativa, por lo que nos vamos a quedar con este método directo de acceso al objeto. Si te interesa brindar soporte para ajax en IE6, puedes buscar en la web sobre el tema.

Como una nota aparte, try… catch debería ser evitado por los problemas de desempeño que trae consigo.

Creando una nueva instancia:

Crear una nueva instancia de XHR es sumamente sencillo:


var miXHR = new XMLHttpRequest();

Con esto has creado una nueva instancia de XHR lista para ser usada, exprimida y explotada. Ahora, veamos la belleza de XHR en acción.

Para poder seguir el ejemplo, primero tienes que tener la siguiente preparación:

1)Un folder llamado ajax
2)Dentro del folder, un archivo de texto llamado texto.txt
3)Dentro del folder, un archivo HTML llamado ajax.html
4)Dentro del folder, un archivo js llamado ajax.js

El archivo de texto puede contener cualquier texto que tu quieras. El mio, por ejemplo contiene:

“Javascript doesn’t suck, you are just doing it wrong” Douglas Crockford.

Mi archivo HTML contiene tan solo el HTML necesario para ser considerado válido:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
   <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8" />
      <title>Ajax! Ah javascript ambiciosamente xtremo!!!</title>
      <script type="text/javascript" src="ajax.js"></script>
   </head>
   <body>
      <p id="ajaxPantalla"></p>
   </body>
</html>

Y mi archivo Javascript esta completamente vacío… por el momento.

Eso es todo lo que necesitas por ahora. Empecemos a trabajar en nuestro javascript:

archivo: ajax.js


window.onload = function(){
   //declaramos un event handler para el evento load de window.
}

Empezamos declarando un event handler para el evento load de window. Este nos va a permitir acceder al DOM cuando ya este totalmente cargado. El DOM, teóricamente, se termina de cargar antes de que el evento load de window sea activado, sin embargo, los métodos para poder detecta cuando el DOM ha sido cargado son, al momento de escribir este articulo, demasiado engorrosos y desde mi punto de vista no vale la pena recurrir a ellos por varias razones.
Nótese que estamos usando event handlres y no event listeners, esto es solo por comodidad, si quiere puedes usar event listeners, aun que en este ejemplo no creo que valga la pena pasar por todo el trabajo extra que eso requiere.

Continuando con nuestro ejemplo, procedamos a crear una instancia del objeto XHR y algunas variables extra que nos serán de utilidad:

archivo: ajax.js
funcion: window.onLoad


var xhr = new XMLHttpRequest();
var pantalla = document.getElementById('ajaxPantalla');
var initTime = new Date().getTime();

Empezamos por definir una nueva instancia de XMLHttpRequest, y la guardamos en una variable (xhr).
También tomamos una referencia a uno de los elementos en nuestro HTML y lo guardamos en otra variable (pantalla)
Por último, guardamos el tiempo actual en otra variable (initTime). Este ultimo paso es solo para poder ir monitorizando el tiempo que toman nuestras llamadas en ser procesadas. Al final capturaremos el tiempo de finalizado de la función y lo compararemos con el tiempo de inicio de la función para ver cuanto tiempo ha tomado el su procesamiento. Para ser mas “exactos” combendría mover la variable initTime justo al inicio, antes de xhr, de modo que el tiempo sea lo primero que se toma al iniciar la función. Sin embargo, yo lo he preferido dejar así.

Continuemos con nuestro ejemplo:

archivo: ajax.js
function: window.onload


if(xhr){
   xhr.onreadystatechange = function(){
   if(xhr.readyState == 4){
      //if(xhr.status == 200 || xhr.state == 304){
         pantalla.innerHTML = xhr.responseText;
      //}
   }else{
      //proveer mensajes para los diferentes codigos http.
   }
}
xhr.open('GET','texto.txt',true);
xhr.send(null);
}else{
   //proveer una alternativa a ajax si no está disponible.
}

Aquí es donde todo esta pasando. Primero chequeamos que efectivamente xhr esté disponible, de no ser así, proveemos un método alternativo:


if(xhr){
   ...
}else{
   //proveer una alternativa a ajax si no esta disponible
}

En este ejemplo no vamos a hablar sobre alternativas, eso lo dejaremos para ejemplos mas adelante.

Si el primer if nos da true, entonces sabemos que xhr esta disponible, por lo que es seguro continuar.


xhr.onreadystatechange = function(){
   if(xhr.readyState == 4){
      //if(xhr.status == 200 || xhr.state == 304){
         pantalla.innerHTML = xhr.responseText;
      //}else{
         //proveer mensajes para los diferentes codigos http.
      //}
   }
}
xhr.open('GET','texto.txt',true);
xhr.send(null);

Lo primero que hacemos una vez determinado que el objeto xhr está disponible, es asignar una función a su evento readystatechange. Este evento se genera cada vez que el estado de la petición cambia. En esta ocasión no hablaremos de los diferentes estados de la petición, eso lo dejaremos para el siguiente artículo. Por ahora basta con que sepas que el cuarto estado es cuando la petición ha sido exitosa y nos ha regresado los resultados.

En un ejemplo real, o si estas corriendo los ejemplos en un localhost, puedes chequear el estado (status) de la respuesta (response). Si sabes algo de los códigos http, sabrás que 200 significa OK y 304 significa no modificado. En nuestro ejemplo chequeamos si el status de la respuesta es 200 o 304, lo que significa que el documento está disponible, de no ser así, enviamos mensajes diferentes dependiendo el código http de la respuesta. En este caso no hemos incluido esos mensajes, pero implementarlos no es difícil.

Una vez determinado que el status de la respuesta es 200 o 304, podemos imprimir el contenido de nuestro archivo txt a nuestra pantalla, para eso usamos innerHTML para asignar a pantalla el texto regresado por xhr.

xhr tiene dos diferentes tipos de respuesta: responseText y responseXML. Dependiendo de lo que estés pidiendo al servidor querrás usar uno u otro. La mayor parte del tiempo estarás usando responseText, por lo que en nuestros ejemplos nos mantendremos especialmente ligados a el.

Las ultimas dos lineas son las que en realidad hacen la petición:

xhr.open() toma mínimo dos parámetros, el método (GET o POST entre otros) y la url del recurso que queremos pedir (en nuestro caso ‘texto.txt’). El tercer parámetro determina si la petición es sincrónica o asíncrona. En nuestro caso, true, le dice al navegador que la petición debe ser asíncrona. En un futuro hablare de las diferencias entre peticiones sincrónicas y asíncronas, por el momento, basta con saber que la mayor parte del tiempo usaras true como tercer parámetro.

Como una nota aparte, el tercer parámetro no debería ser nunca false por problemas de desempeño.

xhr.open() también recibe otros dos parámetros (usuario y clave) para autentificación básica. Estos los usas cuando un sitio te pide una clave y contraseña. Por ejemplo, si vas a:

http://twitter.com/statuses/user_timeline.xml

te darás cuenta que el navegador te pide una clave y contraseña. Si estuvieras haciendo una petición vía ajax a una página similar, usarías los dos últimos parámetros para especificar tu usuario y contraseña. Toma en cuenta que esto no es recomendable ya que ajax es javascript y los archivos javascript pueden ser fácilmente vistos. Su uso puede ser para, por ejemplo, autentificar usuarios usando ajax donde tanto usuario como clave sean provistos por el usuario y no “hard codded” en el javascript.

xhr.send() sirve para enviar datos. En nuestro caso no estamos enviando nada, por lo que usamos null, habrá ocasiones cuando quieras enviar datos, por ejemplo para un sitio que requiere opciones como un índice de temas en un blog. En ejemplos futuros veremos como se usa send() para enviar datos. Por ahora, no es necesario.

Este ha sido un ejemplo sencillo del uso de ajax. En futuros artículos veremos ejemplos mas complejos y útiles. Habrás notado que en este ejemplo todo sucede cuando se carga la pagina, lo cual realmente no tiene sentido. EL objetivo es poder hacer las peticiones como respuesta al input del usuario ya sea hacer click en un enlace, un botón, o simplemente enviar un formulario.

Aquí esta el código completo, notaras que he agregado algunas variables y un par de lineas para medir el tiempo que tarda (en milisegundos) nuestra petición en ejecutarse. Es simplemente para poder ir manteniendo en mente un poco el desempeño de nuestras funciones.

archivo: ajax.js (completo):


window.onload = function(){
   //declaramos un event handler para el evento load de window.
   var xhr = new XMLHttpRequest();
   var pantalla = document.getElementById('ajaxPantalla');
   var initTime = new Date().getTime();
   var finTime = null;
   var totTime = null;

   if(xhr){
      xhr.onreadystatechange = function(){
         if(xhr.readyState == 4){
            //if(xhr.status == 200 || xhr.state == 304){
               pantalla.innerHTML = xhr.responseText;
               finTime = new Date().getTime();
               totTime = finTime - initTime;
               alert(totTime + 'milisegundos');
            //}
         }else{
            //proveer mensajes para los diferentes codigos http.
         }
      }
      xhr.open('GET','texto.txt',true);
      xhr.send(null);
   }else{
      //proveer una alternativa a ajax si no esta disponible.
   }
}

Espero verlos en la siguiente entrega.

Bueno, una nota primero en cuanto al titulo del articulo. La neta que no sabía ni como llamarlo, así que el titulo igual y no sea 100% descriptivo del contenido del post.

Habiendo dicho eso, prosigamos. Hace unos días me encontraba con un dilema. Has encontrado alguna vez con un formulario que quieres que muestre una página u otra dependiendo de si la acción fue realizada con éxito o no? Bueno, pues ese era mi dilema. Es muy sencillo solucionarlo, pero yo no quería tener que cambiar la estructura de toda la aplicación (un CMS).  Explico el problema para que veas un poco más de lo que hablo:

Tengo una pagina que se llama digamos “informacion.php”. Esta pagina se encarga de tres cosas, 1)agregar información nueva, 2)editar información existente y 3)borrar información existente. Para poder hacerlo toma el valor de una variable que se le pasa por GET, de modo que si la variable tiene como valor “aInfo”, la pagina muestra un formulario para poder agregar información nueva. El formulario tiene como action ‘informacion.php?modo=aInfo’, de modo que si al hacer la validación del formulario se determina que el formulario no es valido, se muestra un error y se vuelve a mostrar el formulario con los elementos que ya habían sido introducidos. Esto es por motivos de usabilidad ya que si el action del formulario fuera solo ‘informacion.php’, la aplicación no mostraría nuevamente el formulario y al presionar el enlace que nos lleva al formulario los datos de POST se perderían dejando sin posibilidad de introducir automáticamente los datos previamente introducidos por el usuario, obligando al usuario a escribir todo de nuevo en lugar de solo editar lo que estaba mal.

Algunos pueden argumentar que se puede usar GET para enviar los datos de POST al formulario nuevamente, pero eso representa más trabajo, a demás de no representar ninguna garantía debido a las limitaciones de GET e incluso podría ser perjudicial ya que el usuario pensaría que todo esta como él lo había dejado anteriormente cuando la realidad pudiera ser que un texto muy largo no haya sido incluido en su totalidad por GET, eso solo por mencionar uno de los muchos problemas que esta ’solución’ nos podría traer. Otro método igualmente ineficiente es pensar que como se implementará validación en tiempo real mediante javascript se puede confiar en que el problema será captado por javascript y no habrá necesidad de requerir al usuario que navegue manualmente al formulario nuevamente después de haberse encontrado un error en el formulario enviado.

Ninguna de estas dos opciones me convence por completo. Para que comprendas mejor de lo que hablo, muestro aquí una estructura de como está el código:

<?php

$ok = chacarFormulario(‘info’);
//checarFormulario regresa true o false dependiendo de si el formulario es o no valido
if(!$ok){
$error=”formulario invalido”;
//La variable error es capturada después por la aplicación y mostrada al usuario
}else{
//Guardo todo en la base de datos
}

?>

Si todo está bien no necesito mostrar el formulario ya que eso puede confundir al usuario a demás de que se ve feo. Si, por el contrario, hay algún error, necesito mostrar el formulario con los campos previamente llenados con la información que el usuario introdujo antes de enviar el formulario. Esta info se encuentra en $_POST, pero no entrare en esos detalles. La cosa es que para poder mostrar esa formulario action tiene que estar como ‘informacion.php?modo=aInfo’, pero eso me trae problemas si todo estuvo bien ya que para que no se muestre el formulario la variable modo no tiene que estar presente (o seteada como dicen algunos).

En otras palabras, si el formulario está correcto su action debería ser “informacion.php” y si no, el action debería ser “informacion.php?modo=aInfo”, pero claro, es imposible cambiar el action del formulario después de haberlo enviado y no hay forma de saber si el formulario es valido y así cambiar su action antes de enviarlo. Un dilema con una solución más fácil de lo que parece.

Mientras algunos empezarían a hacer raras convinaciones entre POST y GET y a usar variables para esto y para lo otro creando una pesadilla de código. Yo preferí sentarme a analizar el tema y llegue a la conclusión de que, si el problema era la existencia de la variable modo, bastaría con borrar esa variable y todo andaría bien.

Efectivamente, basta un simple unset para solucionar el problema:

<?php

$ok = chacarFormulario(‘info’);
//checarFormulario regresa true o false dependiendo de si el formulario es o no valido
if(!$ok){
$error=”formulario invalido”;
//La variable error es capturada después por la aplicación y mostrada al usuario
}else{

//Guardo todo en la base de datos
unset($_GET['modo']);
}

?>

De esta manera, para cuando la applicación llega a la parte que decide que parte mostrar (un formulario para gregar info, un listado de la información existente o una tabla con opciones de editar y borrar), lo cual hace dependiendo del valor de modo, se da cuenta que modo no existe, aún cuando en nuestra URL siga estando. Como para php modo ha sido eliminada y por consiguiente ya no existe, la aoplicación toma el valor por defecto. Para entenderlo mejor, te muestro la estructura de la parte de la app que decide que parte mostrar:

<?php

if($_GET && isset($_GET['modo'])){
switch($_GET['modo']){
case ‘aInfo’:
//muestra formulario para agregar info
break;
case ‘eInfo’:
//muestra opciones para editar info
break;
//mas de lo mismo case break, case break…
}
}else{
//si la variable $_GET['modo'] no existe entonces:
//muestra tabla con lista de info existente y opciones de borrar y eliminar.
}

?>

En caso de que todo haya estado bien, la vaiable modo es eliminada (para eso usamos unset()) por lo que cuando se llega a la parte de código apenas mostrada arriba, se ejecuta el código dentro del else{ } como si nuestro formulario hubiera sido enviado con action=”informacion.php”, cuando en realidad ha sido enviado con action=”informacion.php?modo=aInfo”.

Bueno, espero que se haya entendido por lo menos un poco. Creí que era un buen método para compartir con los visitantes de este blog. Espero sus comentarios.

Super Menú V0.002

July 10, 2009

He estado trabajando en un script para poder crear menús desplegables a partir de arrays. Ayer terminé lo que yo llamo la versión 0.002 de dicho script y quisiera compartirla con ustedes. Me gustaría aclarar que el propósito de compartirla no es distribuirla, por lo menos no todavía. El propósito en compartirla es más bien en cierta forma liberar el código y permitir que otros usuarios aprendan de él, pero también abrir un flujo de información a través del cual se estén haciendo sugerencias sobre lo que habría que mejorar, o cambiar en el script para lograr una mejora en el desempeño. También cabe aclarar que en proyectos abiertos al publico en general, como en sitios web, no es recomendable su uso ya que es un asesino de todo intento de accesibilidad. Esto por la simple razón de que Javascript es absolutamente necesario para poder crear el menú. Por tal motivo, recomiendo que si se usa, sea solo en ambientes que tenemos ‘controlados’ o en los que sabemos que los usuarios necesariamente tendrán javascript disponible y activado, por ejemplo, en una aplicación AIR, en el área administrativa de un sitio a la que sabemos que se accede con javascript disponible y activado, a apps locales que se usan con dispositivos que tienes javascript disponible y activado y situaciones similares.

La lógica detrás del script es muy sencilla. Si sigues regularmente el blog, habrás notado que me gusta hacer scripts sencillos y en cierta forma demostrar que los scripts no tiene por que alcanzar un nivel de complejidad que resulte confuso incluso para el autor de script. El script consiste, por el momento, de un constructor y un objeto. El constructor es una función llamada Desplegable. El trabajo de esta función es crear una serie de listas (elementos ul) anidadas tomando como base un array el cual se le pasa como primer parámetro. La función por el momento toma tres parámetros, dos de los cuales son opcionales. Como la función es un constructor y tratada como tal, la llamada no puede ser directa, hay que crear una instancia del constructor, por lo que una llamada a la función se vería más o menos así:

var miMenu = new Desplegable(estructura, direccion, contenedor);

En donde:

estructura: es el array sobre el cual se basa el menú.

direccion:por ahora toma solo un valor, ‘vertical’,  y sirve para especificar la dirección en la que el menú es creado.

contenedor: Es el id del elemento en el cual queremos que se cree nuestro menú.

de modo que si quiero crear un menú y que este sea agregado dentro de un div con id=’cabecera’, la llamada sería la siguiente:

var miMenu = new Desplegable(estructura, 'vertical', 'cabecera');

Notar que el último parámetro es el id y no una referencia al elemento en el cual queremos que se agregue el menú. Pasar una referencia del tipo:

var cabecera = document.getElementById('cabecera');
var miMenu = new Desplegable(estructura, direccion, cabecera);

Daría un resultado inesperado que podría causar destrozos en tu proyecto.

El único parámetro que por el momento es obligatorio es el primero, el cual pasa la estructura del array que queremos tomar como base para crear las listas anidadas. El segundo parámetro, si no se especifica, toma como por defecto el valor ‘vertical’. Recordar que este parámetro por ahora solo puede tomar el valor ‘vertical’. El tercer parámetro, si no se especifica, toma como valor por defecto el elemento body (etiqueta <body>). Es poco recomendable que no se especifique este parámetro ya que puede causar efectos inesperados como poner el menú hasta el final de la página, después incluso del pié de página.

El otro componente es un objeto llamado sM. Este se encarga de dos cosas:

1)Carga el CSS para el menú
2)Controla el plegado y desplegado de los sub-menús.

Este elemento es reciclado, es decir, ya lo tenía entre mis curiosidades. Cabe aclarar que este objeto no es de mi propia autoría, fue más bien creado en uno de los capítulos de DHTML utopia. El propósito al incluir este objeto fue demostrar que es sencillo crear nuestro propio objeto para controlar el plegado y desplegado de los menús de la forma en que queramos. Siempre y cuando nos aseguremos de que dicho objeto llame una función de Desplegable llamada aggCSS(), la cual agrega el CSS al menú.

La razón del porque aggCSS es llamada por el objeto que controla el plegado y desplegado de los sub-menús, es por que si en determinado momento quisiéramos crear nuestro propio objeto para controlar el plegado y desplegado de los menús interiores, sería útil llamar solo a la función Desplegable, analizar el código que genera y ver el árbol que genera. (El CSS nos impediría ver ese aábol.) Poder ver el árbol que genera es una gran ventaja ya que con simplemente ver la estructura de las listas anidadas te puedes dar una idea sobre como controlarlas.

Bueno, sin más, veamos como se hace una llamada real al menú. Como lo que me interesa es simplemente demostrar la creación del array, no tomaré en cuenta los dos últimos parámetros, dejándolos que tomen sus valores por defecto.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
 <title>Untitled</title>
 <script type="text/javascript" src="sM.js">

 </script>
</head>
<body>
<script type="text/javascript">

 estructura = [
 'acerca de->about.html',
 'bio->bio.html',
 [
 'proyectos',
 [
 'CSS',
 'menus->menuscss.html',
 'galerias->galeriascss.html',
 'layouts->layoutscss.html'
 ],
 [
 'javascript',
 'menus->menusjs.html',
 'galerias->galeriasjs.html',
 'animaciones->animacionesjs.html'
 ],
 'php->proyectosphp.html'
 ],
 'contacto->contacto.html',
 [
 'sitios amigos',
 'jseros->http://www.jseros.com/',
 'panino5001->http://www.disegnocentell.com.ar/',
 'I\'m Buzu->http://imbuzu.wordpress.com/'
 ]
 ]
 var miMenu = new Desplegable(estructura);
 sM.menuRef = miMenu;
 sM.init();
</script>

</body>
</html>

Algunas cosas a notar:

El array es un array multidimencional donde cada array anidado representa un ul anidado.

Para especifcar la url a la que apunta el elemento del menú, se pone “->” seguido directamente de la url a la que apunta dicho elemento.

notar sM.menuRef = miMenu. Aquí lo que estamos haciendo es pasandole a sM una referencia al menú para que sepa que aggCSS activar.

Notar la llamada a sM.init().

Creo que el código se explica por si solo. Puedes ver un ejemplo en vivo en:

http://www.p-freeweb.com/outside/javascript/scripts/supermenu/v0_002/sMV0_002Demo.html

También puedes ver el Javascript en:

http://www.p-freeweb.com/outside/javascript/scripts/supermenu/v0_002/sMv0_002.js

Nota: El menú aun no es ni versión 1, por lo que hay muchas cosas que se pueden mejorar aun, espero sus comentarios. El menú ha sido provado en FF 3.5. Tomando en cuenta que su uso no es recomendable para proyectos públicos, soporte para IE no es una prioridad.

Uf, esto va a ser como un record de errores que he aprendido a la mala. Han sido un montón, pero apenas pensé en iniciar esta serie. Ayer estaba muy tranquilo esperando que se llegara la hora de ir al trabajo. De repente me puse a pensar el cual sería la razón por la que una de mis amigas a quien invite a mi nuevo proyecto, el xismografo, no había escrito uno a pesar de haber contestado el mio sin demora. Era una de dos, o no lo había hecho, o no me había invitado a contestarlo. Ambas eran muy improbables. Decidí ir y revisar los últimos ximografos y me di cuenta que en efecto si había creado un xismografo. Entonces pensé, por que no me invito. Revise la lista de invitados y me di cuenta que sí había intentado invitarme. El problema es que todos los correos los había encerrado en un paréntesis. Por ejemplo, (uncorreo@unsitio.com). La parte de la app que envía los correos simplemente envió las invitaciones a las direcciones tal y como estaban, con paréntesis. Como es de esperarse, esas invitaciones no son validas, y aun que lo fueran, no son las correctas.
Me tocó modificar manualmente una de las tablas en mi base de dato, algo que nunca debe hacerse, pero que esta vez no tenía otra opción. Lo peor de todo es que esa posibilidad de error yo ya la había pensado, pero preferí confiar en que el usuario haría bien las cosas.

Modificar manualmente las bases de datos me trajo otro problema que aun estoy tratando de resolver. El problema no es grabe y es solo con uno de los registros anteriores. Podría decirse que puedo simplemente olvidarme del problema y que no me afectara realmente mucho, pero esa no es una opción cuando quieres que un proyecto tenga éxito.

Otro de los problemas en lo que ya había pensado, pero que también, tontamente, preferí confiar en el usuario, es que a la hora de presionar enter en un formulario, este se envía automáticamente. Por muchos tiempo estuve pensando en cancelar esa acción por que me podría causar resultados no deseados. Por ejemplo el envío de un formulario cuando aun no está completo. Me he dado cuenta que eso fue lo que le pasó a mi amiga.

Estos dos errores me parecieron poco probables que aparecieran, pero al final son los dos errores que presenta la primera persona que intenta crear un xismografo y distribuirlo. Por eso cuando piense en una posibilidad de error en algún sitio o app en la que estés trabajando. O cuando estés organizando cualquier cosa, no te dejes convencer por ti mismo pensando que es muy poco probable que pase. Mejor ponte a trabajar en prevenir y asegurar que efectivamente no pase. Generalmente soy un programador muy negativo. Siempre pensando que mis usuarios van a tratar de hackearme el sitio, que no van a saber ni como prender una compu, que no van a tener javascript activado, que no van a tener imágenes disponibles o css disponible. Trato de prevenir cualquier disfuncionalidad en mis proyectos, pero esta ves simplemente me dejé llevar por el conformismo y un poco de flojera y ahora he tenido que pagar el precio.

La web verde.

January 19, 2009

En los últimos años ha habido un chispazo en el movimiento ecologista. Cada vez más gente se une a este movimiento y empieza a cambiar el rumbo que llevamos en el tema ecológico. Hemos llegado al punto en que es necesario estar conscientes de que nuestros actos afecta el medio ambiente de una forma positiva o negativa y que hasta la fecha, el efecto ha sido mayormente negativo. Curiosamente, durante años hemos estado tratando de salvar el medio ambiente si darnos cuenta que realmente quienes están en peligro somos nosotros mismos, los seres humanos. El medio ambiente seguirá estando aun cuando nosotros nos hayamos extinguido y muy seguramente la tierra podrá regenerarse y curarse a sí misma cuando nosotros ya no estemos.

Durante mucho tiempo la raza humana fue la raza dominante de este planeta, pero ahora nos hemos convertido en una enfermedad. El planeta tierra está enfermo, y su enfermedad se llama humanidad. Sin embargo, es esa misma enfermedad la que podría empezar la recuperación de nuestro único hogar. Somos nosotros quienes tenemos la llave hacia un nuevo futuro que promete un ambiente más natural y menos contaminado.

Que tiene que ver esto con la web? no mucho al primer vistazo, pero cuando miras más adentro te das cuenta que hay mucha relación, no tanto con el problema como con la solución. Todo aquel que se dedique al desarrollo web tiene entre sus manos un poder enorme de comunicación el cual puede usar para bien o para mal. No se trata de comenzar a crear sitios web dedicados al cuidado de la naturaleza y la protección ambiental. La web verde es más acerca de enviar un mensaje de forma sutil, de desarrollar sitios que consuman menos recursos, sitios que requieran menos tiempo para el logro de objetivos de modo que el tiempo de conexión sea reducido, reduciendo así el consumo de energía. La web verde es sobre el diseño de logotipos e interfaces basados en los elementos naturales. Tomemos por ejemplo el logotipo de apple, una manzana. Independientemente de que la empresa haya sido “castigada” por Greenpeace*, el mensaje, muy probablemente inconsciente, de su logotipo es totalmente orgánico. Imagina una web en la que cada sitio envía un mensaje de este tipo al usuario. Esa sería sin duda una de las contribuciones más nobles de los desarrolladores web.

Es claro que sería necesario hacer una investigación profunda sobre el impacto que la parte visual de un sitio web tiene en el subconsciente del visitante, pero no hace falta ser un experto para darte cuenta que al entrar en un sitio web en el que la primer imagen que vez es un bosque verde con toda su biodiversidad expuesta tu forma de ver la vida cambia por un instante. Un instante parece no ser mucho, pero la vida está hecha de instantes y el cambio se hace con pequeños actos conectados el uno con el otro por un corto tiempo. Es decir, pequeños instantes de buenas acciones seguidos uno tras otros.

Como un ejercicio mental, ve google y concentrate en su favicon. Ahora piensa en lo que ese favicon te sugiere. Chances hay de que a tu mente vengan imágenes relacionadas con la naturaleza. Ese es el impacto que las imágenes tienen en nuestro subconsciente. Ahora imagina una web plagada de mensajes del mismo tipo.

Alguien me dijo en un foro que muchas veces mis mensajes son utopías. Me gusta pensar que soy un soñador y tener sueños como el da la web verde porque en toda la historia los únicos que fueron capaces de dejar huella y lograr algo fueron aquellos que tuvieron un sueño. Me gustaría que te unieras a mi sueño y que la siguiente vez que estés desarrollando un sitio web lo hagas de forma más consciente sobre el mensaje que envías con tus imágenes logotipos y demás y que pensaras en reducir el tiempo necesario para el logro de objetivos así como el consumo de recursos requeridos para lograr dichos objetivos. Usemos nuestro talento y conocimiento para un fin menos egoísta que mero hecho de ganarnos la vida y empecemos a pensar en preservar la vida. No solo la nuestra, sino la de los demás seres con quienes compartimos el planeta y la de las futuras generaciones.

*http://ecomundo.servital.es/apple-apoya-la-ecologia-%C2%BF-estrategia-o-compromiso/

Productividad web

January 18, 2009

Como mides el nivel de productividad de tus sitios web? Muchos piensan que entre más visitas más productividad, pero no se fijan en el tiempo que los usuarios pasa en su sitio web. Esto es importante porque el tiempo que un usuario pasa en nuestro sitio web nos da una idea de que tan interesante y útil les pareció. Muchos pueden decir que para eso basta con revisar el número de usuarios que regresan, es decir, no basarse solo en las visitas únicas sino ver y tomar en cuenta el numero de visitantes recurrentes; esto cierto, pero solo a medias. La verdad es que muchos de ellos solo regresan por que tu sitio web aparece continuamente en los buscadores. Eso no necesariamente quiere decir que estos usuarios encontraron tu contenido interesante, simplemente quiere decir que tienes un buen trabajo de SEO tras tu sitio. Muchos de esos usuarios quizá piensan “otra vez este sitio” y se vallan al instante.

Entonces, como medir realmente la productividad de tu sitio? Eso depende mucho del sitio que tienes. Por ejemplo, si tienes un sitio de comercio electrónico, bastará con ver las ganancias que te está generando. Sin embargo, la cosa se vuelve un poco más complicada con sitios más personales como los blogs. Una forma fácil de medir la productividad es mediante los suscriptores de tus feeds (RSS, atom, etc.) Debido a que los suscriptores demuestran interés en seguir leyendo tu contenido, puedes asegurarte que cada suscriptor es una muestra de la productividad de tu sitio. Otro método es el uso de comentarios, aun que claro tanto estos como los feeds tienen la desventaja de que son realmente muy pocos los usuarios que hacen uso de ellos. Tomemos por ejemplo este blog que lees ahora, a pesar de tener un numero de visitas mas o menos constante, la cantidad de comentarios es mínima en comparación con esas visitas. Lo que sucede es que los usuarios no están acostumbrados a comentar, pero si lo hicieran ayudarían mucho a mejorar la calidad de los blogs. Pero que hay de otros sitios como los portafolios en linea?

Ese es otro tema aparte. Para medir la productividad de tu portafolio necesitas tomar en cuenta no el número de visitas o de comentarios, sino la cantidad de clientes que obtienes a través de tu sitio web. En este tipo de sitios el posicionamiento en buscadores juega un papel muy importante, pero es más importante aun el medio de propaganda más antiguo, el que se hace de boca en boca. Por tal motivo me atrevo a decir que lo que realmente le da fuerza a tu portafolio en linea no es el portafolio en sí o el SEO, sino más bien la calidad de tu trabajo.

Este último punto es realmente el motor de todo buen sitio -Calidad- La calidad lo es todo. Un sitio que regularmente actualiza su contenido pero no solo para ocupar espacio sino para presentar contenidos de calidad, es un sitio que esta “condenado” al éxito.

La productividad web puede ser medida de distintas maneras, y todo depende del objetivo final que pretendes lograr con tu sitio web, pero sin duda, el número de visitas no lo es todo y un número alto no demuestra un buen nivel de productividad. Para lograr ser más efectivo se necesitan contenidos de calidad orientados a un mercado especifico de consumidores que son quienes le darán a tu sitio web el posicionamiento. Mi consejo es, antes de empezar a preocuparte demasiado por tu puesto en google, preocúpate por la calidad de tu contenido, pues es esté a fin de cuentas el que determinará el nivel de productividad de tu web.

Semantización Web

November 10, 2008

developmentNo se si el termino semantización web ha sido introducido anteriormente. De no ser así, me gustaría introducirlo en este articulo ya que la web ha llegado al punto en el que tanto estándares como semántica han alcanzado tal grado de importancia que sin estos dos componentes se podría desacelerar su crecimiento y evolución.

El termino semantización web se refiere al acto de impulsar la creación y redacción de sitios web que sean semánticamente correctos. Aun hoy en día, con todo el impulso y aceptación que se le ha dado a los estándares y sobre todo con el soporte que los navegadores lideres (exceptuando a IE) tienen sobre los estándares establecidos por la W3C, se ha logrado un crecimiento de las tecnologías web que no se había vivido anteriormente. Sin embargo, es triste ver que se ha relegado la semántica.

Si bien es un tema que empieza a sonar en los foros de habla hispana dedicados al desarrollo web, la semántica es aun un tema desconocido por muchos; un tema al que es necesario tratar en etapas tempranas del aprendizaje en el campo del desarrollo web. Muchos desarrolladores aun siguen preguntándose cuales son las ventajas de la llamada web semántica y hasta que punto es factible lograr que dicho concepto sea una realidad.

Para lograr la semantzación de la web es imperativo educar a las nuevas generaciones con un enfoque semántico. Pero como es eso posible si las generaciones actuales aun no han comprendido el mensaje? La respuesta está en los emprendedores que se han preocupado por impulsar el uso correcto del lenguaje base de todo sitio web; (X)HTML.

Tristemente aun hay quienes piensan que es buen idea evitar el uso de ids y clases, cuando en realidad son el complemento ideal para lograr la semantización web usando las tecnologías que tenemos al alcance en este momento.

Hay ciertas facetas del diseño web con las que un diseñador convencional no está familiarizado. Ya muchas veces se ha mencionado que el diseño web no es diseño gráfico, pero al parecer el mensaje no ha sonado lo suficientemente fuerte, ya que seguimos viendo en la web sitios que no son mas que un folleto en Internet. Podría mostrar algunos cuantos sitios como ejemplo, pero el objetivo no es criticar a nadie.

Diseñar una pagina web, mas que crear un diseño en si, es crear una experiencia. Cada vez que un diseñador web se sienta a diseñar lo hace pensando en algo mas que colores, figuras e imágenes. El piensa en un usuario o mejor dicho, en miles de usuarios, cada uno con diferentes necesidades, experiencias y expectativas. El diseño web es mas que diseñar un folleto.

Read the rest of this entry »

Español

In the beginning there was the web, and it’s only objective was to be a mean of communication and information distribution. The web was created with the only objective in mind of serving as a communication system that allowed people to share different kinds of information. For that reason, one of the most important characteristics of the web was to be accessible for everyone trying to use it regardless of technology, software, hardware, device, or platform used. Nowadays, however, the web has became more like a development environment for Rich Internet Applications. It’s not that the web has lost it’s objective of being the place where sharing information is easy and fast. It is just that the web has gotten the power of creating that information instead of just sharing it.

Read the rest of this entry »