AJAX y navegadores sin Javascript

Una de las características del Diccionario Malacitano es su interfaz basada en Ajax. La consultas de las distintas letras del diccionario se hacen invocando un código Javascript que actualiza el contenido de una parte del DOM de la página (más exactamente el <div id="contenido"> usando una plantilla RJS, como ya vimos aquí)

<p>La navegación básica en nuestra aplicación depende, por tanto, de que el usuario tenga habilitado Javascript (la J de <span class="caps">AJAX</span>) en su navegador.  ¿Qué ocurre si un usuario llega a nuestra a web con Javascript inhabilitado, o, peor aún, con un navegador sin Javascript?</p>


<p>Pues simplemente verá que los enlaces del índice apuntan a URLs un tanto sospechosas (<code>http://diccionariomalacitano.sobrerailes.com/#</code>).  Y no sólo eso, sino que además, si hace clic en una letra no ocurre nada.    En conclusión, gracias al uso de <span class="caps">AJAX</span> hemos conseguido unos atractivos efectos visuales pero a cambio hemos convertido nuestra aplicación en un <strong>desastre de usabilidad</strong> que necesita arreglo.</p>

        <!--more-->

        <p>Puede ser que alguien piense que no va a recibir apenas visitas de usuarios con Javascript desactivado o con navegadores antiguos y que no le merece la pena dedicar ningún esfuerzo a este asunto, que sólo tiene que ver con dar soporte a usuarios con discapacidad.  Grave error.</p>


<p>En primer lugar, no hay forma de enlazar desde fuera de la aplicación a nuestro contenido.  Por ejemplo, no puedo hacer un enlace a la página de la letra &#8220;f&#8221;, por ejemplo, para guardarlo en mis <em>bookmarks</em> o para hacer un link desde otra web.</p>


<p>En segundo lugar, el usuario más importante de todos, Google, no seguirá nuestros enlaces y por tanto no indexará el contenido de nuestra web.</p>


<p>Sin la posibilidad de recibir enlaces externos y con Google quedándose a la puerta de la web&#8230; ¿cuánto tráfico podrá llegar a generar nuestra página?</p>


<p>Afortunadamente, el arreglo es trivial.</p>


<h3>Arreglando la plantilla</h3>


<p>Nuestro código original era este:</p>
1
2
3
4
<%= link_to_remote letra,
        :url => { :action => :busca, :id => letra },
    :loading => "Element.show('indicador')",
    :complete => "Element.hide('indicador')"

Para generar una URL correcta en el enlace que hemos creado con el helper, debemos aprovechar más opciones de link_to_remote:

1
2
3
4
5
6
7
8
9
10
11
<%= link_to_remote(letra, 
        {
                :url => { :action => :busca, :id => letra },
            :loading => "Element.show('indicador')",
            :complete => "Element.hide('indicador')" 
        },
        { 
                :href => url_for (:controller => "diccionario",
                                                  :action => "busca",
                                                  :id => letra) 
        })

Podemos añadir un hash con las opciones de la URL a generar en el enlace. En este caso, hemos usado otro helper más, url_for, para enlazar a la acción busca del controlador diccionario. Por tanto, de esta manera los enlaces del índice apuntarán, como debe ser, a http://diccionariomalacitano.sobrerailes.com/busca/x), y esta será la URL que seguirá un navegador que no tenga Javascript activado.

Arreglando el controlador

Sin embargo, nuestro controlador responde usando RJS, lo cual claramente no es lo deseado: un navegador sin Javascript no espera las respuestas que genera una plantilla RJS, pensada para ser invocada desde AJAX.

Para distinguir si se invoca esta acción desde un enlace HTML tradicional o desde la función Javascript generada, basta con hacer lo siguiente:

1
2
3
4
5
6
7
8
def busca
   @entradas = Entrada.find_all_by_inicial(params[:id], :order => "voz")
  
  respond_to do |tipo|
    tipo.html {render :partial => "entrada", :layout => "diccionario", :locals => { :entradas => @entradas } }
    tipo.js   {}
  end
 end

Simplemente, el método respond_to nos indica si debemos responder HTML estandard o bien responder a una petició Javascript (en cuyo caso no hacemos nada ya que por defecto se usará la vista RJS que ya tenemos creada)

blog comments powered by Disqus