Ruby

V parte: Ruby on Rails e Web 2.0di

Quali sono i punti di contatto tra il mondo Ruby on Rails e il Web 2.0? In questo articolo si farà una panoramica su software liberamente disponibile che si inserisce in questo contesto, su Ajax e su altre tecnologie, al fine di comprendere lo stato di RoR rispetto a Web 2.0.

Introduzione

L‘affermazione del Web 2.0 e le sue implicazioni tecnologiche e sociali sono ormai note a tutti noi. MokaByte se ne sta ampiamente occupando nelle sue pagine con una serie di articoli finalizzati a descriverne caratteristiche, soluzioni e ambito di azione. In questo articolo ci occuperemo di Web 2.0 in un‘ottica esclusivamente Ruby On Rails.
Il presente articolo è suddiviso logicamente in due sezioni:

  1. Alcuni esempi di implementazione di soluzioni Rails con una breve premessa relativa ai principi di Ajax.
  2. Qualche cenno ad alcuni prodotti, liberamente disponibili, vicini al mondo Web 2.0, realizzati in Rails, che possono essere interessanti punti di riferimento in materia.

Iniziamo dalla prima sezione.

Ajax. The Rails Way

Uno degli strumenti tecnologici che ha consentito l‘affermazione del Web 2.0 è, senza dubbio, legato Ajax. La disponibilità  di un front-end web, al tempo stesso accattivante ma soprattutto user-oriented, ha dato un notevole impulso all‘affermazione del "content user based site".
Innazitutto che cosa è Ajax e a che cosa serve? Facciamo una rapida descrizione.
Asynchronous JavaScript and XML, questo il significato dell‘acronimo, è una tecnica che permette di estendere le usuali (ormai del Web 1.0) funzionalità  nelle applicazioni web ricaricando frammenti della pagina HTML in maniera asincrona, consentendone aggiornamento o sostituzione senza che questa operazione coinvolga l‘intera pagina.

Figura 1. Il modello di classica applicazione web 1.0 e quello di applicazione web 2.0 [fonte Adaptive Path]

La presenza di un Ajax Engine nella versione 2.0 del Web consente una serie di operazioni al tempo stesso utili e accattivanti per l‘utente finale.
Ã? sufficiente aprire un account su GMail per averne un‘idea precisa di quale possa essere il risultato finale dell‘operazione.
Il risultato più intrigante, derivante dall‘utilizzo di Ajax, è una navigazione web "non bloccata" da operazioni di richiesta del browser, cosa questa particolarmente sgradevole al rapido e smaliziato utente Internet.

Figura 2 - Il modello sincrono confrontato con quello asincrono [fonte Adaptive Path]

Ma fin qui abbiamo motivato solo la A di Ajax, cioè Asynchronous.
Passiamo alla Ja = JavaScript. Al fine di gestire le richieste Ajax effettuate dalla pagina web si ricorre al JavaScript e in particolare a determinate librerie che mettono a disposizione una serie di funzionalità  (= funzioni) atte a raggiungere lo scopo.
In particolare noi utilizzeremo il framework Prototype per i nostri semplici esempi, una libreria che facilita la realizzazione di soluzioni dinamiche.
La X = XML nell‘acronimo è motivata più che altro da ragioni storiche poichà© non è detto che i dati passati su XMLHttpRequest siano in formato XML.
Aggiungiamo che la comunicazione tra il client e il server avviene ricorrendo a XMLHttpRequest, "...una API che può essere utilizzata in JavaScript, e in altri linguaggi di scripting per trasferire XML e altri formati testo verso e dal web server utilizzando HTTP, realizzando una comunicazione su di un canale indipendente tra la pagina web lato client e la componente server." [Wikipedia].
Ajax è chiaramente utilizzabile da qualsiasi ambiente lato server ma Rails nasce con un supporto built-in. Sviluppare applicazioni basate su RoR che ricorrono largamente ad Ajax è quindi piuttosto semplificato.
Facciamo qualche esempio in merito.
Apriamo Aptana, con il supporto RoR, e creiamo un progetto Rails di nome MokabyteAjax.
Tutti gli effetti Ajax e le operazioni DOM disponibili sono contenute nei .js presenti in public/javascript e creati in automatico alla generazione del progetto.
Per renderle disponibili all‘interno della componente view è sufficiente effettuare la seguente chiamata nella sezione della pagina .rhtml

<%= javascript_include_tag("prototype", "effects") %>

