Mi modesta comparativa entre PURE y jQuery-tmpl

Hola! En mis dos últimos posts he estado hablando un poco de PURE, una herramienta para generar código HTML a partir de una plantilla y un objeto Json. Hace poco Microsoft ha presentado jquery-tmpl, su propuesta (todavía abierta y en fase de discusión) para realizar exactamente lo mismo: generar HTML a partir de plantillas y json. Más detalles los podeis encontrar en este post de Stephen Walher.

Ni soy (ni me considero) un experto ni en PURE ni en javascript, pero me he permitido realizar una pequeña comparativa entre PURE y la propuesta de microsoft para templates, para ver en que se parecen y en que se diferencian. Esta es mi comparativa, sin duda limitada por mi propia falta de conocimientos, pero que comparto con vosotros por si os parece de interés.

Al final del post encontraréis en enlace con el código fuente del proyecto, que en este caso es un lector de los feeds de geeks.ms, implementado en ASP.NET MVC. Básicamente hay dos vistas: una que se genera usando PURE y otra usando jquery-tmpl.

No voy a comentar nada de la parte “servidor” del proyecto, puesto que teneis el códgo fuente en el zip (y obviamente si alguien tiene alguna duda puede contactar conmigo). Lo que quiero comentar es el código de generación usando PURE y jquery-tmpl.

1. Generación usando PURE

La generación usando PURE no tiene mucho secreto. La plantilla está definida de la siguiente manera:

<div id="pure">
<h1>
</h1>
<h2>
</h2>
<span class="t1" id="generator"></span>
<p class="feed">
<a></a>
<br />
<span></span>
</p>
</div>

Toda la vista está generada usando PURE, puesto que el objeto JSON tiene toda la información necesaria.

El código para generar el template, también es sencillo:

var directive = {
'h1': 'Channel.Title',
'h2': 'Channel.Description',
'span#generator': 'Powered by: #{Channel.Generator}',
'p.feed': {
'feed<-Channel.Items': {
'a': 'feed.Title',
'a@href': 'feed.Link',
'span': function(ctx) {
return stripped = ctx.item.Description.replace(/(<([^>]+)>)/ig, "").
substring(0, 350) + "...";
}
}
}
};

$("#pure").render(data, directive);

Como casi siempre, se declara una directiva que controlará el renderizado y finalmente se llama al método render.

Si echamos un vistazo a la directiva vemos una cosa que no había mostrado en los posts anteriores, y es la posibilidad de llamar a métodos javascript: en este caso en el span se colocará el resultado que devuelva el método anónimo declarado en la directiva. Cuando se llama a una función javascript desde un bucle, PURE le pasa un objeto que tiene, entre otras, la propiedad item que es el objeto correspondiente a la iteración que se está renderizando. El método es sencillo: lo que hace es eliminar el código HTML del feed y truncarlo a 350 carácteres.

2. Generación usando jquery-tmpl

Antes que me olvide: jquery-tmpl requiere jquery 1.4.2. Con la versión 1.4.1 (que es la que usa el generador de proyectos de ASP.NET MVC 2 RC2) no funciona.

A diferencia de PURE, jquery-tmpl opta por tener los templates dentro de un tag <script> cuyo type sea text/html. Este no es un type correcto para un tag <script> por lo que es ignorado por el naveagador. Eso hace que, a diferencia de PURE, los elementos que forman el template no pertenecen al DOM del documento, puesto que son ignorados. Podréis ver la diferencia ejecutando el proyecto y consultando primero los datos con PURE y luego con jquery-tmpl. En el primer caso vereis como el template, a pesar de ser elementos vacíos, es visible ya que tienen estilos de colores y borders. Esto tampoco es que represente más problema: generalmente usando PURE el template está oculto inicialmente y se muestra cuando ha terminado la generación (p.ej. usando el método toggle() de jQuery). Yo no le hecho adrede, para que veáis el efecto.

