Advanced Views with Erector A builder view framework Jeff Dean
Dec 07, 2014
Advanced Views with Erector
A builder view framework
Jeff Dean
ERB views kinda suck
Make you work more
No encapsulation
Refactoring can be hard
We need something that...
Requires less work
Respects encapsulation
Is testable in isolation
Erector to the rescue!
Views are classes
Views are classes
•Modular decomposition
•Inheritance (nested layouts)
•Consistent semantics
Views are classesclass Views::Articles::Show < Erector::RailsWidget
def content div :class => "content" do p "Hello <script> World!", :class => "sidebar" end end
end
Does the right thing
Does the right thing
•Escapes HTML
•Auto-closes tags
•You control indenting and whitespace
Does the right thing
class Views::Articles::Show < Erector::RailsWidget def content div :class => "content" do p "Hello <script> World!", :class => "sidebar" end endend
# <div class="content"># <p class="sidebar">Hello <script> World!</p># </div>
ERB Refactoring
<!-- app/views/articles/show.html.erb -->
<%=h truncate(article.title, :length => 10) %>
<!-- app/views/articles/show.html.erb -->
<%=h display_name(article) %>
# app/helpers/articles.rb
def display_name(article) truncate(article.title, :length => 10)end
<!-- app/views/articles/show.html.erb -->
<%=h article_display_name(article) %>
# app/helpers/articles.rb
def article_display_name(article) truncate(article.title, :length => 10)end
<!-- app/views/articles/show.html.erb -->
<%=h article_display_name(article) %>
# app/helpers/articles.rb
def article_display_name(article) truncate(article.title, :length => 10)end
<!-- app/views/articles/show.html.erb -->
<%= article_display_name(article) %>
# app/helpers/articles.rb
def article_display_name(article) content_tag :span, h(truncate(article.title, :length => 10)), :title => article.titleend
<!-- app/views/articles/show.html.erb -->
<%= article_display_name(article) %>
# app/helpers/articles.rb
def article_display_name(article) content_tag :span, h(truncate(article.title, :length => 10)), :title => article.titleend
<!-- app/views/articles/show.html.erb -->
<%= article_display_name(article) %>
# app/helpers/articles.rb
def article_display_name(article) content_tag :span, h(truncate(article.title, :length => 10)), :title => article.titleend
<!-- app/views/articles/show.html.erb -->
<%= render("articles/title", :title => article) %>
<!-- app/views/_title.html.erb -->
<span title="<%= article.title %>"> <%=h truncate(article.title, :length => 10) %></span>
<!-- app/views/articles/show.html.erb -->
<%= render("articles/title", :title => article) %>
<!-- app/views/_title.html.erb -->
<span title="<%= article.title %>"> <%=h truncate(article.title, :length => 10) %></span>
Erector Refactoring
# app/views/articles/show.rb
class Views::Articles::Show < Erector::RailsWidget def content text do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Erector::RailsWidget def content display_name end
private def display_name text do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Erector::RailsWidget def content display_name end
private def display_name text do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Erector::RailsWidget def content display_name end
private def display_name span :title => @article.title do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Erector::RailsWidget def content display_name end
private def display_name span :title => @article.title do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Views::Articles::Base def content display_name endend
# app/views/articles/base.rb
class Views::Articles::Base < Erector::RailsWidget def display_name span :title => @article.title do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Views::Articles::Base def content display_name endend
# app/views/articles/base.rb
class Views::Articles::Base < Erector::RailsWidget def display_name span :title => @article.title do truncate @article.title, :length => 10 end endend
# app/views/articles/show.rb
class Views::Articles::Show < Views::Articles::Base def content display_name endend
# app/views/articles/base.rb
class Views::Articles::Base < Erector::RailsWidget def display_name span :title => @article.title do truncate @article.title, :length => 10 end endend
What’s next?
more rails helpers
better performance
rails 3
Questions