Skip to content

Commit

Permalink
use Inline templates in docs
Browse files Browse the repository at this point in the history
This change updates our docs to lean on inline templates as
they greatly simplify our example code <3

I've intentionally omitted a changelog.
  • Loading branch information
joelhawksley committed Jun 23, 2023
1 parent 364dcbe commit f7f64a7
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 79 deletions.
48 changes: 19 additions & 29 deletions docs/guide/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -47,30 +44,27 @@ 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
<li>
<h2><%= @item.name %></h2>
<span><%= @notice %></span>
</li>
ERB

def initialize(item:, notice:)
@item = item
@notice = notice
end
end
```

```erb
<%# app/components/product_component.html.erb %>
<li>
<h2><%= @item.name %></h2>
<span><%= @notice %></span>
</li>
```

## Collection counter

Since 2.5.0
Expand All @@ -79,22 +73,20 @@ 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
<li>
<%= @counter %> <%= @product.name %>
</li>
ERB

def initialize(product:, product_counter:)
@product = product
@counter = product_counter
end
end
```

```erb
<%# app/components/product_component.html.erb %>
<li>
<%= @counter %> <%= @product.name %>
</li>
```

## Collection iteration context

Since 2.33.0
Expand All @@ -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
<li class="<%= "featured" if @iteration.first? %>">
<%= @product.name %>
</li>
ERB

def initialize(product:, product_iteration:)
@product = product
@iteration = product_iteration
end
end
```

```erb
<%# app/components/product_component.html.erb %>
<li class="<%= "featured" if @iteration.first? %>">
<%= @product.name %>
</li>
```
14 changes: 6 additions & 8 deletions docs/guide/conditional_rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<div class="banner">
Please confirm your email address.
</div>
ERB

def initialize(user:)
@user = user
end
Expand All @@ -42,13 +47,6 @@ class ConfirmEmailComponent < ViewComponent::Base
end
```

```erb
<%# app/components/confirm_email_component.html.erb %>
<div class="banner">
Please confirm your email address.
</div>
```

```erb
<%= render(ConfirmEmailComponent.new(user: current_user)) %>
```
Expand Down
16 changes: 5 additions & 11 deletions docs/guide/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<span title="<%= @title %>"><%= content %></span>
ERB

def initialize(title:)
@title = title
end
end
```

```erb
<%# app/components/example_component.html.erb %>
<span title="<%= @title %>"><%= content %></span>
```

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 %>
Expand All @@ -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!")) %>
```

Expand All @@ -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
Expand All @@ -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
Expand Down
42 changes: 20 additions & 22 deletions docs/guide/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<h1>Hello, <%= @name %>!</h1>
ERB

def initialize(name)
@name = name
end
end
```

## Sibling file

The simplest option is to place the view next to the Ruby component:
Place the view next to the Ruby component:

```console
app/components
Expand Down Expand Up @@ -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
<h1>Hello, <%= name %>!</h1>
ERB

def initialize(name)
@name = name
end
end
```

## Inherited

Since 2.19.0
Expand Down
15 changes: 6 additions & 9 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<h1>Hello, <%= @name %>!</h1>
ERB

def initialize(name:)
@name = name
end
end
```

```erb
<%# app/components/message_component.html.erb %>
<h1>Hello, <%= @name %>!</h1>
```

Which is instantiated and passed to Rails' `#render`:

```erb
<%# app/views/demo/index.html.erb %>
<%= render(MessageComponent.new(name: "World")) %>
```

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f7f64a7

Please sign in to comment.