Possiamo immettere questa inclusione nella pagina template in modo tale che sia immediatamente disponibile per tutte le pagine che ci fanno riferimento.
In generale per fare una invocazione Ajax si ricorre ad un espressione simile alla seguente:

<%= link_to_remote("Do something", :update => ‘myajaxdiv‘,
:url => { :action => :actionname }) %>

dove il primo parametro risulta essere il testo del link, il secondo l‘elemento (id) della pagina che sarà  aggiornato e il terzo è la action che viene invocata.
Ovviamente nella view sarà  presente qualcosa del tipo

Something will be changed

che rappresenta la parte di front-end che sarà  "rimpiazzata" con il risultato dell‘operazione effettuata.
Facciamo un esempio molto banale che ci spieghi questa situazione.
Usando la view "generators" di Aptana creiamo un controller di nome "first" con due metodi "index" e "dothing". Ormai sappiamo che in automatico avremo disponibili sia il controller che i file di view. Aggiungiamo in app/views/layout il file application.rhtml con il seguente contenuto





<%= javascript_include_tag "prototype", "effects" %>
Mokabyte - Rails & Web 2.0



<%= @content_for_layout %>


In tal modo abbiamo disponibili i file .js della libreria Prototype per tutti i file dell‘applicazione (a meno che non provvediamo a disabilitare l‘utilizzo del template).
Il file appviewsfirstindex.rhtml sarà  la pagina all‘interno della quale è presente il "div" che sarà  aggiornato

<%= link_to_remote("Do something", :update => ‘myajaxdiv‘,:url => { :action => :dothing }) %>
Something will be changed

mentre il file appviewsfirstdothing.rhtml conterrà 



    Hello World from Ajax!

    (DateTime.now = <%= DateTime.now %>)

l‘oggetto dell‘aggiornamento della pagina index.rhtml

Per far funzionare il tutto è necessario disabilitare l‘utilizzo dei template per la seconda pagina.
Aggiungiamo al metodo ‘dothing‘ del first_controller.rb il seguente codice

render(:layout => false)   

A questo punto possiamo fare lo start del nostro server MokabyteAjaxServer ed invocare

http://localhost:3000/first/index.

Clicchiamo su "Do something" ed otteniamo qualcosa simile a quanto mostrato in figura 3.

Figura 3 - Risultato dell‘invocazione Ajax

Passiamo a un esempio un pò più evoluto. Si tratta di una lista di elementi che si aggiorna mediante Ajax, quindi senza ricaricare l‘intera pagina ma solo il frammento di interesse.
Introduciamo qualche elemento di interesse all‘esempio simulando la presenza di una base dati di elementi "da fare" aggiungendo nel model una classe todo.rb (appmodels odo.rb) con il seguente contenuto:

class Todo
 attr_reader :element
 attr_reader :postingTime
 DATABASE = []
 def initialize(element)
  @element = element
  @postingTime = Time.now
  DATABASE.unshift(self)
 end
      
 def self.find_recent
  DATABASE
 end
      
 # Todo
 new("Buying a Rails book")
 new("Taking a coffee")
end

Questa classe ci serve sia come contenitore sia come accessor, cioè per fornire l‘elenco dei nostri "todos" aggiornati.
Usando il generatore di codice di Rails creiamo un controller "list" con due metodi "index" e "add_element". Li completiamo con il seguente sorgente.

class ListController
 < ApplicationController
  def add_element
   todo = Todo.new(params[:element_body])
   render(:partial => "todo", :object => todo,:layout => false)
   end
  def index
  @todos = Todo.find_recent
  end
end

Il metodo index ci serve per recuperare la lista di elementi, mentre add_element per aggiungere il nuovo elemento (il parametro consente di recuperare i dati dal front end) e poi reindirizzare al front-end per aggiungere il nuovo elemento alla lista dei già  presenti.
Passiamo alla componente view. Questa è la componente che più risente dell‘impatto dovuto all‘adozione di un Ajax Engine.
Nel corso della trattazione ci imbatteremo nei template di Rails (in realtà  anche nel micro esempio precedente ci siamo passati molto vicini). Cosଠfacendo inizieremo ad introdurli per poi trattarli più ampiamente in articoli futuri.
Introduciamo l‘elemento principale di novità  nella view Ajax, e cioè l‘istruzione form_remote_tag().

    form_remote_tag(:url => { :action => "actionname" },
:update=> "div_to_update")