La gran diferencia de jquery-tmpl respecto PURE, es que no existe el concepto de directiva: el propio template contiene la directiva embebida en su interior. Para ello Microsoft ha recurrido a una sintaxis que nos resulte lo más familiar posible. La definición del template queda así:

<script id="template" type="text/html">
<h1>{%= Channel.Title %}</h1>
<h2>{%= Channel.Description %}</h2>
<span class="t1" id="generator">{%= Channel.Generator %}</span>
{% for (var i=0, l = Channel.Items.length; i<l; i++) { %}
<p class="feed">
<a href="{%= Channel.Items[i].Link %}">
{%= Channel.Items[i].Title %}
</a>
<br />
<span>{%= strip(Channel.Items[i].Description) %}</span></p>
{% } %}
</script>

Se puede observar el uso de la sintaxis {% y %}, que recuerda a la <% y %> usada en páginas aspx para el código de servidor. De esta manera {%= expr %} se traduce por el valor de expr donde expr se evalúa en el contexto del objeto json. Así {%= Channel.Description %} se traduce por el valor de la propiedad Description, de la propiedad Channel del objeto json.

También vemos el uso de {% y %} para iterar: Las etiquetas {% y %} nos permiten colocar código javasacript en nuestro template, en este caso un bucle for para iterar sobre todos los elementos de la colección Channel.Items.

Finalmente fijaos en la llamada a la función strip dentro del <span>. La función strip sirve para eliminar el código html del feed y truncarlo a 350 carácteres, y está definida dentro de un tag <script> en la propia página:

function strip(str) {
return str.replace(/(<([^>]+)>)/ig, "").substring(0, 350) + "...";
}

Hemos visto como definimos el template… y como lo aplicamos? Pues muy fácil, primeramente necesitamos el contenedor (o sea, el sitio donde se va a colocar el código HTML generado):

<div id="mstemplate">
</div>

Y una vez tenemos los datos en json, seleccionamos el template (usando un selector de jquery) y llamamos a su método render, pasándole los datos json y finalmente llamamos a appendTo para que el resultado se coloque dentro del contenedor que indiquemos.

$("#template").render(data).appendTo("#mstemplate");

3. Algunas conclusiones mías

La principal diferencia es que en PURE el template es un conjunto de objetos DOM conocidos por el navegador, mientras que en jquery-tmpl, el template es ignorado por el navegador ya que está dentro de un <script> cuyo tipo es “text/html”. En el apartado de discusiones del documento de propuesta de microsoft, se comenta el hecho que los templates no son objetos DOM para evitar efectos colaterales. Esto es cierto si se adopta la filosofía de que el template tenga la directiva embebida. Si mi template tiene algo como:

<img src="{%= ImageUrl %}" />

Si el template fuese un objeto DOM reconocido por el navegador, éste intentaría cargar la imagen “{%= ImagenUrl %}”, la primera vez. Esto es algo que NO podemos evitar haciendo que el template sea invisible. Es por ello que Microsoft opta por poner el template dentro de un tag <script> cuyo type sea “text/html” y de esta manera sea ignorado por el navegador.

En PURE no hay este problema, ya que la directiva está separada y además PURE puede crear atributos que no estén en el template si la directiva así lo indica. De este modo, el template para el caso anterior en PURE queda como:

<img />

Y la directiva asociada es la que crea el tag src dentro del tag <img>:

var directive = { 'img@src' : 'ImageUrl'};

De este modo el template puede ser un objeto DOM sin efectos colaterales.

No sé si el hecho de que los templates sean objetos DOM reales o no, tiene mucha importancia. Lo que si me hizo notar @tchvil es que con PURE la página sigue siendo xhtml, mientras que con jquery-tmpl no, por el uso de la sintaxis {% … %} y que eso puede tener su importancia en según que casos.

4. ¿Es necesario un estándard de templates en jquery?

