diff --git a/docs/guide/collections.md b/docs/guide/collections.md
index 426a8b939..48ae219cf 100644
--- a/docs/guide/collections.md
+++ b/docs/guide/collections.md
@@ -12,12 +12,10 @@ Since 2.1.0
Like [Rails partials](https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-collections), it's possible to render a collection with ViewComponents, using `with_collection`:
```erb
-<%# app/view/products/index.html.erb %>
<%= render(ProductComponent.with_collection(@products)) %>
```
```ruby
-# app/components/product_component.rb
class ProductComponent < ViewComponent::Base
def initialize(product:)
@product = product
@@ -32,7 +30,6 @@ end
Use `with_collection_parameter` to change the name of the collection parameter:
```ruby
-# app/components/product_component.rb
class ProductComponent < ViewComponent::Base
with_collection_parameter :item
@@ -47,15 +44,20 @@ end
Additional arguments besides the collection are passed to each component instance:
```erb
-<%# app/view/products/index.html.erb %>
<%= render(ProductComponent.with_collection(@products, notice: "hi")) %>
```
```ruby
-# app/components/product_component.rb
class ProductComponent < ViewComponent::Base
with_collection_parameter :item
+ erb_template <<-ERB
+
+ <%= @item.name %>
+ <%= @notice %>
+
+ ERB
+
def initialize(item:, notice:)
@item = item
@notice = notice
@@ -63,14 +65,6 @@ class ProductComponent < ViewComponent::Base
end
```
-```erb
-<%# app/components/product_component.html.erb %>
-
- <%= @item.name %>
- <%= @notice %>
-
-```
-
## Collection counter
Since 2.5.0
@@ -79,8 +73,13 @@ Since 2.5.0
ViewComponent defines a counter variable matching the parameter name above, followed by `_counter`. To access the variable, add it to `initialize` as an argument:
```ruby
-# app/components/product_component.rb
class ProductComponent < ViewComponent::Base
+ erb_template <<-ERB
+
+ <%= @counter %> <%= @product.name %>
+
+ ERB
+
def initialize(product:, product_counter:)
@product = product
@counter = product_counter
@@ -88,13 +87,6 @@ class ProductComponent < ViewComponent::Base
end
```
-```erb
-<%# app/components/product_component.html.erb %>
-
- <%= @counter %> <%= @product.name %>
-
-```
-
## Collection iteration context
Since 2.33.0
@@ -105,18 +97,16 @@ ViewComponent defines an iteration variable matching the parameter name above, f
To access the variable, add it to `initialize` as an argument:
```ruby
-# app/components/product_component.rb
class ProductComponent < ViewComponent::Base
+ erb_template <<-ERB
+ ">
+ <%= @product.name %>
+
+ ERB
+
def initialize(product:, product_iteration:)
@product = product
@iteration = product_iteration
end
end
```
-
-```erb
-<%# app/components/product_component.html.erb %>
-">
- <%= @product.name %>
-
-```
diff --git a/docs/guide/conditional_rendering.md b/docs/guide/conditional_rendering.md
index cb65e3630..8c4223c0b 100644
--- a/docs/guide/conditional_rendering.md
+++ b/docs/guide/conditional_rendering.md
@@ -30,8 +30,13 @@ or the view that renders the component:
Using the `#render?` hook simplifies the view:
```ruby
-# app/components/confirm_email_component.rb
class ConfirmEmailComponent < ViewComponent::Base
+ erb_template <<-ERB
+
+ Please confirm your email address.
+
+ ERB
+
def initialize(user:)
@user = user
end
@@ -42,13 +47,6 @@ class ConfirmEmailComponent < ViewComponent::Base
end
```
-```erb
-<%# app/components/confirm_email_component.html.erb %>
-
- Please confirm your email address.
-
-```
-
```erb
<%= render(ConfirmEmailComponent.new(user: current_user)) %>
```
diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md
index e70c093db..8470f6dab 100644
--- a/docs/guide/getting-started.md
+++ b/docs/guide/getting-started.md
@@ -41,28 +41,25 @@ Available options to customize the generator are documented on the [Generators](
## Implementation
-A ViewComponent is a Ruby file and corresponding template file with the same base name:
+A ViewComponent is a Ruby class that inherits from `ViewComponent::Base`:
```ruby
-# app/components/example_component.rb
class ExampleComponent < ViewComponent::Base
+ erb_template <<-ERB
+ <%= content %>
+ ERB
+
def initialize(title:)
@title = title
end
end
```
-```erb
-<%# app/components/example_component.html.erb %>
-<%= content %>
-```
-
Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor.
Rendered in a view as:
```erb
-<%# app/views/home/index.html.erb %>
<%= render(ExampleComponent.new(title: "my title")) do %>
Hello, World!
<% end %>
@@ -82,7 +79,6 @@ Since 2.31.0
String content can also be passed to a ViewComponent by calling `#with_content`:
```erb
-<%# app/views/home/index.html.erb %>
<%= render(ExampleComponent.new(title: "my title").with_content("Hello, World!")) %>
```
@@ -91,7 +87,6 @@ String content can also be passed to a ViewComponent by calling `#with_content`:
It's also possible to render ViewComponents in controllers:
```ruby
-# app/controllers/home_controller.rb
def show
render(ExampleComponent.new(title: "My Title"))
end
@@ -102,7 +97,6 @@ _Note: Content can't be passed to a component via a block in controllers. Instea
When using turbo frames with [turbo-rails](https://github.com/hotwired/turbo-rails), set `content_type` as `text/html`:
```ruby
-# app/controllers/home_controller.rb
def create
render(ExampleComponent.new, content_type: "text/html")
end
diff --git a/docs/guide/templates.md b/docs/guide/templates.md
index f3681a8c0..073191308 100644
--- a/docs/guide/templates.md
+++ b/docs/guide/templates.md
@@ -8,9 +8,28 @@ parent: How-to guide
ViewComponents wrap a template (or several, if using [variants](https://guides.rubyonrails.org/layouts_and_rendering.html#the-variants-option)), defined in one of several ways:
+## Inline
+
+Since 3.0.0
+{: .label }
+
+To define a template inside a component, call the `.TEMPLATE_HANDLER_template` macro:
+
+```ruby
+class InlineErbComponent < ViewComponent::Base
+ erb_template <<~ERB
+ Hello, <%= @name %>!
+ ERB
+
+ def initialize(name)
+ @name = name
+ end
+end
+```
+
## Sibling file
-The simplest option is to place the view next to the Ruby component:
+Place template file next to the component:
```console
app/components
@@ -82,27 +101,6 @@ end
_**Note**: `call_*` methods must be public._
-## Inline
-
-Since 3.0.0
-{: .label }
-
-To define a template inside a component, call the `.TEMPLATE_HANDLER_template` macro:
-
-```ruby
-class InlineErbComponent < ViewComponent::Base
- attr_reader :name
-
- erb_template <<~ERB
- Hello, <%= name %>!
- ERB
-
- def initialize(name)
- @name = name
- end
-end
-```
-
## Inherited
Since 2.19.0
diff --git a/docs/index.md b/docs/index.md
index 40e3c7a70..84bf32926 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -10,26 +10,23 @@ A framework for creating reusable, testable & encapsulated view components, buil
## What's a ViewComponent?
-Think of ViewComponents as an evolution of the presenter pattern, inspired by [React](https://reactjs.org/docs/react-component.html). A ViewComponent is a Ruby object and template:
+Think of ViewComponents as an evolution of the presenter pattern, inspired by [React](https://reactjs.org/docs/react-component.html). A ViewComponent is a Ruby object:
```ruby
-# app/components/message_component.rb
class MessageComponent < ViewComponent::Base
+ erb_template <<-ERB
+ Hello, <%= @name %>!
+ ERB
+
def initialize(name:)
@name = name
end
end
```
-```erb
-<%# app/components/message_component.html.erb %>
-Hello, <%= @name %>!
-```
-
Which is instantiated and passed to Rails' `#render`:
```erb
-<%# app/views/demo/index.html.erb %>
<%= render(MessageComponent.new(name: "World")) %>
```
@@ -85,7 +82,7 @@ Based on several [benchmarks](https://github.com/viewcomponent/view_component/bl
The primary optimization is pre-compiling all ViewComponent templates at application boot, instead of at runtime like traditional Rails views.
-For example, the `MessageComponent` template is compiled onto the Ruby object like so:
+For example, the `MessageComponent` template is compiled onto the Ruby object:
```ruby
# app/components/message_component.rb