Questa, in luogo di form_tag() normalmente utilizzata per generare un form Rails, si occupa di serializzare gli elementi del form ed effettua l‘invio dei dati alla componente server tramite XMLHttpRequest. Ovviamente lato server non è richiesta alcuna modifica al codice per recepire i dati, rispetto ad un front end Web 1.0.
Nel nostro esempio ci spingeremo un pochino oltre implementando due Javascript callback (:loading, :complete) per il metodo form_remote_tag().
Questo il sorgente della pagina appviewslistindex.rhtml

<% content_for("page_scripts") do -%>
 function todo_added() {
  var todo = $(‘todos‘).firstChild;
  new Effect.Highlight(todo);
  Element.hide(‘busy‘);
  $(‘form-submit-button‘).disabled = false;
 }
 function todo_loading() {
  Element.show(‘busy‘);
  $(‘form-submit-button‘).disabled = true;
 }
<% end -%>

      <%= render(:partial => ‘todo‘, :collection => @todos) %>
<%= form_remote_tag(:url => { :action => "add_element" },
 :update   => "todos",
   :position => :top,
   :loading  => ‘todo_loading()‘,
 :complete => ‘todo_added()‘);
%>
<%= text_field_tag(‘element_body‘, ‘‘, :id => ‘element-body-field‘) %>
<%= submit_tag("Add Item", :id => ‘form-submit-button‘) %>
 
<%= end_form_tag %>

