2010-06-01 17 views
95

Ich versuche, eine HTML-Komponente, die ich geschrieben habe, die Panel-Styling bietet wieder zu verwenden. Etwas wie:Schienen render teilweise mit Block

<div class="v-panel"> 
    <div class="v-panel-tr"></div> 
    <h3>Some Title</h3> 
    <div class="v-panel-c"> 
     .. content goes here 
    </div> 
    <div class="v-panel-b"><div class="v-panel-br"></div><div class="v-panel-bl"></div></div> 
    </div> 

So sehe ich, dass Render einen Block nimmt. Ich dachte, dann könnte ich so etwas tun:

# /shared/_panel.html.erb 
<div class="v-panel"> 
    <div class="v-panel-tr"></div> 
    <h3><%= title %></h3> 
    <div class="v-panel-c"> 
    <%= yield %> 
    </div> 
    <div class="v-panel-b"><div class="v-panel-br"></div><div class="v-panel-bl"></div></div> 
</div> 

Und ich möchte so etwas wie:

#some html view 
<%= render :partial => '/shared/panel', :locals =>{:title => "Some Title"} do %> 
    <p>Here is some content to be rendered inside the panel</p> 
<% end %> 

Leider funktioniert das nicht mit diesem Fehler umgehen:

ActionView::TemplateError (/Users/bradrobertson/Repos/VeloUltralite/source/trunk/app/views/sessions/new.html.erb:1: , unexpected tRPAREN 

old_output_buffer = output_buffer;;@output_buffer = ''; __in_erb_template=true ; @output_buffer.concat((render :partial => '/shared/panel', :locals => {:title => "Welcome"} do).to_s) 
on line #1 of app/views/sessions/new.html.erb: 
1: <%= render :partial => '/shared/panel', :locals => {:title => "Welcome"} do -%> 
... 

So es mag die = offensichtlich nicht mit einem Block, aber wenn ich es entferne, dann gibt es nichts aus.

Weiß jemand wie ich das mache, was ich hier erreichen will? Ich möchte dieses Panel html an vielen Stellen meiner Site wiederverwenden.

+0

Die akzeptierte Antwort ist korrekt, aber seit Rails 5.0.0 ist dies ohne die 'Layout'-Problemumgehung möglich, siehe http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials-to-simplify -views – fabi

Antwort

172

Während diese beiden Antworten über Arbeit (auch das Beispiel, dass tony Links sowieso) ich in diesem oben genannten Post die knappste Antwort zu finden endete (Kommentar von Kornelis Sietsma)

Ich denke, render :layout tut genau, was ich suchte:

# Some View 
<%= render :layout => '/shared/panel', :locals => {:title => 'some title'} do %> 
    <p>Here is some content</p> 
<% end %> 

kombiniert mit:

# /shared/_panel.html.erb 
<div class="v-panel"> 
    <div class="v-panel-tr"></div> 
    <h3><%= title -%></h3> 
    <div class="v-panel-c"> 
    <%= yield %> 
    </div> 
</div> 
+6

in Rails 3.2.2, denke ich, dass Sie '<%= %>' anstelle von '<% %>', z. '<% = render: layout => '/ shared/panel',' –

+0

Sie haben recht, dieser Post macht keine Vermutungen über die Rails-Version, ich bin mir sicher, dass die Leute das herausfinden können. – brad

+0

wie dieser (löst mein Problem so +1), aber ist das eine gute Praxis? Wird es aus irgendeinem Grund keine Verlangsamung geben? Vielleicht löst die Datenbank früher als erwartet einen anderen Ertrag aus (habe keine Zeit, das jetzt selbst zu untersuchen, frage mich) – equivalent8

1

Ich denke, es wird funktionieren (nur schnell schmutzig Test), wenn Sie es zuerst einer Variablen zuweisen und dann ausgeben.

<% foo = render :partial => '/shared/panel', :locals =>{:title => "Some Title"} do %> 
<p>Here is some content to be rendered inside the panel</p> 
<% end %> 
<%= foo %> 
+2

Funktioniert nicht mit Rails 3.2. – Nowaker

7

Sie können die Capture-Helfer verwenden und sogar inline im Aufruf machen:

<%= render 'my_partial', 
      :locals => { :title => "Some Title" }, 
      :captured => capture { %> 
    <p>Here is some content to be rendered inside the partial</p> 
<% } %> 

und in gemeinsam genutzten/Platte:

<h3><%= title %></h3> 
<div class="my-outer-wrapper"> 
    <%= captured %> 
</div> 

, die produzieren:

<h3>Some Title</h3> 
<div class="my-outer-wrapper"> 
    <p>Here is some content to be rendered inside the partial</p> 
</div> 

See http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html

+1

Das Inline-Muster eignet sich gut für einen Teil, der mehrere Blöcke benötigt – mahemoff

19

Hier ist ein al basierend auf vorherigen Antworten.

Erstellen Sie Ihre Teil auf shared/_modal.html.erb:

<div class="ui modal form"> 
    <i class="close icon"></i> 
    <div class="header"> 
    <%= heading %> 
    </div> 
    <div class="content"> 
    <%= capture(&block) %> 
    </div> 
    <div class="actions"> 
    <div class="ui negative button">Cancel</div> 
    <div class="ui positive button">Ok</div> 
    </div> 
</div> 

Definieren Sie Ihre Methode auf application_helper.rb:

def modal_for(heading, &block) 
    render(
    partial: 'shared/modal', 
    locals: { heading: heading, block: block } 
) 
end 

es aus jeder Ansicht aufrufen:

<%= modal_for('My Title') do |t| %> 
    <p>Here is some content to be rendered inside the partial</p> 
<% end %> 
+1

good one !! –

1

auf der akzeptierte Antwort Basierend dies Was gut für mich funktioniert mit Rails 4.

Wir können ein Panel als solche machen:

= render_panel('Non Compliance Reports', type: 'primary') do 
    %p your content goes here! 

enter image description here

Dies erfordert eine Hilfsmethode und einen breiten Blick:

Hilfsmethode (ui_helper.rb)

def render_panel(heading, options = {}, &block) 
    options.reverse_merge!(type: 'default') 
    options[:panel_classes] = ["panel-#{options[:type]}"] 

    render layout: '/ui/panel', locals: { heading: heading, options: options } do 
    capture(&block) 
    end 
end 

Ansicht (/ui/panel.html.haml)

.panel{ class: options[:panel_classes] } 
    .panel-heading= heading 
    .panel-body 
    = yield