Reputation: 1236
I'm looking for solution to have partial with multiple yields
.
In real example I have this views structure:
Basic application.erb (/views/layouts/application.erb):
<!DOCTYPE html>
<head>
<title>Some title</title>
</head>
<body>
<div class="page">
<%= yield %>
</div>
</body>
</html>
Some partial to DRY my code (/views/shared/content.erb):
<div class="content">
<div class="sidebar">
<%= yield :sidebar %>
</div>
<div class="main">
<%= yield %>
</div>
</div>
And controller view (/views/home/index.erb):
<%= render :partial => 'layouts/header' %>
<%= render :partial => 'shared/navigation' %>
<% # It is close to what I want to do %>
<%= render :layout => 'shared/content' do %>
<% content_for :sidebar do %>
<%# This is will go to application.erb, not in content.erb %>
<%= render :partial => 'shared/menu' %>
<% end %>
<%= yield %>
<% end %>
<%= render :partial => 'layouts/footer' %>
So the main issue here is to have a template block with multiple yield areas and ability to pass custom html or render another partial.
Upvotes: 5
Views: 5850
Reputation: 1125
Here is my solution:
/views/shared/_content.erb
<div class="content">
<div class="sidebar">
<%= yield :sidebar %>
</div>
<div class="main">
<%= yield %>
</div>
</div>
views/home/index.erb
<%= my_content_tag do %>
<% content_for :sidebar do %>
<%= render :partial => 'shared/menu' %>
<% end %>
<%= yield %>
<% end %>
app/helpers/my_tags_helper.rb
module MyTagsHelper
def my_content_tag(&block)
sidebar_backup = @view_flow.content.delete(:sidebar)
x = capture(&block)
html = render('shared/content') { x }
@view_flow.content[:sidebar] = sidebar_backup if sidebar_backup
html
end
end
The key is using capture
to extract content_for
block and pass it into @view_flow
Upvotes: 1
Reputation: 1236
In my case I've found solution like this.
On my controller view (/views/home/index.erb):
<% sidebar_content = render :partial => 'shared/slider' %>
<%= render :layout => 'shared/content', :locals => {:sidebar => sidebar_content} do %>
<%= yield %>
<% end %>
The partial with multiple areas (/views/shared/content.erb):
<div class="content">
<div class="sidebar">
<%= sidebar %>
</div>
<div class="main">
<%= yield %>
</div>
</div>
This solution doesn't look pretty, but it works. I hope to find something better in near future.
Upvotes: 5
Reputation: 8900
This question is old, however, it's still relevant when I was searching for an answer on Google.
I've come up with a solution, while still not beautiful, works very well. The idea uses Rails' capture
method, which takes a block and stores its contents into a variable:
controller.html.erb
<%= render 'shared/partial', body: capture { %>
My body content
<% }, footer: capture { %>
My footer content
<% } %>
shared/_partial.html.erb
<div id="body"><%= body %></div>
<div id="footer"><%= footer %></div>
Hope this helps someone!
Upvotes: 15