Bird
Raised Fist0
Ruby on Railsframework~10 mins

Layouts and content_for in Ruby on Rails - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Layouts and content_for
Request comes in
↓
Controller action runs
↓
Render view template
↓
View calls content_for :section
↓
Layout calls yield or yield(:section)
↓
Final HTML sent to browser
Rails processes a request by running a controller, rendering a view that defines content blocks with content_for, then the layout inserts those blocks using yield or yield(:section).
Execution Sample
Ruby on Rails
<!-- layout.html.erb -->
<html>
  <body>
    <header><%= yield :header %></header>
    <main><%= yield %></main>
  </body>
</html>
This layout inserts a header section from content_for :header and the main content from the view.
Execution Table
StepActionTemplate/MethodContent Stored or RenderedOutput Location
1Controller renders viewshow.html.erbStarts rendering viewN/A
2View calls content_for :headershow.html.erbStores '<h1>Page Title</h1>' in :headerStored for layout
3View renders main contentshow.html.erbRenders '<p>Welcome to the page.</p>'Main yield content
4Layout calls yield :headerlayout.html.erbInserts stored header contentInside <header> tag
5Layout calls yieldlayout.html.erbInserts main contentInside <main> tag
6Final HTML sentlayout.html.erb<html><body><header><h1>Page Title</h1></header><main><p>Welcome to the page.</p></main></body></html>Browser receives full page
💡 All content_for blocks inserted by layout yields; rendering completes.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 5Final
content_for :headerempty'<h1>Page Title</h1>' stored'<h1>Page Title</h1>' stored'<h1>Page Title</h1>' inserted'<h1>Page Title</h1>' in final HTML
main contentemptyempty'<p>Welcome to the page.</p>' rendered'<p>Welcome to the page.</p>' inserted'<p>Welcome to the page.</p>' in final HTML
Key Moments - 3 Insights
Why does content_for not immediately display content where it is called?
content_for stores content in a buffer for later use by the layout's yield. See Step 2 in execution_table where content is stored, not output.
What happens if the layout does not call yield(:header)?
The stored content_for :header block is never inserted into the final HTML, so it won't appear on the page. See Step 4 where yield :header inserts content.
Can the main content be accessed with yield(:main)?
No, the main content is accessed with yield without arguments. yield(:section) only works for named content_for blocks. See Step 5 where yield inserts main content.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what content is stored after Step 2?
AEmpty content
B'<p>Welcome to the page.</p>' in main content
C'<h1>Page Title</h1>' in content_for :header
D'<footer>Footer text</footer>' in content_for :footer
💡 Hint
Check the 'Content Stored or Rendered' column at Step 2.
At which step does the layout insert the main content into the page?
AStep 4
BStep 5
CStep 2
DStep 6
💡 Hint
Look for 'Layout calls yield' in the 'Action' column.
If the layout did not call yield :header, what would happen to the header content?
AIt would be lost and not appear in the final HTML
BIt would still appear in the main content area
CIt would cause an error
DIt would appear twice in the page
💡 Hint
Refer to the key moment about missing yield(:header) and Step 4.
Concept Snapshot
Rails layouts wrap views to create full pages.
Use content_for to define named content blocks in views.
Layouts insert these blocks with yield(:name).
Main view content is inserted with yield without arguments.
If layout omits yield(:name), that content is not shown.
This separates page structure from page content.
Full Transcript
In Rails, when a request comes in, the controller runs and renders a view template. The view can define content blocks using content_for, which stores content for later use. The layout template then calls yield or yield with a symbol to insert these stored blocks into the final HTML. For example, content_for :header stores header content, and the layout inserts it with yield :header. The main content of the view is inserted with yield without arguments. If the layout does not call yield for a content_for block, that content will not appear in the final page. This system helps separate the page's structure (layout) from its content (views).

Practice

(1/5)
1. What is the main purpose of using content_for in Rails layouts?
easy
A. To define the main layout file for the application
B. To insert specific content into named sections of a layout
C. To create a new controller action
D. To style the page with CSS

Solution

  1. Step 1: Understand the role of layouts

    Layouts provide a shared structure like headers and footers for pages.
  2. Step 2: Understand content_for usage

    content_for allows views to add content to specific named areas in the layout.
  3. Final Answer:

    To insert specific content into named sections of a layout -> Option B
  4. Quick Check:

    content_for inserts content into layout spots [OK]
Hint: Remember: content_for fills layout placeholders [OK]
Common Mistakes:
  • Confusing content_for with layout definition
  • Thinking it styles pages directly
  • Mixing it up with controller actions
