Why Phlex?
The frontend that ships with Rails starts to become a mess as views grow in complexity and size. This can lead to a tangled web of templates, partials, helpers, and code that is difficult to maintain, extend, and reuse throughout the application.
Partials in Rails have limits
Today when building applications in Rails, the way to βDRY upβ your views is to use partials. However, partials have their own set of limitations and can become cumbersome to manage as your application grows in complexity, especially when partials are rendered inside of partials.
locals and global context cause bugs
π Unlock content
Purchase this course to unlock this video, source code, and content.
ββββ β βββββ βββββββ β βββββββ βββββββββ β βββββ ββββββ ββ ββββββ ββ βββββ ββββββββ ββββββββ ββ β ββββββ βββββββ β βββββ βββββ ββ ββββ ββββ ββββββββ βββ βββββ ββ βββββββββ βββ ββ β ββββββββ βββ β βββ ββ βββββββββββ
Helpers can enforce required and optional arguments
βββββββ βββββββ ββββ βββββ ββββββββ ββ βββββββ βββββββββ ββ ββββββββ ββ βββββββββ ββ ββ ββββ βββββββ ββββ βββββ βββββββββ ββββ ββββ βββββ ββ βββββββ ββ βββββββ β βββββββ βββββββββ
def ββββββββββββ(ββββ:)
β ββββββ βββββββββ ββ βββββββββ βββββββ ββββ β ββββ
βββββββββββ :div, class: "user" do
βββββββββββ :h1, ββββ.ββββ
βββββββββββ :p, ββββ.βββββ
end
end
Strict partials are a hack to enforce arguments
ββ ββββββ βββββββ β ββββββββββ βββ ββββββββ βββββββββββ ββββββ βββββββ βββββββββ ββββββ βββ ββββββ ββββββββββ ββ βββ βββββ βββββββ ββ ββββ ββ βββββββ ββββ βββββ
βββ ββββββββββββββββββββββββ ββ
βββ ββββββββ βββββββ ββ
ββββ class="user"β
ββββ<%= ββββ.ββββ %>βββββ
βββ<%= ββββ.βββββ %>ββββ
ββββββ
Partials canβt render multiple blocks
ββββββββ ββββββββββ ββββ βββββββ ββββββββ ββββββββ ββββ ββββββββ βββββ βββββββββ βββ ββββββββ βββ βββ ββββ ββ βββββββ β βββββ βββ β ββββ βββ β ββββββββββ ββββββ βββββ ββββ βββββββββ ββββ βββββ
<%= ββββββ "panel" do %>
<%= ββ.βββββ do %>
ββ href="#panel-1"βPanelββββ
<% end %>
<% ββ.ββββ do %>
βββββββ
<% end %>
<% end %>
ββββ ββββββββ ββββ βββ ββ βββ βββ ββ βββββ βββ βββββ βββββββ ββββββββββ ββββ ββ βββ ββββββββ ββ β ββββββ ββββ ββββββ β βββββ ββββ ββββββ βββ βββ ββββ ββ ββββββββββ
Phlex solves these problems
βββββββββ βββββββββ ββ βββββ βββββββ β ββββ ββββββ ββββββββ βββββββ βββ ββββββ βββ βββββ ββββββββ βββββ ββ ββββ ββββ ββββββ βββββ ββββ ββββββ ββ βββββ ββββββ βββββ βββββ ββ βββββ βββ βββ ββββ ββββββββββ βββ ββββββββ ββ βββββββββββββ βββββ ββ ββββββββββββββ
class Components::User < ββββββββββ::ββββ
def ββββββββββ(ββββ:)
βββββ = ββββ
end
def βββββββββββββ
βββ(class: "user"){
ββ { βββββ.ββββ }
p { βββββ.βββββ }
}
end
end
ββββ ββ βββ βββββ ββ βββ ββ βββββββββ
<%= ββββββ ββββ.βββ(user: βββββ) %>
Everything is Ruby
ββββ β βββββ βββββ ββ ββββββ β βββββββ ββ βββ ββ ββββββββββ ββββββββ βββββ β ββββββββ βββββββββ ββββ βββββ ββββ ββ βββββ ββββ ββ βββββββ ββββ β βββββ ββ βββ βββββββ βββββββ βββ ββββ ββ βββ β βββββββββ βββ ββ βββββββββ β βββββββββ
class Notification < βββββββββ::ββββ
def ββββββββββ(βββββ:)
ββββββ = βββββ
end
def βββββββββββββ
ββ { ββββββ }
yield
end
def βββββββ
βββ(class: "message-body"){ yield }
end
end
ββββββ ββββββββββββ.βββ(title: "This is just Ruby") do
p { "That means you can use modules, classes, methods, and more to organize your code." }
end
Refactoring HTML is refactoring Ruby
ββ βββ ββββ ββ ββ ββββ ββββ βββββββ ββββ ββββββββ βββ βββ ββββββ βββββββ βββ βββββββ ββββ ββββββββ ββββββββ ββββββββ ββββββ βββ βββββββ βββββββ ββββ ββββ ββββ βββββ
Native interfaces
βββββ ββββββββ βββ βββββββββ ββββ ββ ββββββββ ββββββββββ ββ βββ ββββ β βββββββ βββ ββββββ ββ ββββ ββ β βββββ ββββ βββ ββββββ βββββ βββββββ ββββ ββββββ ββββββ ββββββ βββββββ β ββββββ ββββββββ ββββββ ββββββββ βββ βββββ βββββββ ββ βββ βββββ βββββ βββ βββββββ ββββ β ββββ βββββββββββ ββββββββββββββ ββ β ββββ ββββββ βββββ βββ ββββββ βββ ββββ ββββββββ
βββββ ββββββββββ ββ βββββ ββ βββββ βββ βββ βββ ββββββ βββββββββββ ββββββββ βββ βββββββ ββ βββββββ βββββ ββββββββββ βββββββ ββββ ββββ βββββββββββ
Easier to reason through stateful views
βββββ βββββ β ββββββ ββββββββ ββββ ββββ β βββββββββ ββββ βββββββ β ββββ ββββββ βββ βββββ ββββββ β ββ ββββ ββββββββ β ββββββββ ββ ββββββ β ββββββββ β ββββββ ββββ ββββββββ ββββββββββββββββββββ ββββββ βββ βββββ βββββββββββ βββββββββ
Organize components with namespaces
ββββββ ββ βββββββββ ββββββββββ ββββββββββ ββ βββββ ββ ββββββββββββ β ββββββββββββββββ βββββ βββββββββ βββββ ββ βββββ ββ βββββββββββββββββββββββββββββββ ββββ β ββββββββ βββββββββ βββββ βββ ββ βββββββββββββ βββββ βββ ββββ ββ βββ βββββββββββββββββββββββ βββββββββ ββ βββ ββββββββββββββββββββββββββββββββββββ βββββ
Phlex compared to ViewComponent
βββββββββββββ ββββ ββ βββ ββ βββββββββββββ ββββ βββββ βββ βββββββββββ βββ βββββ ββ ββββ βββ ββ ββββββ βββ βββββ βββββββββββ ββββ βββ βββββ βββββ βββββββββ βββββββ ββββ βββ ββββ ββββββ
ViewComponent splits out views into separate files
βββββββββββββ βββββββββ βββββ ββββ ββββ βββ βββββ βββ βββββ ββββ ββββ ββββββ
β βββββββββββββββββββββββββββββββββββ
class MessageComponent < βββββββββββββ::ββββ
def ββββββββββ(name:)
βββββ = name
end
end
ββββ ββ ββ βββ βββββ
βββ βββββββββββββββββββββββββββββββββββββββββ ββ
ββββHello, <%= βββββ %>!βββββ
ββ βββββββ
<%= render MessageComponent.new(name: "World") %>
Phlex has views in one file
ββββ βββββ βββββββ ββ ββββββββββββββ βββ βββββ βββ βββββ ββ βββ ββββ βββ ββββ ββ βββββββ ββ βββββ
class Components::Message < ββββββββββ::ββββ
def ββββββββββ(name:)
βββββ = name
end
def βββββββββββββ
ββ { "Hello, #{βββββ}!" }
end
end
βββββββββ βββββ βββββββ ββ ββββββββββββββ βββ βββββ βββ βββββ ββ βββ ββββ βββ ββββ ββ βββββββ ββ βββββ
<%= ββββββ ββββββββββ::βββββββ.βββ(name: "World") %>
βββββββββββββ ββββ ββββ β βββ ββ ββββββ βββββββββ ββββββ ββ βββ βββββ βββ ββββ βββ βββ βββββββ βββββββββ
Slots and blocks
ββββ βββββ βββββββ ββ ββ β βββββββββ ββββββββββ βββββ βββ ββββ ββ ββββββ ββββββ ββββββ ββ ββββ ββββββ βββββββ ββββββββββ βββββ βββββββ βββ βββββββββββββ βββ βββββ ββ βββ
ViewComponent slots
βββ βββββββ ββββ βββ βββββββββββββ βββββ ββββ βββββ ββ βββββ
β βββββββββββββββββ
class BlogComponent < βββββββββββββ::ββββ
βββββββββββ :header
ββββββββββββ :posts
end
ββββ βββββ βββ βββ βββββ βββ ββββ ββββββββ ββββββ ββββββ βββ βββββββββββ βββββ βββββββββ
βββ βββββββββββββββββββββββ ββ
ββββ<%= ββββββ %>βββββ
<% βββββ.ββββ do |ββββ| %>
<%= ββββ %>
<% end %>
βββ βββ ββββββββββββ βββββ βββββββββ
βββ ββββββββββββββ ββ
<%= ββββββ βββββββββββββ.βββ do |βββββββββ| %>
<% βββββββββ.βββββββββββ do %>
<%= βββββββ "My blog", βββββββββ %>
<% end %>
<% ββββββββ.βββ.ββββ do |βββββββββ| %>
<% βββββββββ.βββββββββ do %>
<%= βββββββ βββββββββ.ββββ, βββββββββ.βββ %>
<% end %>
<% end %>
<% end %>
ββββ βββββ βββ βββββββββ βββββ
ββββββ href="/"βMy blogβββββββββ
ββ href="/blog/first-post"βFirst postββββ
ββ href="/blog/second-post"βSecond postββββ
β ββββ βββββββββββββ βββββ ββ ββ β βββ βββββββ βββ ββββββββββ ββ ββββ ββββββ ββ βββ βββββ βββββ βββ β ββββ βββββββ ββββββ βββ ββββββ
Phlex slots are Ruby blocks
βββββ βββββ β βββββββββ ββββββββ ββ βββββ ββββ βββββββββββββ ββ ββββββ ββββ ββββ βββββββ ββββ βββββ βββ ββββββ ββββ ββββ ββββββββ
class Components::Blog < ββββββββββ::ββββ
def ββββββββββ(βββββ:)
ββββββ = βββββ
end
def ββββββ(&) = ββ(&)
def ββββ(&) = β(href: βββββββββ.βββ, &)
def ββββββββ = yield self
end
ββββ ββ ββββββ βββ βββββββββ ββββ βββ ββββββββββββββ βββββ
<%= ββββββ ββββββββββ::ββββ.βββ do |ββ|
ββ.βββββ { βββββββ "My blog", βββββββββ }
ββββββββ.βββ.ββββ do |βββββββββ|
ββ.ββββ { βββββββ βββββββββ.ββββ, βββββββββ.βββ}
end
end %>
ββββ βββββ βββ ββββ βββββ
ββββMy blogβββββ
ββ href="/blog/first-post"βFirst postββββ
ββ href="/blog/second-post"βSecond postββββ
Phlex vs ViewComponent
βββ ββββ βββββ ββββ ββββββ βββ βββββ βββββ βββ ββββββ βββ βββββββ
| Category | Phlex | ViewComponent | Rails Partials (ERB/HAML) |
|---|---|---|---|
| ββββββ β βββββββββββ | ββββ ββββ ββββββ ββββ βββββββ βββββββ βββ βββββββββββ | βββ βββββββββ ββ ββββ ββββββ ββββ βββββββ βββ βββββββββββ | ββββββ βββ ββ βββββ βββββββ βββ βββββ ββββββββββ βββ ββββββ |
| βββββββββββ | ββββ ββββ βββββββ ββ βββββ ββββββββ βββββββ βββ ββββββ ββββ ββ βββββ | βββββ ββββββββ βββββββββ βββ ββββββββ ββββββββ | βββββββ βββββββ ββββ ββββββ ββββββ βββ ββββββββββββ ββββββββ |
| ββββ ββββββ β ββββββββ | ββββ βββββββ ββ βββββββ βββββ ββββββ ββββ ββββ βββββββ | ββββ βββββββ βββ βββββ ββββ βββββββ ββββββββββ ββββ ββββββ | ββββ ββ βββββ βββββββ ββββ βββ ββ ββββββββββ |
| βββββ βββββββββββ | βββββ ββββ ββββββββββββ ββββ βββββββββ βββββββββ | ββββββ ββββββββββ ββββ ββββββββ βββββ βββ ββββββββ | ββββββ ββ βββββ ββββ βββββββ ββββββ |
| ββββββββ β ββββββ βββββββββ | βββββ βββββββ βββββββ βββββββ βββββββββ ββββββ | βββββ βββββ ββββββββ βββ ββββββββ ββββββββββββ | βββββ ββββββββ ββββββ ββββββ ββ βββββββββ |
| βββββββββββββ | βββββ βββββ ββββββββββββ ββββββββ βββββββ βββ ββββββββββββ | βββββββββββ βββββββ βββββ βββ ββββββββββββ | ββββββ ββ ββββββββ ββββββ ββββ ββββ ββββββ ββββββββ βββ βββββββ |
| βββββββ | βββββ ββββ βββββ ββ ββββββββ βββββββ | βββββββββ ββββ βββββββ βββ βββββββ ββββββββ | ββββββββ βββββββ βββββ βββββββ ββ ββββ ββββββ |
| βββββββ | ββββββββ ββββββββ βββββββ ββ ββββββ βββββββ ββββββ | βββββ ββ βββ βββββββββ ββββββββ | ββββββββ βββββ ββββββββ ββββββββ βββββ βββββββ |
| βββββββ β ββ | ββββ ββββββββ ββββ βββββββ β βββ βββ βββββββ βββ ββββββββββ | ββββββ βββββ βββββββ βββ βββββββ βββ βββββββββββ | ββββββ ββββββ βββββββββββββ βββ βββββββ βββββββββ ββββββββ |
| βββββββ β βββββββββ | βββ ββββββ ββββββ ββ βββββββ ββββββ | ββββ βββββββββ ββββ ββββββββ βββ ββββββββββ ββββ ββββββββ | ββββββ βββββββββ ββββββββββ βββββββ βββββ βββββ |
| βββββ β ββββββββ βββββββββββ | βββ ββββ ββββββββββ ββββββββ ββ ββββ ββββ | βββββ ββ βββββββ βββ βββββββββββ βββ ββ ββββββ | βββββ βββ ββββββ ββββ ββββββββββ ββ βββββ |
| βββββ βββββββββ | βββββ ββ ββββββ ββββββ ββββ ββββ ββββββ ββββββ | βββββββββ βββ ββββββ ββββββ βββ βββββββββ | ββββββ ββββ ββββ ββββββββββ |
| βββββββββ β βββββββββ | ββββ ββββββββ βββββ βββββ ββββββ βββββββββββ | βββββ βββββββββ ββββββ ββ βββββββ | βββββββββββ βββ ββββββ ββββ βββ βββ βββββββββ |
| βββββββββββ | βββββββββ βββββββββ βββββ ββ βββββββ βββββ βββ βββββββ | βββββ βββββ | βββββ βββββ |
| ββββββββ βββββ | ββββ ββ βββ ββββ βββββ βββββββ βββ ββ ββββββ | βββββββββ ββββββββ βββββββββββββ ββββββ βββββββββ βββ ββββββββββ | βββββββ βββββ ββββ βββββ ββββββββββ βββββββ ββββ ββββ |
| ββββ βββ | ββββββββββββ ββββββββββββ βββ ββββ ββββ βββββββββββ | ββββ ββββββββββ βββββββββ βββββββ βββ ββββββββββ | βββββ ββββββββββ βββ ββββββ βββββ |
ββββββββββ ββ βββββ ββββ ββ βββββ βββββ ββββ βββ ββββ βββββββββ ββββ βββ ββββ βββββ ββ βββββββββ ββββββββββββ ββββ ββββββββββββ βββ βββββ ββββββββ
βββ βββ ββββββ βββββ βββββ βββββββ β ββββββ βββββββ ββββββ βββββββ βββββ