wake-up-neo.com

Rails rendern partiell mit Block

Ich versuche, eine HTML-Komponente, die ich geschrieben habe, die Panel-Styling bietet, wieder zu verwenden. So etwas wie:

  <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>

Ich sehe also, dass das Rendern einen Block benötigt. Ich dachte mir, ich könnte so etwas machen:

# /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 etwas machen 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 mit diesem Fehler nicht:

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 mag es nicht die = natürlich mit einem Block, aber wenn ich ihn entferne, gibt er einfach nichts aus.

Weiß jemand, wie man das macht, was ich hier erreichen will? Ich möchte dieses HTML-Panel an vielen Stellen auf meiner Website wiederverwenden.

111
brad

Während diese beiden Antworten oben funktionieren (auch das Beispiel, auf das Tony sowieso verweist), fand ich in dem obigen Beitrag die prägnanteste Antwort (Kommentar von Kornelis Sietsma)

Ich vermute render :layout macht gena was ich gesucht habe:

# 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>
190
brad

Hier ist eine Alternative basierend auf vorherigen Antworten.

Erstelle deinen 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

Nennen Sie es aus jeder Sicht:

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

Sie können den Capture-Helfer und sogar Inline im Render-Aufruf verwenden:

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

und in shared/panel:

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

was produzieren wird:

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

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

8
Yetanotherjosh

Basierend auf der akzeptierten Antwort funktionierte dies gut mit Rails 4.

Wir können ein Panel als solches rendern:

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

enter image description here

Dies erfordert eine Hilfsmethode und eine gemeinsame Ansicht:

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
2
Kris

Ich denke, es wird funktionieren (habe gerade einen schnellen Dirty-Test durchgeführt), 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 %>
1
Tesserex