You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails视图嵌套布局:命名yield失效但匿名yield正常

Hey there, let's fix that named yield issue you're having with nested layouts in Rails. I spot a couple of small mistakes in your setup that are causing the :main_content yield to not render anything. Let's walk through the fixes step by step.

Critical Mistake 1: Your PWA layout is misnamed as a partial

You named it _pwa.html.erb, but Rails expects layout files in app/views/layouts/ to be full template files (no leading underscore). The underscore tells Rails it's a partial, not a proper layout, which breaks the nested layout logic. Rename it to pwa.html.erb.

Fix the nested layout structure

Your application.html.erb is the base layout, so your pwa.html.erb needs to properly nest inside it. Here are two correct ways to write the PWA layout:

Option 1: Use content_for to pass content to the base layout

<%# app/views/layouts/pwa.html.erb %>
<% content_for :body do %>
  <div class="container">
    <%= yield :main_content %>
  </div>
<% end %>

<%= render template: "layouts/application" %>

Option 2: Declare the parent layout directly with the layout helper

<%# app/views/layouts/pwa.html.erb %>
<% layout 'application' do %>
  <div class="container">
    <%= yield :main_content %>
  </div>
<% end %>

Ensure content_for runs before rendering the layout

Your view file (view.html.erb) was cut off, but the key rule is: the content_for :main_content block needs to execute before you render the PWA layout. Here are two working approaches:

Approach 1: Write content_for directly in the view

<%# app/views/your_controller/view.html.erb %>
<% content_for :main_content do %>
  <h1>Test</h1>
<% end %>

<%= render layout: "layouts/pwa" %>

Approach 2: Use a partial for reusable content

Keep your _partial.html.erb as is (partials do use leading underscores):

<%# app/views/your_controller/_partial.html.erb %>
<% content_for :main_content do %>
  <h1>Test</h1>
<% end %>

Then in your view file, render the partial first, then the layout:

<%# app/views/your_controller/view.html.erb %>
<%= render partial: "partial" %>
<%= render layout: "layouts/pwa" %>

Why this works

When you run content_for :main_content, Rails stores that content in a buffer. When the layout calls yield :main_content, it pulls from that buffer. If you render the layout before running content_for, the buffer is empty—hence nothing shows up. Also, using a proper layout file (no underscore) ensures Rails treats it as a layout template, not a partial, so the nested yield logic functions correctly.

内容的提问来源于stack exchange,提问作者james

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:29:27