homeASCIIcasts

7: Tutto sui layout  (view original Railscast)

Other translations: En Es

Written by Andrea Salicetti

Questo episodio è tutto sui layout. I layout sono file di viste che definiscono il codice che fa da contorno ad un template. E’ la cosiddetta cornice applicativa. Possono essere condivisi fra le varie action e i vari controller.

Layout di applicazione

Il template qui sotto elenca tutti i progetti.

  <h2>Projects</h2>
  <ul>
  <% for project in @projects %>
      <li><%= project.name %></li>
  <% end %>
  </ul>
  

Questo codice genera una pagina web piuttosto semplice:

Basic page without layout

Se volessimo, aggiungere, per dire, un’intestazione, un logo e una barra di navigazione al sito ed avere tutti questi elementi visibili in ogni pagina, allora potremmo sfruttare un layout. I file di layout sono posizionati nella cartella /app/view/layouts di un’applicazione Rails. Per definirne uno, basta creare un nuovo file denominato application.rhtml[1] nella cartella dei layout. Ciò renderà disponibile un layout globale per tutti i controller e tutte le action. Il file di layout applicativo sarà qualcosa del genere:

  <h1>Application Layout!</h1>
  <%= yield %>
  

La riga significativa del codice sopra è la seconda. La parola chiave yield indica al layout dove piazzare il contenuto del template che userà il layout. Ora, se riguardiamo la pagina di prima, possiamo vedere che il layout è stato applicato.

Basic page with layout

Essendo un layout globale, sarà applicato ad ogni action di ogni controller dell’applicazione. Il più delle volte questo sarà sufficiente, ma che cosa succederebbe se avessimo bisogno di layout differenti per parti distinte della nostra applicazione?

Layout speficici del controller

Un layout può essere reso specifico di un solo controller, semplicemente nominandolo, anzichè application.rhtml, con lo stesso nome del controller di riferimento (più, ovviamente, l’estensione .rhtml). Così, per creare un layout che sarà usato da tutte le action del controller dei Projects, creeremo un file nella cartella layouts, denominato projects.rhtml[2]. Ciò per Rails significa che il layout andrà applicato solo per le action del controller dei progetti.

  <h1>Project Layout!</h1>
  <%= yield %>
  
Basic page with controller-specific layout

E se ora volessimo condividere un layout fra diversi controller, non solamente uno, perchè ad esempio vogliamo un layout per amministratori dell’applicazione? Rails ci permette di utilizzare il comando layout per definire il nome del layout che deve essere utilizzato con un controller.

  class ProjectsController < ApplicationController
    layout "admin" 

    def index
      @projects = Project.find(:all)
    end
  end
  

Un layout indicato con il comando layout ha la precedenza rispetto a qualsiasi layout specifico del controller o applicativo.

Layout dinamici

I layout possono anche essere usati dinamicamente. Per esempio, vorremmo poter applicare il layout admin solo quando un utente è autenticato nella nostra applicazione. Ciò può essere fatto passando un simbolo, piuttosto che un valore costante, al comando layout e creando un metodo, con lo stesso nome del simbolo, che calcola quale layout deve essere utilizzato.

  class ProjectsController < ApplicationController
    layout :user_layout

    def index
      @projects = Project.find(:all)
    end

    protected
    def user_layout
      if current_user.admin?
        "admin" 
      else
        "application" 
      end
    end
  end    
  

Possiamo perfino restingere il layout ad una singola action di un controller con il comando render.

  def index
    @projects = Project.find(:all)
    render :layout => 'projects'
  end
  

Il layout imposto mediante il comando render avrà la precedenza su ogni altro layout specifico del controller.
Infine, per mostrare una action priva di layout, possiamo usare:

render :layout => false

Note

  1. A partire da Rails 2 il file dovrebbe chiamarsi application.html.erb
  2. Di nuovo, da Rails 2 in avanti l’estensione dovrebbe essere .html.erb piuttosto che .rhtml.