File: getting-started.md

package info (click to toggle)
ruby-view-component 4.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,832 kB
  • sloc: ruby: 8,385; sh: 166; makefile: 4
file content (130 lines) | stat: -rw-r--r-- 3,305 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
---
layout: default
title: Getting started
parent: How-to guide
nav_order: 1
---

# Getting started

## Conventions

- Components are subclasses of `ViewComponent::Base` and live in `app/components`. It's common practice to create and inherit from an `ApplicationComponent` that's a subclass of `ViewComponent::Base`.
- Component names end in -`Component`.
- Component module names are plural, as for controllers and jobs: `Users::AvatarComponent`
- Name components for what they render, not what they accept. (`AvatarComponent` instead of `UserComponent`)

## Installation

In `Gemfile`, add:

```ruby
gem "view_component"
```

## Quick start

Use the component generator to create a new ViewComponent.

The generator accepts a component name and a list of arguments:

```console
bin/rails generate view_component:component Example title

      invoke  test_unit
      create  test/components/example_component_test.rb
      create  app/components/example_component.rb
      create  app/components/example_component.html.erb
```

Available options to customize the generator are documented on the [Generators](/guide/generators.html) page.

## Implementation

A ViewComponent is a Ruby class that inherits from `ViewComponent::Base`:

```ruby
class ExampleComponent < ViewComponent::Base
  erb_template <<-ERB
    <span title="<%= @title %>"><%= content %></span>
  ERB

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

Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor.

Rendered in a view as:

```erb
<%= render(ExampleComponent.new(title: "my title")) do %>
  Hello, World!
<% end %>
```

Returning:

```html
<span title="my title">Hello, World!</span>
```

## `#with_content`

Since 2.31.0
{: .label }

String content can also be passed to a ViewComponent by calling `#with_content`:

```erb
<%= render(ExampleComponent.new(title: "my title").with_content("Hello, World!")) %>
```

## Rendering from controllers

It's also possible to render ViewComponents in controllers:

```ruby
def show
  render(ExampleComponent.new(title: "My Title"))
end
```

_Note: Content can't be passed to a component via a block in controllers. Instead, use `with_content`._

When using turbo frames with [turbo-rails](https://github.com/hotwired/turbo-rails), set `content_type` as `text/html`:

```ruby
def create
  render(ExampleComponent.new, content_type: "text/html")
end
```

### Rendering ViewComponents to strings inside controller actions

When rendering the same component multiple times for later reuse, use `render_in`:

```rb
class PagesController < ApplicationController
  def index
    # Doesn't work: triggers a `AbstractController::DoubleRenderError`
    # @reusable_icon = render IconComponent.new("close")

    # Doesn't work: renders the whole index view as a string
    # @reusable_icon = render_to_string IconComponent.new("close")

    # Works: renders the component as a string
    @reusable_icon = IconComponent.new("close").render_in(view_context)
  end
end
```

### Rendering ViewComponents outside of the view context

To render ViewComponents outside of the view context (such as in a background job, markdown processor, etc), instantiate a Rails controller:

```ruby
ApplicationController.new.view_context.render(MyComponent.new)
```