May 28th, 2008
Validación de HTML y dojo
Antes que nada, necesito agrandar mi lista de software favorito :), Enrique y Alejandro fueron tan amables de hacerme ver que esta extremadamente corta en cuestión de herramientas importantes, espero hacerlo mañana !
Y entrando en tema, la validación de HTML es algo que muchos valoramos !! (valga la rebusnancia cacofónica), en el principio de los días WWW-eros se creó un lenguaje para crear la forma de comunicación más importante que tenemos actualmente, la web; este lenguaje implementó los elementos necesarios para hacer tareas tales como insertar texto, títulos, columnas, imágenes, y todo tipo de material multimedia.
Ese lenguaje era bastante burdo, pero fué mejorando relativamente rápido, uno de los grandes pasos fué la inclusión de las hojas de estilo (CSS, Cascade style sheets) para separar vista de presentación, recuerdo la famosa frase de que “el HTML violaba la definición de un documento”, o algo así.
Se empezaron a crear definiciones cada vez mas formales y robustas de lo que ahora conocemos con HTML y el nuevo y mejor XHTML, no solo tenemos definiciones muy formales de como representar los datos de una página y su estilo (HTML y CSS respectivamente), sino que ahora tenemos incluso un gran estandar de comunicacion e interacción hacia lo que se conoce como DOM (Document Object Model) a través de otro lenguaje más, el JavaScript (que dijeron ?? ActionScript ?? pues no, pero se parecen y son como hermanos).
Pero llegó la era 2.0 de la Web !!, ahora no nos conformamos con páginas estáticas, ni siquiera con páginas dinámicas en contenido, ahora queremos que las “aplicaciones web” sean amigables, colaborativas, mashupeables (sin albur), etc.
Que pasa, que o usamos flash para hacer aplicaciones contenidas en un archivo SWF (con herramientas propietarias, y todo lo malo que implica eso), o usar JavaScript y todo su poder para agregarle a las paginitas algo de color, belleza, y movimiento, sin dejar atras usabilidad, rapidez y flexibilidad.
Creo que es la introducción más larga a un blogaso que he escrito en mi vida.
Bueno, siguiendo, obviamente en cuanto apareció la dichosa nueva era del Web 2.0, aparecieron muchas herramientas (bibliotecas) para facilitar el trabajo de crear las páginas bajo la nueva tendencia.
Uno de los más populares, probablemente no el más, es Dojo, que incluye todo lo necesario para hacer AJAX, widgets, layouts, effects, 😛 ya me pasé con el spanglish.
El asunto con Dojo es que graciosamente deciden crearse todo un sistema de creación de efectos y herramientas visuales y funcionales que depende nada más ni nada menos que de la inclusión de un atributo a los tags de HTML, en concreto “dojoType”. Es una forma muy sencilla de crear toda clase de cosas de manera sencilla (el parser de dojo hace el trabajo de localizar los elementos que debe transformar) pero automáticamente invalida no solo XHTML, sino tambien cualquier definición oficial de HTML.
Pero ese no es el fin del mundo, es totalmente posible crear páginas validas (en cuanto a [X]HTML) pero implica un pequeño detalle, hay que programar la creación de todos los elementos !!, ahhhhh, ahora resulta que si tengo que saber JavaScript para hacer una página correcta.
En realidad no es demasiado tedioso hacer la creación de elementos con programación, sobre todo si nos importa mucho crear páginas que sean válidas bajo los estándares de web, pero es un hecho que es más latoso que simplemente irte por la vía rápida y crear todo en el sencillo HTML.
Veamos un ejemplo sencillo, vamos a crear una página con una sola sección que va a contener una tabla tipo “Grid” con todas las bondades que tiene, obviamente le vamos a meter datos, los datos vendrán de un archivo que devuelve json (al estilo django, de ahí lo saqué) que puede representar de manera sencilla la salida de cualquier consulta a una base de datos a través de django (cualquier otro método requiere modificaciones muy sencillas).
Si tienes git, puedes correr “git clone http://garaged.homeip.net/samples/dojosample.git” para bajar el ejemplo, hay que sustituir el link en “my_media/dojo” por un directorio que tenga dojo descomprimido (debe contener dojo,dijit, dojox, util), o puedes bajar el zip.
Usando los atributos de dojo (extrañosa a HTML) podemos simplemente crear un layout directamente en el body:
<body class="tundra">
<div dojoType="dijit.layout.BorderContainer" design="headline"
style="border: 2px solid black; width: 90%; height: 90%; padding: 10px; margin: auto auto auto auto; vertical-align: center;" >
<div dojoType="dijit.layout.ContentPane" region="center" style="width: 100%; height: 100%">
<div id="grid" dojoType="dojox.Grid" structure="layout" title="Tab 2"></div>
</div>
</div>
</body>
Dentro del contenedor ya estamos definiendo un “Grid”, que va a tomar su formato de celdas de un arreglo que se llama “layout”, eso lo definimos en un archivo con JavaScript que llamamos en los headers (grid.js).
var layout = [ {
cells: [[
{name: 'Id'}, {name: 'From'}, {name: 'To'}, {name: 'Spam?'}, {name: 'Score'}
]]
}];
Con ello tenemos ya definido un esquema en el que existe un contenedor principal, que tiene un “hijo” que aloja un “grid” el cual tiene 5 columnas, los datos se cargan con el resto del JavaScript en “grid.js”.
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dojox.grid.Grid");
dojo.require("dojo.parser"); // scan page for widgets and instantiate them
var data_json = new Array();
function getData(url){
dojo.xhrGet({
url: url,
handleAs: "json",
load: makeGrid // smart function call !
});
}
dojo.addOnLoad(function(){
getData("./data.json");
});
function makeGrid(data, ioArgs) {
var i;
for (i=0 ; i<data.length-1; i++ ) {
data_json[i] = [
data[i].pk,
data[i].fields.from_add,
data[i].fields.to_add,
data[i].fields.spam,
data[i].fields.score
]
}
var Model = new dojox.grid.data.Objects(null, data_json);
dijit.byId("grid").setModel(Model);
}
que entre otras cosas hace lo necesario para que se cargue dojo, y se haga el "parseo" del HTML para cambiar todos los tags que tengan un "dojoType" por el correspondiente "widget". Luego por medio de "dojo.addOnLoad" desencadenamos el proceso que trae el archivo data.json y con un tratamiento nada cesudo se convierte en datos que son procesados para ser incluidos en el "Grid".
En el archivo index.html completo puedes ver que tambien se cargan varios archivos CSS que son indispensables para general la tabla en el formato correcto, y muchoas otras monadas que se hacen por debajo del agua automáticamente.
Este ejemplo fué hecho rompiendo el estandar de HTML, insertamos tags que tienen el atributo "dojoType", el cual no es aceptado, y por tanto la página no es válida segun el estandar.
Ahora veamos un diff de la página creando todo "programaticamente" con JavaScript.
--- index.html 2008-05-29 17:26:00.000000000 -0500
+++ index-programatic.html 2008-05-29 17:25:31.000000000 -0500
@@ -9,23 +9,20 @@
@import "./my_media/dojo/dojo/resources/dojo.css";
@import "./my_media/dojo/dijit/themes/tundra/tundra.css";
html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
+ #grid { width: 100%; height: 100%; }
+ #container { border: 2px solid black; width: 90%; height: 90%; margin: auto auto auto auto; vertical-align: center;}
</style>
<script type="text/javascript" src="./my_media/dojo/dojo/dojo.js"
- djConfig="parseOnLoad: true" ></script>
- <script type="text/javascript" src="./my_media/js/grid.js"></script>
+ >
+ </script>
+ <script type="text/javascript" src="./my_media/js/grid-programatic.js"></script>
</head>
-<body class="tundra">
+<body>
-<div dojoType="dijit.layout.BorderContainer" design="headline"
- style="border: 2px solid black; width: 90%; height: 90%; padding: 10px; margin: auto auto auto auto; vertical-align: center;" >
- <div dojoType="dijit.layout.ContentPane" region="center" style="width: 100%; height: 100%">
- <div id="grid" dojoType="dojox.Grid" structure="layout" title="Tab 2"></div>
- </div>
-</div>
</body>
</html>
Notablemente ya no necesitamos el "parseOnLoad" y además el body quedó vacío!
Es porque vamos a hacer todo con JavaScript (mmm, sin palabras). Veamos el diff para grid.js
--- grid.js 2008-05-29 16:55:02.000000000 -0500
+++ grid-programatic.js 2008-05-29 16:54:15.000000000 -0500
@@ -1,7 +1,5 @@
dojo.require("dijit.layout.BorderContainer");
-dojo.require("dijit.layout.ContentPane");
dojo.require("dojox.grid.Grid");
-dojo.require("dojo.parser"); // scan page for widgets and instantiate them
var data_json = new Array();
function getData(url){
@@ -17,6 +15,11 @@
});
function makeGrid(data, ioArgs) {
+ var layout = [ {
+cells: [[
+ {name: 'Id'}, {name: 'From'}, {name: 'To'}, {name: 'Spam?'}, {name: 'Score'}
+ ]]
+ }];
var i;
for (i=0 ; i<data.length-1; i++ ) {
data_json[i] = [
@@ -27,13 +30,23 @@
data[i].fields.score
]
}
- var Model = new dojox.grid.data.Objects(null, data_json);
- dijit.byId("grid").setModel(Model);
+ var cont = new dijit.layout.BorderContainer(
+ { "design": "headline",
+ "id": "container"
+ }
+ );
+ document.body.appendChild(cont.domNode);
+ var newGrid = new dojox.Grid(
+ { "id": "grid",
+ "structure": layout,
+ "region": "center"
+ }
+ );
+ dijit.byId("container").addChild(newGrid);
+ Model = new dojox.grid.data.Table(null, data_json);
+ dijit.byId('grid').setModel(Model);
+ newGrid.render();
+
}
-var layout = [ {
-cells: [[
- {name: 'Id'}, {name: 'From'}, {name: 'To'}, {name: 'Spam?'}, {name: 'Score'}
- ]]
-}];
Ahora el arreglo "layout" que define las columnas del "Grid" está en la funcion que lo hace, ya no necesitamos que sea accesible desde fuera de esta función.
Secuencialmente en la función "makeGrid" creamos un contenedor (ya no se hace en HTML), y le insertamos un hijo que va a ser el Grid, luego alimentamos ese Grid con los datos que traemos por medio de AJAX (por si no se notó) y finalmente llamamos al "render" de la tabla.
Con estos cambios, que aunque no son demasiado complicados, si requieren de más cesos, principalmente porque NO HAY DOCUMENTACIÓN de como hacer BorderContainer programacionalmente todavía en dojo, así que uno se tiene que chutar amablemente el código en JavaScript y entenderlo lo suficiente como para aprender a hacer lo que hace el parseador de los BorderContainer en dojo.
Con esto doy por terminado el día, y como nota hay que poner un
en el body para que valide, aparentemente un body vacío no es válido !! aún así no se logra validar 100% !! jajajaja
Cabe mencionar que herramientas como scriptaculous y meteora hacen todo programáticamente, por lo que en una de esas es preferible usarlas, pero a mi me gusta dojo 😛