-
Notifications
You must be signed in to change notification settings - Fork 442
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to define templates that take parameters
- Loading branch information
Showing
9 changed files
with
101 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# 1. Allow multiple templates | ||
|
||
Date: 2021-10-13 | ||
|
||
## Status | ||
|
||
Proposed. | ||
|
||
## Context | ||
|
||
As components become larger (for example, because you are implementing a whole page), it becomes | ||
useful to be able to extract sections of the view to a different file. ActionView has | ||
partials, and ViewComponent lacks a similar mechanism. | ||
|
||
ActionView partials have the problem that their interface is not introspectable. Data | ||
may be passed into the partial via ivars or locals, and it is impossible to know | ||
which without actually opening up the file. Additionally, partials are globally | ||
invocable, thus making it difficult to detect if a given partial is in use or not, | ||
and who are its users. | ||
|
||
## Considered Options | ||
|
||
* Introduce component partials to components | ||
* Keep components as-is | ||
|
||
### Component partials | ||
|
||
Allow multiple ERB templates available within the component, and make it possible to | ||
invoke them from the main view.Templates are compiled to methods in the format `render_#{template_basename}(locals = {})` | ||
|
||
**Pros:** | ||
* Better performance due to lack of GC pressure and object creation | ||
* Reduces the number of components needed to express a more complex view. | ||
* Extracted sections are not exposed outside the component, thus reducing component library API surface. | ||
|
||
**Cons:** | ||
* Another concept for users of ViewComponent to learn and understand. | ||
* Components are no longer the only way to encapsulate behavior. | ||
|
||
### Keeping components as-is | ||
|
||
**Pros:** | ||
* The API remains simple and components are the only way to encapsulate behavior. | ||
* Encourages creating reusable sub-components. | ||
|
||
**Cons:** | ||
* Extracting a component results in more GC and intermediate objects. | ||
* Extracting a component may result in tightly coupled but split components. | ||
* Creates new public components thus expanding component library API surface. | ||
|
||
## Decision | ||
|
||
We will allow having multiple templates in the sidecar asset. Each asset will be compiled to | ||
it's own method `render_<template_name>`. | ||
|
||
## Consequences | ||
|
||
This implementation has better performance characteristics over both an extracted component | ||
and ActionView partials, because it avoids creating intermediate objects, and the overhead of | ||
creating bindings and `instance_exec`. | ||
Having explicit arguments makes the interface explicit. | ||
|
||
TODO: The following are consequences of the current approach, but the approach might be extended | ||
to avoid them: | ||
|
||
The interface to render a sidecar partial would be a method call, and depart from the usual | ||
`render(*)` interface used in ActionView. | ||
|
||
The generated methods are only invokable via keyword arguments | ||
|
||
The generated methods cannot have arguments with default values. | ||
|
||
The generated methods are public, and thus could be invoked by a third party. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 1 addition & 12 deletions
13
test/sandbox/app/components/multiple_templates_component.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
class MultipleTemplatesComponent < ViewComponent::Base | ||
def initialize(mode:) | ||
@mode = mode | ||
|
||
def initialize | ||
@items = ["Apple", "Banana", "Pear"] | ||
end | ||
|
||
def call | ||
case @mode | ||
when :list | ||
call_list | ||
when :summary | ||
call_summary | ||
end | ||
end | ||
end |
2 changes: 1 addition & 1 deletion
2
test/sandbox/app/components/multiple_templates_component/list.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
<ul> | ||
<ul data-number="<%= locals[:number] %>"> | ||
<% @items.each do |item| %> | ||
<li><%= item %></li> | ||
<% end %> | ||
|
4 changes: 4 additions & 0 deletions
4
...sandbox/app/components/multiple_templates_component/multiple_templates_component.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div class="container"> | ||
<%= render_summary string: "foo" %> | ||
<%= render_list number: 1 %> | ||
</div> |
2 changes: 1 addition & 1 deletion
2
test/sandbox/app/components/multiple_templates_component/summary.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
<div>The items are: <%= @items.to_sentence %></div> | ||
<div>The items are: <%= @items.to_sentence %>, <%= locals[:string] %></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters