2013-12-09 19 views
8

Sto avendo difficoltà a trovare un modo per effettuare le seguenti operazioni:rotaie 4 schemi di nesting

Diciamo che nel mio application.html.erb ho il seguente

<div id="one" > 
    <%= yield %> 
</div> 

poi voglio avere un altro file di layout asdf.html.erb

<div id="two"> 
    <%= yield %> 
</div> 

voglio che il risultato finale sia

<div id="one> 
    <div id="two"> 
     <%= yield %> 
    </div> 
</div> 

È possibile? Grazie.

risposta

7

Per impostazione predefinita, application.html.erb è il layout. È possibile rendere un sub-layout di default chiamando come un parziale dal layout dell'applicazione:

# app/views/layouts/application.html.erb 
<div id="one" > 
    <%= render "layouts/asdf" %> 
</div> 

# app/views/layouts/_asdf.html.erb 
<div id="two"> 
    <%= yield %> 
</div> 

Ciò produrrà il seguente:

<div id="one> 
    <div id="two"> 
     <%= yield %> 
    </div> 
</div> 

alternativa, se stai cercando di condizionatamente i layout di rendering su una base controller-by-controller, si dovrebbe considerare l'utilizzo di nested layouts. Dalla documentazione:

Nelle pagine generate da NewsController, si vuole nascondere il menu principale e aggiungere un menu a destra:

# app/views/layouts/news.html.erb 
<% content_for :stylesheets do %> 
    #top_menu {display: none} 
    #right_menu {float: right; background-color: yellow; color: black} 
<% end %> 
<% content_for :content do %> 
    <div id="right_menu">Right menu items here</div> 
    <%= content_for?(:news_content) ? yield(:news_content) : yield %> 
<% end %> 
<%= render template: "layouts/application" %> 

I punti di vista Notizie utilizzeranno il nuovo layout, nascondendo il menu principale e aggiungendo un nuovo menu di destra all'interno del div "content".

+0

Ma come ottenere il nome del layout che è stato chiamato? Mi aspetterei qualcosa come 'layout == 'applicazione'? yield: render layout' –

8

la soluzione più pulita che ho trovato di gran lunga è venuto da questa repo: https://github.com/rwz/nestive

non volevo tutta la gemma. Se siete come me, ecco come ho raggiunto quello che volevo:

# application_helper.rb 

    # From https://github.com/rwz/nestive/blob/master/lib/nestive/layout_helper.rb 
    def extends(layout, &block) 
    # Make sure it's a string 
    layout = layout.to_s 

    # If there's no directory component, presume a plain layout name 
    layout = "layouts/#{layout}" unless layout.include?('/') 

    # Capture the content to be placed inside the extended layout 
    @view_flow.get(:layout).replace capture(&block) 

    render file: layout 
    end 

Poi si tengono /layouts/application.html.erb invariato!

E puoi creare altri layout. Nel mio caso /layouts/public.html.erb e /layouts/devise.html.erb:

# public.html.erb 
<%= extends :application do %> 
    <%= render 'partials/navbar' %> 
    <div class="container margin-top"> 
    <%= yield %> 
    </div> 
<% end %> 

# devise.html.erb 
<%= extends :public do %> 
    <div class="col-sm-6 col-sm-offset-3"> 
    <%= yield %> 
    </div> 
<% end %> 

funziona come un fascino! Sto ancora sorridendo, finalmente ho trovato una soluzione pulita.

+0

Scoperto il tuo commento oggi e subito impiegato. È molto utile, grazie! – dimitarvp

1

È inoltre possibile effettuare le seguenti operazioni per rendere condizionalmente un sub-impaginazione:

# app/views/layouts/application.html.erb 
<%= controller.controller_name.include?("foo") ? render("layouts/foo") : yield %> 

# app/views/layouts/_foo.html.erb 
<div class="bar"> 
    <%= yield %> 
</div> 

Per scenari con un unico sub-impaginazione, ho trovato questo preferibile l'approccio di layout nidificata delineato nel Rails guide perché l'esecuzione non deve passare dal layout secondario, al layout principale e quindi tornare al layout secondario. Invece, scorre in modo più naturale, a partire dal layout principale, procedendo verso il sub-layout e quindi terminando alla vista.

0

Se stai cercando una soluzione pulita che non accoppi application.html.erb ai suoi elementi ereditari, la gemma nestiva (come indicato nell'altro è abituato a farlo ma non sembra funzionare con Rails 5. Ma questo è un altro modo per farlo:. https://mattbrictson.com/easier-nested-layouts-in-rails

# Place this in app/helpers/layouts_helper.rb 
module LayoutsHelper 
    def parent_layout(layout) 
    @view_flow.set(:layout, output_buffer) 
    output = render(:file => "layouts/#{layout}") 
    self.output_buffer = ActionView::OutputBuffer.new(output) 
    end 
end 

Poi asdf.html.erb diventa

<div id="two"> 
    <%= yield %> 
</div> 
<% parent_layout 'application' %> 

Sappiate che questo si basa su Rails interni e potrebbe smettere di funzionare in una versione futura questo non è molto probabile che accada presto, come esso ha lavorato per almeno 3 anni (in base alla data del post sul blog collegato).