Cambiando de prototype a YUI con Grails

Días antes del último despliegue de Jobsket, estuve dándole vueltas a un problemilla con Grails 1.0.5 y los taglibs estándar para usar Ajax, por defecto Grails utiliza la librería javascript prototype para abstraerse de los distintos navegadores. Para que funcionen los taglibs remoteFunction, remoteLink y formRemote debemos utilizar <g:javascript library="prototype" /> para que cargue el .js de la librería, la cuestión es que estamos utilizando algunos componentes de YahooUI(y de GrailsUI) y para aligerar el peso de las peticiones, queríamos quitar todas nuestras dependencias con prototype.

Después de refactorizar nuestro código javascript dependiente de prototype, donde hemos encontrado que hay efectos muy sencillos de implementar gracias a script.aculo.us que no lo son tanto con YahooUI(la librería Effects Widget nos ha ayudado en esta transición), nos encontramos que teniendo en el layout la declaración de qué librería deben usar para renderizar esos taglibs de Ajax, en las vistas seguía haciéndolo con el código para prototype, por lo que daba errores javascript. Para que en cada vista renderizara usando el código de YUI, debemos poner la declaración <g:javascript library="yui" /> en cada vista, yendo con cuidado en el orden de las dependencias, ya que si hay un <g:javascript library="yui"/> en el layout y en la vista sólo se renderizará el segundo, por lo que habría que hacer algo así:

En el layout:
<g:javascript library="yui" />
<g:layoutHead />
<yui:javascript dir="..." file="..." />
<yui:javascript dir="..." file="..." />
<g:javascript library="application" />

En la vista:
<g:javascript library="yui" />
<yui:javascript dir="..." file="..." />

En este orden se renderizarán primero las dependencias básicas de la librería YUI, luego las que necesitemos para usar componentes, y por último nuestro propio código que puede depender de algún componente.

En fin, no es una solución DRY, pero funciona para los pocos casos en los que lo necesitamos.

Otra de las soluciones de las que nos hemos ayudado, como muchos seguro que imaginaréis ;), es implementar una función $(), que aunque no nos dé las bondades de las extensiones DOM de prototype, nos ha ayudado a tener que cambiar mucho menos código:

function $(id){ return YAHOO.util.Dom.get(id)}