2. Which of the following is the correct syntax to define a content block named :sidebar in a Rails view?
easy
A. <%= yield :sidebar %>
B. <% content_for :sidebar = 'Sidebar content' %>
C. <% sidebar_content 'Sidebar content' %>
D. <%= content_for :sidebar do %>Sidebar content<% end %>

Solution

  1. Step 1: Recall content_for block syntax

    The correct way is to use content_for :name do ... end with ERB tags.
  2. Step 2: Check each option

    <%= content_for :sidebar do %>Sidebar content<% end %> uses <%= content_for :sidebar do %> ... <% end %> which is correct syntax. <% content_for :sidebar = 'Sidebar content' %> tries assignment incorrectly. <%= yield :sidebar %> is for yielding, not defining. <% sidebar_content 'Sidebar content' %> is invalid.
  3. Final Answer:

    <%= content_for :sidebar do %>Sidebar content<% end %> -> Option D
  4. Quick Check:

    Use content_for :name do ... end to define content [OK]
Hint: Use content_for :name do ... end to define blocks [OK]
Common Mistakes:
  • Using assignment instead of block for content_for
  • Confusing yield with content_for
  • Missing ERB tags or using wrong ones
3. Given the layout code:
<html>
<body>
  <header><%= yield :header %></header>
  <main><%= yield %></main>
  <footer><%= yield :footer %></footer>
</body>
</html>

And the view code:
<%= content_for :header do %>Welcome Header<% end %>

Main content here

<%= content_for :footer do %>Footer Info<% end %>

What will be rendered inside the <main> tag?
medium
A. Footer Info
B. Welcome Header
C.

Main content here

D. Nothing

Solution

  1. Step 1: Understand yield usage in layout

    yield without arguments renders the main view content. yield :header and yield :footer render named content blocks.
  2. Step 2: Identify main content in view

    The main content is the part outside content_for blocks: <p>Main content here</p>.
  3. Final Answer:

    <p>Main content here</p> -> Option C
  4. Quick Check:

    Main content = yield without args = <p>Main content here</p> [OK]
Hint: Main content is outside content_for, shown by plain yield [OK]
Common Mistakes:
  • Thinking content_for blocks appear in main yield
  • Confusing named yields with main yield
  • Ignoring content outside content_for
4. You have this layout snippet:
<header><%= yield :title %></header>

And this view code:
<% content_for :title = 'Page Title' %>

Why does the title not appear in the header when rendering?
medium
A. Because content_for must use a block, not assignment
B. Because yield is missing in the layout
C. Because the layout file is not linked properly
D. Because content_for only works in controllers

Solution

  1. Step 1: Check content_for syntax in view

    The code uses assignment content_for :title = 'Page Title', which is invalid syntax.
  2. Step 2: Correct usage of content_for

    content_for requires a block: content_for :title do 'Page Title' end or content_for(:title) { 'Page Title' }.
  3. Final Answer:

    Because content_for must use a block, not assignment -> Option A
  4. Quick Check:

    content_for needs blocks, not assignment [OK]
Hint: Always use blocks with content_for, not assignment [OK]
Common Mistakes:
  • Using assignment instead of block for content_for
  • Forgetting to yield named content in layout
  • Assuming content_for works in controllers
5. You want to create a layout that shows a custom page title if provided, or a default title otherwise. Which layout code correctly uses content_for and yield to achieve this?
hard
A. <title><%= content_for?(:title) ? yield(:title) : 'Default Title' %></title>
B. <title><%= yield(:title) || 'Default Title' %></title>
C. <title><%= content_for(:title) || 'Default Title' %></title>
D. <title><%= yield :title if content_for?(:title) %></title>

Solution

  1. Step 1: Understand content_for? and yield

    content_for?(:title) checks if content was provided. yield(:title) outputs it.
  2. Step 2: Check each option for fallback logic

    <title><%= content_for?(:title) ? yield(:title) : 'Default Title' %></title> uses a ternary to show yield(:title) if present, else 'Default Title'. <title><%= yield(:title) || 'Default Title' %></title> uses yield(:title) || 'Default Title' but yield(:title) returns nil if no content, so fallback works but less explicit. <title><%= content_for(:title) || 'Default Title' %></title> uses content_for(:title) which returns nil and does not output content. <title><%= yield :title if content_for?(:title) %></title> only yields if content exists but shows nothing otherwise.
  3. Final Answer:

    <title><%= content_for?(:title) ? yield(:title) : 'Default Title' %></title> -> Option A
  4. Quick Check:

    Use content_for? to check, then yield or fallback [OK]
Hint: Use content_for?(:name) to check before yielding [OK]
Common Mistakes:
  • Using content_for instead of content_for? for checking
  • Assuming yield(:name) returns empty string instead of nil
  • Not providing fallback content
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard