Dagi3d v4

Accesibilidad con Ajax y Ruby On Rails

Estaba desarrollando una página web con Ruby On Rails donde necesariamente tenía que utilizar Ajax para mostrar el contenido de las distintas secciones ya que ésta tenía un reproductor de audio hecho en Flash, por lo que el hecho de recargar la página entera suponía cortar la música cada vez que se cambiase de sección (o eso o utilizar iframes, así que la cosa estaba clara)

El 'problema' que me encontré con la función 'link_to_remote' es que por defecto no añade ninguna url en el atributo 'href' del enlace, lo que no sólo supone un problema para aquellos usuarios que no tengan javascript, si no a la hora de que los buscadores indexen el contenido, ya que en teoría no siguen los enlaces dentro de código javascript.

Para solucionarlo, tan sólo tuve que escribir una sencilla función en un helper que añadiese automáticamente al atributo 'href' la misma url a la que se iba a hacer la petición con Ajax:
module PublicHelper

def ajax_link(label, url = {}, options = {})

options.merge!({:href => url_for(url)})

link_to_remote label,
{
:url => url,
:update => "section_content",
:loading => "Element.hide('section'); Element.show('loading'); ",
:complete => "Element.hide('loading');"
},
options
end
end
Así, al llamar a la función ajax_link("enlace", :controller => "foo", :action => "bar"), se genería el código html <a href="/foo/bar" onclick=".." />

El siguiente incoveniente era distinguir en el controlador cuándo se estaba haciendo una petición con Ajax o se estaba pidiendo directamente la url para devolver sólo el trozo html con el contenido, o bien la página entera. Por defecto, Prototype, la librería utilizada en Rails para usar Ajax, realiza la petición a través del método POST, así que para decidir si se debía utilizar el layout tan sólo había que tener en cuenta el tipo de petición que se estaba haciendo:
class FooController < ApplicationController

layout "foo"

def bar
render(:action => "foobar", :layout => request.get?)
end
end
Otra opción hubiese sido mandar un parámetro adicional en la petición y luego comprobar en el controlador si éste existia y así saber si se trataba de una petición con Ajax o no.

Igual sería interesante hacer esto en forma de plugin e incluir alguna funcionalidad más como añadir el código javascript a los enlaces de manera no intrusiva.
YoNoSoyTu
21/05/2007 02:28

En vez de request.get? puedes utilizar request.xhr? que te indica si la petición ha sido a través de XmlHTTPRequest (Ajax, para entendernos).

Y sobre el JavaScript no intrusivo existe UJS4Rails (http://www.ujs4rails.com/) que modifica muchos de los helpers de Rails para generar JavaScript no intrusivo.

dagi3d
21/05/2007 07:43

le echaré un vistazo al plugin que comentas a ver que tal. gracias por el apunte!

Damián Janowski
28/06/2007 13:34

Muy bueno Martín! Y como dicen, Unobstrusive Javascript for Rails es excelente. Tanto, que creo que debería incluirse en el core para fomentar buenas prácticas del uso de Ajax.

Deja un comentario
*: campos obligatorios. La dirección de correo no será publicada