Layout differenti per lo stesso controller

Può succedere di dover utilizzare template grafici diversi per metodi differenti di uno stesso controller. In prima analisi verrebbe da implementare una soluzione che prevede una chiamata esplicita al layout da utilizzare all’interno di ogni singola action.

Qualcosa del tipo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class PostController < ApplicationController
  def index
    [...]
    :layout => 'standard'
  end

  def show
    [...]
    :layout => 'standard'
  end

  def new
    [...]
    :layout => 'admin'
  end

  def edit
    [...]
    :layout => 'admin'
  end
end

Esiste però un modo più semplice e DRY di implementare la stessa soluzione. Per selezionare il layout corretto da utilizzare Rails cerca una action chiamata “choose_layout”.

Definendo la propria versione di “choose_layout” è possibile gestire banalmente la scelta del layout come potete vedere nel codice che segue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class PostController < ApplicationController

  layout :choose_layout

  def index
    [...]
  end

  def show
    [...]
  end

  def new
    [...]
  end

  def edit
    [...]
  end

  private

  def choose_layout    
    if [ 'new', 'edit' ].include? action_name
      'admin'
    else
      'standard'
    end
  end
end

Questa action utilizza la variabile Rails action_name che contiene il nome dell’action corrente per decidere quale layout caricare.
Quindi se action_name vale ‘new’ o ‘edit’ verrà caricato il layout ‘admin‘, altrimenti per qualsiasi altra action verrà caricato il layout ‘standard‘.

Tags: , ,


About Claudio

Claudio Marai is a co-founder of DevInterface.

After graduating in Computer Science has contributed to develop complex web applications based on Java/J2EE and desktop applications with the. NET framework for the Ministry of Justice and ultimately for the banking ambit.

The passion for web in recent years has led him to be interested in more modern frameworks such as Ruby on Rails and Django, and to a development approach based on agile methodologies such as eXtreme Programming and SCRUM.

About DevInterface

We are an information and communication technology agency. Our mission is to provide web application development, design services and communication strategies. We specialize in building web applications with modern and efficient frameworks.

Related Post

5 Responses to “Layout differenti per lo stesso controller”

  1. [...] This post was mentioned on Twitter by Jason Noble, DevInterface. DevInterface said: "Different layout for the same controllerLayout differenti per lo stesso controller" – http://bit.ly/d0P7ZU #rubytweets [...]

  2. Stephen Touset scrive:

    The layout call already supports an :o nly and :except parameter, for exactly this purpose. Why reinvent the wheel?

  3. Jamie Dyer scrive:

    What Stephen said, also in this example you wouldn’t even need to specify the layout if you separate the admin features into it’s own controller. In my experience applications that try to combine user and admin functionality in the same controllers are over complicated and poorly implemented.

  4. Dan scrive:

    Sometimes the logic behind which layout to render is more complicated than, “This action uses this template and this action uses that one”

    I hadn’t seen a symbol passed to the layout method, thanks for sharing!

  5. Claudio scrive:

    @Stephan: I’m agree with you we don’t have to reinvent the wheel.
    But I think this method can be helpful if you have to add some conditions.
    Using this approach you can write something like:

    1
    2
    3
    4
    5
    6
    7
    def choose_layout    
      if some_conditions and [ 'new', 'edit' ].include? action_name
        'admin'
      else
        'standard'
      end
    end

    @Jamie: the ‘admin’ name for the layout in my example is just for demonstration purpose, I don’t mean that the same controller will combine user and administration functionality. It’s up to developer to implement controllers as he prefers.

Leave a Reply

Insert code beetween <code lang="ruby"> and </code>

Copyright 2012 DevInterface s.n.c.

DevInterface Blog is proudly powered by WordPress