Рейки роблять частковими з блоком


119

Я намагаюся повторно використовувати компонент html, який я написав, що забезпечує стилістику панелі. Щось на зразок:

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

Тож я бачу, що візуалізація займає блок. Я зрозумів, що я можу зробити щось подібне:

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

І я хочу зробити щось на кшталт:

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

На жаль, ця помилка не працює:

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

Тож це =очевидно не подобається з блоком, але якщо я його видаляю, він просто нічого не виводить.

Хтось знає, як тут робити те, що я намагаюся досягти? Я хотів би повторно використовувати цей html панель у багатьох місцях на своєму сайті.


1
Прийнята відповідь правильна, але оскільки Rails 5.0.0 це можливо без layoutобходу, див. Guides.rubyonrails.org/…
fabi

Відповіді:


208

Хоча обидві відповіді вище (як приклад, що тоні посилається на будь-який спосіб), я виявив найкоректнішу відповідь у цьому вище посту (коментар Корнеліс Сієцма)

Я думаю, render :layoutробить саме те , що я шукав:

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

поєднується з:

# /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
в Rails 3.2.2, я думаю, вам доведеться використовувати <%= %>замість цього <% %>, наприклад<%= render :layout => '/shared/panel',
Siwei Shen 申思维

Ви маєте рацію, ця публікація не передбачає припущень щодо версії Rails, я впевнений, що люди можуть це зрозуміти.
бред

як ця (вирішує мою проблему так +1), але це хороша практика? чи не буде чомусь уповільнення? Можливо, база даних спрацьовує раніше, ніж це передбачається, через іншу врожайність (не встигаю досліджувати це самотужки зараз, просто цікаво)
еквівалент8

1
Будь-який спосіб дізнатися, чи отримано вміст? У випадку, якщо це необов’язково.
Vadorequest

3
У Rails 5.0 сталася зміна, тому це загальне для всіх партій, а не лише для макетів. Ви можете змінити перший рядок коду для виклику на:<%= render '/shared/panel', title: 'some title' do %>
Джей Мітчелл,

27

Ось альтернатива на основі попередніх відповідей.

Створіть своє часткове в 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>

Визначте свій метод на application_helper.rb:

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

Телефонуйте з будь-якого виду:

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

11

Ви можете використовувати помічник захоплення та навіть вбудований у виклику візуалізації:

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

і в спільному / панелі:

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

який дасть:

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

Дивіться http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html


1
Вбудований візерунок приємний для часткової потреби в декількох блоках.
mahemoff

4

На основі прийнятої відповіді це те, що добре спрацювало для мене за допомогою Rails 4.

Ми можемо надати панель як таку:

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

введіть тут опис зображення

Для цього потрібен допоміжний метод і спільний вигляд:

хелперний метод (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

Переглянути (/ui/panel.html.haml)

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

Це працює в Rails 5.x теж мені просто потрібно , щоб зміни panel.html.hamlв_panel.html.haml
Kris

1

Я думаю, що це спрацює (тільки що зробив швидкий брудний тест), якщо спершу призначити його змінній, а потім вивести її.

<% foo = render :partial => '/shared/panel', :locals =>{:title => "Some Title"} do %>
<p>Here is some content to be rendered inside the panel</p>
<% end %>
<%= foo %>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.