In testa abbiamo l‘istruzione content_for("page_scripts") dove sono implementate le funzioni di callback che sono inserite (come vedremo) nella pagina template con l‘istruzione <%= @content_for_page_scripts %> che provvede ad invocarle.
A seguire abbiamo la parte di visualizzazione della lista e il form con text e submit.
Nella pagina appviewslist\_todo.rhtml abbiamo invece gli elementi della lista da mandare a video, qualcosa tipo:


  •  


      <%= todo.postingTime.strftime("%H:%M:%S") %>:
      <%= todo.element %>
     


  • La pagina template appviewslayoutslist.rhtml conterrà  invece qualcosa del tipo:



     
     <%= javascript_include_tag("prototype", "effects") %>
     
     My To Do List
     <%= stylesheet_link_tag ‘mokabyte‘ %> 

    My List



     <%= @content_for_layout %>

    Rimandiamo a un prossimo articolo per tutti i dettagli relativi ai meccanismi della componente view ed in particolare dei template, ma la potenza dello strumento è ben evidente già  da questi semplici esempi. Siamo a questo punto pronti per invocare

    http://localhost:3000/list/index 

    e iniziare ad aggiungere elementi alla lista in modalità  2.0.

    Figura 4 - La lista che si aggiorna senza ricaricare la pagina

    A questo punto avremo tutti gli strumenti necessari per dare avvio alla realizzazione di una accattivante applicazione Rails Web 2.0 e per introdurre degli effetti veramente... "speciali".

    Qualche soluzione

    Passiamo ora a dare un‘occhiata ad alcuni prodotti realizzati in Rails che ben si inseriscono nell‘ambito Web2.0. Perchè lo facciamo? Il fatto che questi prodotti siano tutti realizzati utilizzando lo stesso framework, il fatto che questo framework abbia regole abbastanza vincolanti (basti pensare alla struttura in cartelle, allo switch tra ambiente di sviluppo, test, produzione) unito alla disponibilità  del codice sorgente rende di fatto facilmente utilizzabile non solo il prodotto ma anche solo parti di questo o rende semplificata l‘eventuale integrazione con altro software con le medesime componenti. Aggiungiamo anche che conoscere queste applicazioni ci abilita automaticamente a un‘utilizzo "as is" del software, cosa questa abbastanza frequente in caso di blog, wiki, ecc.
    Iniziamo da due prodotti per la gestione di blog, Typo (http://typosphere.org/) e Mephisto (http://www.mephistoblog.com). Sono entrambi dei prodotti WordPress-like realizzati in Rails. Facilissimi da installare con MySQL (almeno utilizzando WeBrick o Mongrel), meritano sicuramente una citazione (e una prova).

    Figura 5 - Il sito di Mephisto, basato su Mephisto

    Figura 6 - Un‘ installazione in locale di Typo

    Tra le altre cose la lista di alcuni dei blog che si poggiano su Typo (http://trac.typosphere.org/wiki/TypoPowered) è tutt‘altro che trascurabile...

    Nel mese di giugno, l‘ articolo sul Web 2.0 è stato dedicato all‘argomento wiki. Si è fatto riferimento a varie implementazioni, tra cui MediaWiki (PHP) e soprattutto XWiki (Java). Anche RoR dispone di una propria implementazione wiki. Si tratta di Instiki (http://www.instiki.org). Niente di particolare dal punto di vista funzionale. Si tratta di un ennesimo wiki-clone i cui punti di forza risultano essere la facilità  di installazione e di utilizzo.

    Andiamo oltre e arriviamo ad Ozimodo (http://ozimodo.rubyforge.org/), un tumblelog. Che cosa è un tumblelog? Wikipedia dice che "Un tumblelog è una variante del blog, che favorisce una forma abbreviata, arricchita da multimedialità , rispetto a quelli che sono i lunghi editoriali frequentemente associati ai blog. La forma di comunicazione comunemente usata include collegamenti, fotografie, citazioni, dialoghi di chat e video. A differenza dei blog questo formato è frequentemente usato dall‘autore per condividere creazioni, scoperte, esperienze senza la necessità  di commentarle".

    Figura 7 - Ozimodo al lavoro

    Veramente divertente metter su un blog (o come lo vogliamo chiamare) prendendo un video da YouTube, uno da GoogleVideo, caricando tue immagini personali, postando articolo di solo testo e cosଠvia. Uno spasso. Provatelo e non ve ne pentirete.
    Abbiamo citato qualche prodotto, tra quelli di cui abbiamo esperienza diretta, ma se volessimo andare alla ricerca di qualcos‘altro, sia esso Web 2.0 oppure Web "tradizionale" o applicazione standalone in Ruby possiamo dare un‘occhiata a RAA (Ruby Application Archive) (http://raa.ruby-lang.org/) e a RubyForge (http://rubyforge.org).
    Repository appostamente predisposti, sono punti di riferimento da tener sempre presenti nella ricerca. Prima di dedicarsi alla realizzazione from scratch, vale sempre la pena dare un‘occhiata.

    Conclusioni

    Abbiamo introdotto molti nuovi elementi da approfondire in ambito Rails/Ajax/Soluzioni Web2.0.
    Sicuramente Ruby e Rails risultano essere sufficientemente maturi per implementazioni di questo tipo. Prova ne sono la facilità  di realizzazione e le implementazioni disponibili.
    Aggiungerei anche che laddove, in contesti "non enterprise" non abbiamo necessità  di solide, ma costose applicazioni Java EE, Rails fornisce una valida soluzione Ajax-based, MVC e Object Oriented.

    Riferimenti

    [1] Dave Thomas, "Agile Software Development with Rails. The Pragmatic Programmer‘s Guide", Pragmatic Bookshelf, 2005
    http://www.pragmaticprogrammer.com

    [2] A. Brandolini, "Il punto sul Web 2.0", Mokabyte 113, gennaio 2007

    [3] S. Rossini, "Il Web 2.0 - II parte: Wiki", Mokabyte 118, Maggio 2007

    [4] S. Rossini - A. Rocca, "Il Web 2.0 - III parte: Ajax", Mokabyte 120, Luglio/Agosto 2007

    [5] Jesse James Garrett, "Ajax: A New Approach to Web Applications", Adaptive Path

    [4] Prototype - The Javascript framework
    http://www.prototypejs.org/

    [5] Instiki
    http://www.instiki.org

    [6] Ozimodo - tumbleloggin‘ on rails
    http://ozimodo.rubyforge.org/

    [7] Mephisto
    http://mephistoblog.com/

    [7] Typo
    http://typosphere.org/

    Condividi

    Pubblicato nel numero
    121 settembre 2007
    Laureato in Scienze Statistiche e particolarmente attento alle novità che lo circondano, dal 1998 lavora nel settore dell‘IT. Prevalentemente coinvolto in progetti legati a Java, da un paio d‘anni è interessato al mondo Open Source. Dopo aver accumulato una notevole esperienza presso vari clienti e con vari ruoli (da programmatore…
    Articoli nella stessa serie
    • Ruby
      I parte: introduzione al linguaggio
    • Ruby
      II parte: approfondiamo alcuni aspetti del linguaggio Ruby
    • Ruby
      III parte: Iniziamo a percorrere i binari di Rails
    • Ruby
      IV parte: Rails... non solo Web Services
    Ti potrebbe interessare anche