Si no he entendido mal, la intención de microsoft con jquery-tmpl (que recuerdo está en fase de definición) es que se convierta en el método estándard de templates en jquery. Yo no se si es necesario que haya un mecanismo estándard de templates en jquery. Pienso que es bueno que el core sea lo más pequeño posible y que se use el mecanismo de plugins para ir enchufando las distintas funcionalidades. De este modo cualquiera podrá usar el mecanismo de templates que más le convenga en cada momento. Aunque en el documento se justifica la inclusión de un mecanismo estándard de templates en el core de jquery para que así si alguien quiere desarrollar un plug-in para jquery pueda usar templates sabiendo que estarán soportados…

Lo que sí me ha parecido ir leyendo en algunos posts, es que Microsoft va a ir abandonando su Ajax Library (me refiero a la parte de cliente, no a los controles ajax de asp.net) para ir centrando esfuerzos en jquery. Si realmente es así me parece una decisión excelente y que apoyo plenamente.

Como comenté al principio aquí tenéis el código del proyecto para que hagáis con él lo que queráis! (Está en mi skydrive).

Un saludo!

4 comentarios sobre “Mi modesta comparativa entre PURE y jQuery-tmpl”

  1. Holas! Un tema muy interesante…

    Está claro que la limpieza en la definición del marcado en PURE, y su cumplimiento con los estándares (xhtml) son grandes ventajas.

    Sin embargo, al menos para para mí, sería más sencillo adaptarme a la sintaxis de jquery-tmpl debido a que utiliza un código idéntico al utilizado en las vistas (mvc), aunque con las particularidades del lado cliente, claro.

    Fíjate que sin tener ni idea de ninguno de las dos tecnologías (es así, de hecho :-)), sería perfectamente capaz de retocar el segundo ejemplo (jquery-tmpl), mientras que para tocar el primero (PURE) tendría que acudir a la documentación que, aunque no sea complejo, ya es menos cómodo.

    Está claro que la propuesta de MS rompería actualmente la validación xhtml, pero bueno, todavía se trata de una propuesta, y seguro evolucionará hacia alguna solución menos dolorosa desde ese punto de vista.

    En fin, se trata de un tema realmente interesante, que habrá que ver por dónde sale.

    Saludos.

  2. Excelente Artículo,
    Me parece más limpio y con más concepción de Template PURE, al separar la plantilla del código que hace el binding del lado del cliente.
    Por otro lado es mucho mas instuitivo Jquery-tmpl, como dice Jose, se podría hacer retoques al código sin tener mucha idea. Lo que si, por el articulo veo que hay más funciones y formas en jquery-tmpl para evitar confusiones en el DOM, es decir , “arreglos” para que pueda funcionar, no se si me equivoco.

  3. @José M, Gonzalo
    Es evidente que la sintaxis que ha elegido Microsoft para jquery-tmpl es mucho más intuitiva para una gran mayoría. Como decís, alguien sin mucha idea sería capaz de retocar el código, mientras que retocar las directivas de PURE es sin duda un poco más complejo.

    @Gonzalo,
    No termino de entender lo que comentas de “evitar confusiones en el DOM”. Si te refieres a que es más fácil “seleccionar” qué elemento del template obtiene qué datos, seguramente tengas razón…
    En jquery-tmpl puedes tener un template:

    {%= p1 %}

    {%= p2 %}

    Y queda claro donde va el valor de p1 y p2.
    Por otro lado en PURE no tengo claro como se puede realizar esto (asignar dos propiedades a dos tags

    que no tienen id ni clase). Para poder indicar en cual de los dos

    s va cada propiedad debo poder seleccionarlas de forma distinta en la directiva, por lo que tengo que asignarles un id o una clase:

    y ahora si que en la directiva ya puedo poner
    {“p.c1”: “p1”}, {“p.c2” : “p2”}

    De todos modos no saber como hacer esto puede ser alguna limitación mía: no soy un experto en los selectores de jquery tampoco (ya veo que tengo que mirarmelos bien :p), por lo que si hay algun selector que permita seleccionar el primer

    y otro que permita seleccionar el segundo

    entonces estaríamos en las mismas… 🙂

    Gracias a los dos por vuestros comentarios!!! Coincido con vosotros en que es un tema realmente interesante!! 😉

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *