SlideShare a Scribd company logo
1 of 119
DRYing up
Views and Controllers
Layouts, partials, helpers, and filters
The Problem
The Problem


I said Rails was big on DRY (don’t repeat yourself)
The Problem


I said Rails was big on DRY (don’t repeat yourself)
But we are duplicating a lot of code so far!
Add an Article Form
A trivial page containing a form
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Add an Article</title>
  </head>
  <body>
    <h1>Add an Article</h1>
    <% form_for @article do |f| %>
      <%= f.error_messages %>
      <%= f.label :title %><br><%= f.text_field :title %><br>
      <%= f.label :body %><br><%= f.text_area :body %><br>
      <%= f.submit "Post Article" %>
    <% end %>
  </body>
</html>




Add an Article Form
A trivial page containing a form
Update Article Form
Nearly the exact same page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Update Article</title>
  </head>
  <body>
    <h1>Update Article</h1>
    <% form_for @article do |f| %>
      <%= f.error_messages %>
      <%= f.label :title %><br><%= f.text_field :title %><br>
      <%= f.label :body %><br><%= f.text_area :body %><br>
      <%= f.submit "Save Article" %>
    <% end %>
  </body>
</html>




Update Article Form
Nearly the exact same page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Update Article</title>
  </head>
  <body>
    <h1>Update Article</h1>
    <% form_for @article do |f| %>
      <%= f.error_messages %>
      <%= f.label :title %><br><%= f.text_field :title %><br>
      <%= f.label :body %><br><%= f.text_area :body %><br>
      <%= f.submit "Save Article" %>
    <% end %>
  </body>
</html>




Update Article Form
Nearly the exact same page
Solutions
Solutions
 Rails has many different tools to reduce repetition
Solutions
 Rails has many different tools to reduce repetition
   Layouts
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
   Helpers
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
   Helpers
   Filters
Solutions
 Rails has many different tools to reduce repetition
   Layouts
   Partials
   Helpers
   Filters
 Let’s take a look at what each of these is good for
Layouts
A tool for separating page header
and footer code
Repetitive HTML
Repetitive HTML


Layouts help you to handle header and footer code
Repetitive HTML


Layouts help you to handle header and footer code
  This is handy for HTML <head> … </head>
  sections and common site design code
Repetitive HTML


Layouts help you to handle header and footer code
  This is handy for HTML <head> … </head>
  sections and common site design code
Rails will render a layout for each page, if available
Layout Selection
                   class ArticlesController <
                       ApplicationController
                    # ...
                   end
Layout Selection
                       class ArticlesController <
Each controller can        ApplicationController
have it’s own layout    # ...
                       end
Layout Selection
                           class ArticlesController <
Each controller can            ApplicationController
have it’s own layout        # ...
                           end

If a controller doesn’t,
Rails will check parent
controllers
Layout Selection
                           class ArticlesController <
Each controller can            ApplicationController
have it’s own layout        # ...
                           end

If a controller doesn’t,
Rails will check parent
controllers
  application.html.erb
  is the easiest way to
  set a global layout
A Basic Layout
Just yield where you want to insert
the page content
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>My Blog</title>
  </head>
  <body>
    <%= yield %>
  </body>
</html>




A Basic Layout
Just yield where you want to insert
the page content
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>My Blog</title>
  </head>
  <body>
    <%= yield %>
  </body>
</html>




A Basic Layout
Just yield where you want to insert
the page content
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>My Blog</title>
  </head>
  <body>
    <%= yield %>
  </body>
</html>




A Basic Layout
Just yield where you want to insert
the page content
The Revised Add Form
This code is inserted into the layout by Rails
to create a full page
<h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_field :title %><br>
   <%= f.label :body %><br><%= f.text_area :body %><br>
   <%= f.submit "Post Article" %>
 <% end %>




The Revised Add Form
This code is inserted into the layout by Rails
to create a full page
The Revised Edit Form
There’s still some duplication,
but things are definitely improving
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_field :title %><br>
   <%= f.label :body %><br><%= f.text_area :body %><br>
   <%= f.submit "Save Article" %>
 <% end %>




The Revised Edit Form
There’s still some duplication,
but things are definitely improving
Fixing the Title
Fixing the Title

                   <% content_for :name, "Content" %>

                   <% content_for :name do %>
                     <script type="text/javascript"
                          charset="utf-8">
                       // ...
                     </script>
                   <% end %>




                   <%= yield :name %>
Fixing the Title
 content_for() can be
 used to pass content   <% content_for :name, "Content" %>

 between files           <% content_for :name do %>
                          <script type="text/javascript"
                               charset="utf-8">
                            // ...
                          </script>
                        <% end %>




                        <%= yield :name %>
Fixing the Title
 content_for() can be
 used to pass content     <% content_for :name, "Content" %>

 between files             <% content_for :name do %>
                            <script type="text/javascript"
                                 charset="utf-8">
 One file sets content,        // ...
                            </script>
 using a Ruby String or   <% end %>

 a block of HTML
                          <%= yield :name %>
Fixing the Title
 content_for() can be
 used to pass content       <% content_for :name, "Content" %>

 between files               <% content_for :name do %>
                              <script type="text/javascript"
                                   charset="utf-8">
 One file sets content,          // ...
                              </script>
 using a Ruby String or     <% end %>

 a block of HTML
 Another file yields to it   <%= yield :name %>


 by name
Set Title Content
Each page sets relevant title content
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <!-- .... -->




                              <% content_for :page_title, "Update Article" %>

                              <h1>Update Article</h1>
                              <!-- ... -->




Set Title Content
Each page sets relevant title content
Read the Title Content
The layout will now make use of the title content
if it exists
<title>
      <%= ["My Blog", yield(:page_title)].compact.join(" : ") %>
    </title>




Read the Title Content
The layout will now make use of the title content
if it exists
Content Sharing in Action
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
Content Sharing in Action

 We now have dynamic
 titles based on the
 page you are viewing
 content_for() is also
 handy for sidebars and
 other shared content
Partials
A tool for separating repeated
chunks of view code
Duplicate Form Fields
We need to remove more duplication,
but be pragmatic about what to leave
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_field :title %><br>
   <%= f.label :body %><br><%= f.text_area :body %><br>
   <%= f.submit "Save Article" %>
 <% end %>




Duplicate Form Fields
We need to remove more duplication,
but be pragmatic about what to leave
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_field :title %><br>
   <%= f.label :body %><br><%= f.text_area :body %><br>
   <%= f.submit "Save Article" %>
 <% end %>




Duplicate Form Fields
We need to remove more duplication,
but be pragmatic about what to leave
<h1>Update Article</h1>
 <% form_for @article do |f| %>
   <%= f.error_messages %>
   <%= f.label :title %><br><%= f.text_field :title %><br>
   <%= f.label :body %><br><%= f.text_area :body %><br>
   <%= f.submit "Save Article" %>
 <% end %>




Duplicate Form Fields
We need to remove more duplication,
but be pragmatic about what to leave
Shared HTML
Shared HTML

Any shared HTML can be placed into a “partial”
Shared HTML

Any shared HTML can be placed into a “partial”
  This is often used for form fields, and code that
  displays the details of an individual model
Shared HTML

Any shared HTML can be placed into a “partial”
  This is often used for form fields, and code that
  displays the details of an individual model
That partial can then be inserted into all needed places
Shared HTML

Any shared HTML can be placed into a “partial”
  This is often used for form fields, and code that
  displays the details of an individual model
That partial can then be inserted into all needed places
By convention, partial files begin with an _ in Rails (for
example: _article.html.erb)
_form.html.erb
I’ve moved the form fields into a separate HTML
file, starting with an _ so Rails knows it’s a partial
<%= f.error_messages %>
  <%= f.label :title %><br><%= f.text_field :title %><br>
  <%= f.label :body %><br><%= f.text_area :body %><br>




_form.html.erb
I’ve moved the form fields into a separate HTML
file, starting with an _ so Rails knows it’s a partial
<%= f.error_messages %>
  <%= f.label :title %><br><%= f.text_field :title %><br>
  <%= f.label :body %><br><%= f.text_area :body %><br>




_form.html.erb
I’ve moved the form fields into a separate HTML
file, starting with an _ so Rails knows it’s a partial
Forms render() the Partial
We can render() the partial anywhere we need
to reuse it and even pass variables into it
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "form", :f => f %>
   <%= f.submit "Post Article" %>
 <% end %>



                              <% content_for :page_title, "Update Article" %>

                              <h1>Update Article</h1>
                              <% form_for @article do |f| %>
                                <%= render "form", :f => f %>
                                <%= f.submit "Save Article" %>
                              <% end %>




Forms render() the Partial
We can render() the partial anywhere we need
to reuse it and even pass variables into it
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "form", :f => f %>
   <%= f.submit "Post Article" %>
 <% end %>



                              <% content_for :page_title, "Update Article" %>

                              <h1>Update Article</h1>
                              <% form_for @article do |f| %>
                                <%= render "form", :f => f %>
                                <%= f.submit "Save Article" %>
                              <% end %>




Forms render() the Partial
We can render() the partial anywhere we need
to reuse it and even pass variables into it
Partials for Models
Partials for Models

 Rails is smart about partials used to show a model
Partials for Models

 Rails is smart about partials used to show a model
   It can recognize them by name (more conventions!)
Partials for Models

 Rails is smart about partials used to show a model
   It can recognize them by name (more conventions!)
 It will render() the proper partial for a model or
 repeatedly render() the same partial for an entire
 collection of models
Partials for Models

 Rails is smart about partials used to show a model
   It can recognize them by name (more conventions!)
 It will render() the proper partial for a model or
 repeatedly render() the same partial for an entire
 collection of models
 A local variable is set holding the model, again named
 by the type
Manual Iteration
This code works, but Rails is smart enough to
help us if we follow some conventions
<h1>Articles</h1>
<ul>
  <% @articles.each do |article| %>
     <li>
        <%= link_to h(article.title), article_path(article)    %>
        <%= link_to "edit",         edit_article_path(article) %>
     </li>
  <% end %>
</ul>




Manual Iteration
This code works, but Rails is smart enough to
help us if we follow some conventions
_article.html.erb
I moved the Article display code into
an _article.html.erb partial
<li>
    <%= link_to h(article.title), article_path(article)    %>
    <%= link_to "edit",         edit_article_path(article) %>
 </li>




_article.html.erb
I moved the Article display code into
an _article.html.erb partial
<li>
    <%= link_to h(article.title), article_path(article)    %>
    <%= link_to "edit",         edit_article_path(article) %>
 </li>




_article.html.erb
I moved the Article display code into
an _article.html.erb partial
Partial Found by Name
Rails looks for an _article.html.erb to render()
the Article (matching the names)
<h1>Articles</h1>
         <ul>
           <% @articles.each do |article| %>
              <%= render article %>
           <% end %>
         </ul>




Partial Found by Name
Rails looks for an _article.html.erb to render()
the Article (matching the names)
One Step Further
Rails can even recognize a collection (an Array),
render()ing the partial once for each member
<h1>Articles</h1>
              <ul>
                <%= render @articles %>
              </ul>




One Step Further
Rails can even recognize a collection (an Array),
render()ing the partial once for each member
Helpers
A tool for separating out view logic
Where to Hide View Logic
Where to Hide View Logic

Views should be pretty dumb template filling code
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and needs to be
moved
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and needs to be
moved
  Move business logic into model methods
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and needs to be
moved
  Move business logic into model methods
  If it’s really view logic, write a helper method
Where to Hide View Logic

Views should be pretty dumb template filling code
Logic in your views is hard to maintain and needs to be
moved
  Move business logic into model methods
  If it’s really view logic, write a helper method
A helper is just a Ruby “Mixin” Rails adds to the view
These can be Combined
This is some logic though, so it belongs in a
helper method
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "form", :f => f %>
   <%= f.submit "Post Article" %>
 <% end %>



                              <% content_for :page_title, "Update Article" %>

                              <h1>Update Article</h1>
                              <% form_for @article do |f| %>
                                <%= render "form", :f => f %>
                                <%= f.submit "Save Article" %>
                              <% end %>




These can be Combined
This is some logic though, so it belongs in a
helper method
<% content_for :page_title, "Add an Article" %>

 <h1>Add an Article</h1>
 <% form_for @article do |f| %>
   <%= render "form", :f => f %>
   <%= f.submit "Post Article" %>
 <% end %>



                              <% content_for :page_title, "Update Article" %>

                              <h1>Update Article</h1>
                              <% form_for @article do |f| %>
                                <%= render "form", :f => f %>
                                <%= f.submit "Save Article" %>
                              <% end %>




These can be Combined
This is some logic though, so it belongs in a
helper method
Adding a Helper Method
I added this method to the Module (“Mixin”) in
app/helpers/application_helper.rb
module ApplicationHelper
           def page_title(title)
            content_for :page_title, title
            "<h1>#{title}</h1>"
           end
          end




Adding a Helper Method
I added this method to the Module (“Mixin”) in
app/helpers/application_helper.rb
Switch to Using the Helper
The views are a little cleaner now with the logic
moved to the helper
<%= page_title "Add an Article" %>

  <% form_for @article do |f| %>
    <%= render "form", :f => f %>
    <%= f.submit "Post Article" %>
  <% end %>




                                       <%= page_title "Update Article" %>

                                       <% form_for @article do |f| %>
                                         <%= render "form", :f => f %>
                                         <%= f.submit "Save Article" %>
                                       <% end %>




Switch to Using the Helper
The views are a little cleaner now with the logic
moved to the helper
Built-in Helpers
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currency methods
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currency methods
   Link and form builders
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currency methods
   Link and form builders
   Image, CSS, and JavaScript support methods
Built-in Helpers
 Rails comes with a ton of helpers, available in all views
   Date and time methods
   Number and currency methods
   Link and form builders
   Image, CSS, and JavaScript support methods
   …
An Article Show Page
Uses helpers to escape HTML, show time, and
add simple formatting (like paragraphs) here
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @article.body %>




An Article Show Page
Uses helpers to escape HTML, show time, and
add simple formatting (like paragraphs) here
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @article.body %>




An Article Show Page
Uses helpers to escape HTML, show time, and
add simple formatting (like paragraphs) here
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @article.body %>




An Article Show Page
Uses helpers to escape HTML, show time, and
add simple formatting (like paragraphs) here
<%= page_title h(@article.title) %>

 <p>posted <%= time_ago_in_words @article.created_at %> ago</p>

 <%= simple_format @article.body %>




An Article Show Page
Uses helpers to escape HTML, show time, and
add simple formatting (like paragraphs) here
Filters
A tool for separating repeated
chunks of controller code
Controller Duplication
It’s very common for show, edit, update, and
destroy to start with the same lookup code
class ArticlesController < ApplicationController
           # ...

           def show
            @article = Article.find(params[:id])
           end

           def edit
            @article = Article.find(params[:id])
           end

           def update
            @article = Article.find(params[:id])
            # ...
           end

           def destroy
            @article = Article.find(params[:id])
            # ...
           end
          end




Controller Duplication
It’s very common for show, edit, update, and
destroy to start with the same lookup code
class ArticlesController < ApplicationController
           # ...

           def show
            @article = Article.find(params[:id])
           end

           def edit
            @article = Article.find(params[:id])
           end

           def update
            @article = Article.find(params[:id])
            # ...
           end

           def destroy
            @article = Article.find(params[:id])
            # ...
           end
          end




Controller Duplication
It’s very common for show, edit, update, and
destroy to start with the same lookup code
Before or After an Action
Before or After an Action

 Rails has filters that can be run before or after an action
Before or After an Action

 Rails has filters that can be run before or after an action
 before_filter() is often used to lookup model instances
 or check access control
Before or After an Action

 Rails has filters that can be run before or after an action
 before_filter() is often used to lookup model instances
 or check access control
   You can choose to skip the action that follows
Before or After an Action

 Rails has filters that can be run before or after an action
 before_filter() is often used to lookup model instances
 or check access control
   You can choose to skip the action that follows
 after_filter() isn’t used as much, but it can be handy
 for statistics tracking
Using a before_filter()
You can specify a method to call before
certain actions are run
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]

        # ...

        def show
        end

        def edit
        end

        def update
         # ...
        end

        def destroy
         # ...
        end

        private

        def find_article
         @article = Article.find(params[:id])
        end
       end




Using a before_filter()
You can specify a method to call before
certain actions are run
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]

        # ...

        def show
        end

        def edit
        end

        def update
         # ...
        end

        def destroy
         # ...
        end

        private

        def find_article
         @article = Article.find(params[:id])
        end
       end




Using a before_filter()
You can specify a method to call before
certain actions are run
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]

        # ...

        def show
        end

        def edit
        end

        def update
         # ...
        end

        def destroy
         # ...
        end

        private

        def find_article
         @article = Article.find(params[:id])
        end
       end




Using a before_filter()
You can specify a method to call before
certain actions are run
class ArticlesController < ApplicationController
        before_filter :find_article, :only => %w[show edit update destroy]

        # ...

        def show
        end

        def edit
        end

        def update
         # ...
        end

        def destroy
         # ...
        end

        private

        def find_article
         @article = Article.find(params[:id])
        end
       end




Using a before_filter()
You can specify a method to call before
certain actions are run
Questions?
DRY up Your Views Lab
Your book has instructions on how to remove
the duplication in your code

More Related Content

What's hot

A quick guide to Css and java script
A quick guide to Css and  java scriptA quick guide to Css and  java script
A quick guide to Css and java scriptAVINASH KUMAR
 
Understanding JSP -Servlets
Understanding JSP -ServletsUnderstanding JSP -Servlets
Understanding JSP -ServletsGagandeep Singh
 
Html 5 in a big nutshell
Html 5 in a big nutshellHtml 5 in a big nutshell
Html 5 in a big nutshellLennart Schoors
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised contentMichael Peacock
 
HTL(Sightly) - All you need to know
HTL(Sightly) - All you need to knowHTL(Sightly) - All you need to know
HTL(Sightly) - All you need to knowPrabhdeep Singh
 
Learn html elements and structure cheatsheet codecademy
Learn html  elements and structure cheatsheet   codecademyLearn html  elements and structure cheatsheet   codecademy
Learn html elements and structure cheatsheet codecademynirmalamanjunath
 
Introduction to Sightly
Introduction to SightlyIntroduction to Sightly
Introduction to SightlyAnkit Gubrani
 
Build and deploy Python Django project
Build and deploy Python Django projectBuild and deploy Python Django project
Build and deploy Python Django projectXiaoqi Zhao
 
CSS Frameworks
CSS FrameworksCSS Frameworks
CSS FrameworksMike Crabb
 
JavaScript and jQuery Fundamentals
JavaScript and jQuery FundamentalsJavaScript and jQuery Fundamentals
JavaScript and jQuery FundamentalsBG Java EE Course
 
Web Design Basics
Web Design BasicsWeb Design Basics
Web Design BasicsCindy Royal
 
GDI Seattle Intermediate HTML and CSS Class 1
GDI Seattle Intermediate HTML and CSS Class 1GDI Seattle Intermediate HTML and CSS Class 1
GDI Seattle Intermediate HTML and CSS Class 1Heather Rock
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginningAnis Ahmad
 
HTML5 - Introduction
HTML5 - IntroductionHTML5 - Introduction
HTML5 - IntroductionDavy De Pauw
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2RORLAB
 
Web engineering and Technology
Web engineering and TechnologyWeb engineering and Technology
Web engineering and Technologychirag patil
 

What's hot (20)

A quick guide to Css and java script
A quick guide to Css and  java scriptA quick guide to Css and  java script
A quick guide to Css and java script
 
Introduction to Html5
Introduction to Html5Introduction to Html5
Introduction to Html5
 
Understanding JSP -Servlets
Understanding JSP -ServletsUnderstanding JSP -Servlets
Understanding JSP -Servlets
 
Html 5 in a big nutshell
Html 5 in a big nutshellHtml 5 in a big nutshell
Html 5 in a big nutshell
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised content
 
HTL(Sightly) - All you need to know
HTL(Sightly) - All you need to knowHTL(Sightly) - All you need to know
HTL(Sightly) - All you need to know
 
Learn html elements and structure cheatsheet codecademy
Learn html  elements and structure cheatsheet   codecademyLearn html  elements and structure cheatsheet   codecademy
Learn html elements and structure cheatsheet codecademy
 
Introduction to Sightly
Introduction to SightlyIntroduction to Sightly
Introduction to Sightly
 
Build and deploy Python Django project
Build and deploy Python Django projectBuild and deploy Python Django project
Build and deploy Python Django project
 
CSS Frameworks
CSS FrameworksCSS Frameworks
CSS Frameworks
 
JavaScript and jQuery Fundamentals
JavaScript and jQuery FundamentalsJavaScript and jQuery Fundamentals
JavaScript and jQuery Fundamentals
 
Web Design Basics
Web Design BasicsWeb Design Basics
Web Design Basics
 
ASP
ASPASP
ASP
 
AEM - Client Libraries
AEM - Client LibrariesAEM - Client Libraries
AEM - Client Libraries
 
GDI Seattle Intermediate HTML and CSS Class 1
GDI Seattle Intermediate HTML and CSS Class 1GDI Seattle Intermediate HTML and CSS Class 1
GDI Seattle Intermediate HTML and CSS Class 1
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
HTML5 - Introduction
HTML5 - IntroductionHTML5 - Introduction
HTML5 - Introduction
 
HTML 5 Basics Part One
HTML 5 Basics Part OneHTML 5 Basics Part One
HTML 5 Basics Part One
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2
 
Web engineering and Technology
Web engineering and TechnologyWeb engineering and Technology
Web engineering and Technology
 

Similar to DRYing Up Rails Views and Controllers

HTML CSS and Web Development
HTML CSS and Web DevelopmentHTML CSS and Web Development
HTML CSS and Web DevelopmentRahul Mishra
 
Django Templates
Django TemplatesDjango Templates
Django TemplatesWilly Liu
 
HTML Web design english & sinhala mix note
HTML Web design english & sinhala mix noteHTML Web design english & sinhala mix note
HTML Web design english & sinhala mix noteMahinda Gamage
 
html for beginners
html for beginnershtml for beginners
html for beginnersKIIZAPHILIP
 
The complete-html-cheat-sheet
The complete-html-cheat-sheetThe complete-html-cheat-sheet
The complete-html-cheat-sheetHARUN PEHLIVAN
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
引き出しとしてのDjango - SoozyCon7
引き出しとしてのDjango - SoozyCon7引き出しとしてのDjango - SoozyCon7
引き出しとしてのDjango - SoozyCon7makoto tsuyuki
 
Zen codingcheatsheet
Zen codingcheatsheetZen codingcheatsheet
Zen codingcheatsheetgoldenveizer
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Engine Yard
 
Caracteristicas Basicas De Htlm
Caracteristicas Basicas De HtlmCaracteristicas Basicas De Htlm
Caracteristicas Basicas De HtlmMaria S Rivera
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Ted Kulp
 

Similar to DRYing Up Rails Views and Controllers (20)

Html tutorial
Html tutorialHtml tutorial
Html tutorial
 
HTML CSS and Web Development
HTML CSS and Web DevelopmentHTML CSS and Web Development
HTML CSS and Web Development
 
Django Templates
Django TemplatesDjango Templates
Django Templates
 
HTML Web design english & sinhala mix note
HTML Web design english & sinhala mix noteHTML Web design english & sinhala mix note
HTML Web design english & sinhala mix note
 
html for beginners
html for beginnershtml for beginners
html for beginners
 
Lecture1and2
Lecture1and2Lecture1and2
Lecture1and2
 
The complete-html-cheat-sheet
The complete-html-cheat-sheetThe complete-html-cheat-sheet
The complete-html-cheat-sheet
 
The complete-html-cheat-sheet
The complete-html-cheat-sheetThe complete-html-cheat-sheet
The complete-html-cheat-sheet
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Html
HtmlHtml
Html
 
Html basics
Html basicsHtml basics
Html basics
 
引き出しとしてのDjango - SoozyCon7
引き出しとしてのDjango - SoozyCon7引き出しとしてのDjango - SoozyCon7
引き出しとしてのDjango - SoozyCon7
 
Zen codingcheatsheet
Zen codingcheatsheetZen codingcheatsheet
Zen codingcheatsheet
 
Hows Haml?
Hows Haml?Hows Haml?
Hows Haml?
 
Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel Rails Antipatterns | Open Session with Chad Pytel
Rails Antipatterns | Open Session with Chad Pytel
 
Caracteristicas Basicas De Htlm
Caracteristicas Basicas De HtlmCaracteristicas Basicas De Htlm
Caracteristicas Basicas De Htlm
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 

More from James Gray

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A KeynoteJames Gray
 
Regular expressions
Regular expressionsRegular expressions
Regular expressionsJames Gray
 
Counting on God
Counting on GodCounting on God
Counting on GodJames Gray
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your MindJames Gray
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)James Gray
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in RailsJames Gray
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And RenderingJames Gray
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with RailsJames Gray
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in RailsJames Gray
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on RailsJames Gray
 

More from James Gray (18)

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A Keynote
 
I Doubt That!
I Doubt That!I Doubt That!
I Doubt That!
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Counting on God
Counting on GodCounting on God
Counting on God
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your Mind
 
Unblocked
UnblockedUnblocked
Unblocked
 
Module Magic
Module MagicModule Magic
Module Magic
 
API Design
API DesignAPI Design
API Design
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Test Coverage in Rails
Test Coverage in RailsTest Coverage in Rails
Test Coverage in Rails
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And Rendering
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with Rails
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in Rails
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Ruby
RubyRuby
Ruby
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on Rails
 

Recently uploaded

EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfOverkill Security
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 

Recently uploaded (20)

EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

DRYing Up Rails Views and Controllers

  • 1. DRYing up Views and Controllers Layouts, partials, helpers, and filters
  • 3. The Problem I said Rails was big on DRY (don’t repeat yourself)
  • 4. The Problem I said Rails was big on DRY (don’t repeat yourself) But we are duplicating a lot of code so far!
  • 5. Add an Article Form A trivial page containing a form
  • 6. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Add an Article</title> </head> <body> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Post Article" %> <% end %> </body> </html> Add an Article Form A trivial page containing a form
  • 7. Update Article Form Nearly the exact same page
  • 8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Update Article</title> </head> <body> <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> </body> </html> Update Article Form Nearly the exact same page
  • 9. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Update Article</title> </head> <body> <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> </body> </html> Update Article Form Nearly the exact same page
  • 11. Solutions Rails has many different tools to reduce repetition
  • 12. Solutions Rails has many different tools to reduce repetition Layouts
  • 13. Solutions Rails has many different tools to reduce repetition Layouts Partials
  • 14. Solutions Rails has many different tools to reduce repetition Layouts Partials Helpers
  • 15. Solutions Rails has many different tools to reduce repetition Layouts Partials Helpers Filters
  • 16. Solutions Rails has many different tools to reduce repetition Layouts Partials Helpers Filters Let’s take a look at what each of these is good for
  • 17. Layouts A tool for separating page header and footer code
  • 19. Repetitive HTML Layouts help you to handle header and footer code
  • 20. Repetitive HTML Layouts help you to handle header and footer code This is handy for HTML <head> … </head> sections and common site design code
  • 21. Repetitive HTML Layouts help you to handle header and footer code This is handy for HTML <head> … </head> sections and common site design code Rails will render a layout for each page, if available
  • 22. Layout Selection class ArticlesController < ApplicationController # ... end
  • 23. Layout Selection class ArticlesController < Each controller can ApplicationController have it’s own layout # ... end
  • 24. Layout Selection class ArticlesController < Each controller can ApplicationController have it’s own layout # ... end If a controller doesn’t, Rails will check parent controllers
  • 25. Layout Selection class ArticlesController < Each controller can ApplicationController have it’s own layout # ... end If a controller doesn’t, Rails will check parent controllers application.html.erb is the easiest way to set a global layout
  • 26. A Basic Layout Just yield where you want to insert the page content
  • 27. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>My Blog</title> </head> <body> <%= yield %> </body> </html> A Basic Layout Just yield where you want to insert the page content
  • 28. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>My Blog</title> </head> <body> <%= yield %> </body> </html> A Basic Layout Just yield where you want to insert the page content
  • 29. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>My Blog</title> </head> <body> <%= yield %> </body> </html> A Basic Layout Just yield where you want to insert the page content
  • 30. The Revised Add Form This code is inserted into the layout by Rails to create a full page
  • 31. <h1>Add an Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Post Article" %> <% end %> The Revised Add Form This code is inserted into the layout by Rails to create a full page
  • 32. The Revised Edit Form There’s still some duplication, but things are definitely improving
  • 33. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> The Revised Edit Form There’s still some duplication, but things are definitely improving
  • 35. Fixing the Title <% content_for :name, "Content" %> <% content_for :name do %> <script type="text/javascript" charset="utf-8"> // ... </script> <% end %> <%= yield :name %>
  • 36. Fixing the Title content_for() can be used to pass content <% content_for :name, "Content" %> between files <% content_for :name do %> <script type="text/javascript" charset="utf-8"> // ... </script> <% end %> <%= yield :name %>
  • 37. Fixing the Title content_for() can be used to pass content <% content_for :name, "Content" %> between files <% content_for :name do %> <script type="text/javascript" charset="utf-8"> One file sets content, // ... </script> using a Ruby String or <% end %> a block of HTML <%= yield :name %>
  • 38. Fixing the Title content_for() can be used to pass content <% content_for :name, "Content" %> between files <% content_for :name do %> <script type="text/javascript" charset="utf-8"> One file sets content, // ... </script> using a Ruby String or <% end %> a block of HTML Another file yields to it <%= yield :name %> by name
  • 39. Set Title Content Each page sets relevant title content
  • 40. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <!-- .... --> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <!-- ... --> Set Title Content Each page sets relevant title content
  • 41. Read the Title Content The layout will now make use of the title content if it exists
  • 42. <title> <%= ["My Blog", yield(:page_title)].compact.join(" : ") %> </title> Read the Title Content The layout will now make use of the title content if it exists
  • 44. Content Sharing in Action We now have dynamic titles based on the page you are viewing
  • 45. Content Sharing in Action We now have dynamic titles based on the page you are viewing
  • 46. Content Sharing in Action We now have dynamic titles based on the page you are viewing
  • 47. Content Sharing in Action We now have dynamic titles based on the page you are viewing content_for() is also handy for sidebars and other shared content
  • 48. Partials A tool for separating repeated chunks of view code
  • 49. Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  • 50. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  • 51. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  • 52. <h1>Update Article</h1> <% form_for @article do |f| %> <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> <%= f.submit "Save Article" %> <% end %> Duplicate Form Fields We need to remove more duplication, but be pragmatic about what to leave
  • 54. Shared HTML Any shared HTML can be placed into a “partial”
  • 55. Shared HTML Any shared HTML can be placed into a “partial” This is often used for form fields, and code that displays the details of an individual model
  • 56. Shared HTML Any shared HTML can be placed into a “partial” This is often used for form fields, and code that displays the details of an individual model That partial can then be inserted into all needed places
  • 57. Shared HTML Any shared HTML can be placed into a “partial” This is often used for form fields, and code that displays the details of an individual model That partial can then be inserted into all needed places By convention, partial files begin with an _ in Rails (for example: _article.html.erb)
  • 58. _form.html.erb I’ve moved the form fields into a separate HTML file, starting with an _ so Rails knows it’s a partial
  • 59. <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> _form.html.erb I’ve moved the form fields into a separate HTML file, starting with an _ so Rails knows it’s a partial
  • 60. <%= f.error_messages %> <%= f.label :title %><br><%= f.text_field :title %><br> <%= f.label :body %><br><%= f.text_area :body %><br> _form.html.erb I’ve moved the form fields into a separate HTML file, starting with an _ so Rails knows it’s a partial
  • 61. Forms render() the Partial We can render() the partial anywhere we need to reuse it and even pass variables into it
  • 62. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> Forms render() the Partial We can render() the partial anywhere we need to reuse it and even pass variables into it
  • 63. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> Forms render() the Partial We can render() the partial anywhere we need to reuse it and even pass variables into it
  • 65. Partials for Models Rails is smart about partials used to show a model
  • 66. Partials for Models Rails is smart about partials used to show a model It can recognize them by name (more conventions!)
  • 67. Partials for Models Rails is smart about partials used to show a model It can recognize them by name (more conventions!) It will render() the proper partial for a model or repeatedly render() the same partial for an entire collection of models
  • 68. Partials for Models Rails is smart about partials used to show a model It can recognize them by name (more conventions!) It will render() the proper partial for a model or repeatedly render() the same partial for an entire collection of models A local variable is set holding the model, again named by the type
  • 69. Manual Iteration This code works, but Rails is smart enough to help us if we follow some conventions
  • 70. <h1>Articles</h1> <ul> <% @articles.each do |article| %> <li> <%= link_to h(article.title), article_path(article) %> <%= link_to "edit", edit_article_path(article) %> </li> <% end %> </ul> Manual Iteration This code works, but Rails is smart enough to help us if we follow some conventions
  • 71. _article.html.erb I moved the Article display code into an _article.html.erb partial
  • 72. <li> <%= link_to h(article.title), article_path(article) %> <%= link_to "edit", edit_article_path(article) %> </li> _article.html.erb I moved the Article display code into an _article.html.erb partial
  • 73. <li> <%= link_to h(article.title), article_path(article) %> <%= link_to "edit", edit_article_path(article) %> </li> _article.html.erb I moved the Article display code into an _article.html.erb partial
  • 74. Partial Found by Name Rails looks for an _article.html.erb to render() the Article (matching the names)
  • 75. <h1>Articles</h1> <ul> <% @articles.each do |article| %> <%= render article %> <% end %> </ul> Partial Found by Name Rails looks for an _article.html.erb to render() the Article (matching the names)
  • 76. One Step Further Rails can even recognize a collection (an Array), render()ing the partial once for each member
  • 77. <h1>Articles</h1> <ul> <%= render @articles %> </ul> One Step Further Rails can even recognize a collection (an Array), render()ing the partial once for each member
  • 78. Helpers A tool for separating out view logic
  • 79. Where to Hide View Logic
  • 80. Where to Hide View Logic Views should be pretty dumb template filling code
  • 81. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved
  • 82. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved Move business logic into model methods
  • 83. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved Move business logic into model methods If it’s really view logic, write a helper method
  • 84. Where to Hide View Logic Views should be pretty dumb template filling code Logic in your views is hard to maintain and needs to be moved Move business logic into model methods If it’s really view logic, write a helper method A helper is just a Ruby “Mixin” Rails adds to the view
  • 85. These can be Combined This is some logic though, so it belongs in a helper method
  • 86. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> These can be Combined This is some logic though, so it belongs in a helper method
  • 87. <% content_for :page_title, "Add an Article" %> <h1>Add an Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <% content_for :page_title, "Update Article" %> <h1>Update Article</h1> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> These can be Combined This is some logic though, so it belongs in a helper method
  • 88. Adding a Helper Method I added this method to the Module (“Mixin”) in app/helpers/application_helper.rb
  • 89. module ApplicationHelper def page_title(title) content_for :page_title, title "<h1>#{title}</h1>" end end Adding a Helper Method I added this method to the Module (“Mixin”) in app/helpers/application_helper.rb
  • 90. Switch to Using the Helper The views are a little cleaner now with the logic moved to the helper
  • 91. <%= page_title "Add an Article" %> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Post Article" %> <% end %> <%= page_title "Update Article" %> <% form_for @article do |f| %> <%= render "form", :f => f %> <%= f.submit "Save Article" %> <% end %> Switch to Using the Helper The views are a little cleaner now with the logic moved to the helper
  • 93. Built-in Helpers Rails comes with a ton of helpers, available in all views
  • 94. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods
  • 95. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods
  • 96. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods Link and form builders
  • 97. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods Link and form builders Image, CSS, and JavaScript support methods
  • 98. Built-in Helpers Rails comes with a ton of helpers, available in all views Date and time methods Number and currency methods Link and form builders Image, CSS, and JavaScript support methods …
  • 99. An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  • 100. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  • 101. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  • 102. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  • 103. <%= page_title h(@article.title) %> <p>posted <%= time_ago_in_words @article.created_at %> ago</p> <%= simple_format @article.body %> An Article Show Page Uses helpers to escape HTML, show time, and add simple formatting (like paragraphs) here
  • 104. Filters A tool for separating repeated chunks of controller code
  • 105. Controller Duplication It’s very common for show, edit, update, and destroy to start with the same lookup code
  • 106. class ArticlesController < ApplicationController # ... def show @article = Article.find(params[:id]) end def edit @article = Article.find(params[:id]) end def update @article = Article.find(params[:id]) # ... end def destroy @article = Article.find(params[:id]) # ... end end Controller Duplication It’s very common for show, edit, update, and destroy to start with the same lookup code
  • 107. class ArticlesController < ApplicationController # ... def show @article = Article.find(params[:id]) end def edit @article = Article.find(params[:id]) end def update @article = Article.find(params[:id]) # ... end def destroy @article = Article.find(params[:id]) # ... end end Controller Duplication It’s very common for show, edit, update, and destroy to start with the same lookup code
  • 108. Before or After an Action
  • 109. Before or After an Action Rails has filters that can be run before or after an action
  • 110. Before or After an Action Rails has filters that can be run before or after an action before_filter() is often used to lookup model instances or check access control
  • 111. Before or After an Action Rails has filters that can be run before or after an action before_filter() is often used to lookup model instances or check access control You can choose to skip the action that follows
  • 112. Before or After an Action Rails has filters that can be run before or after an action before_filter() is often used to lookup model instances or check access control You can choose to skip the action that follows after_filter() isn’t used as much, but it can be handy for statistics tracking
  • 113. Using a before_filter() You can specify a method to call before certain actions are run
  • 114. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  • 115. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  • 116. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  • 117. class ArticlesController < ApplicationController before_filter :find_article, :only => %w[show edit update destroy] # ... def show end def edit end def update # ... end def destroy # ... end private def find_article @article = Article.find(params[:id]) end end Using a before_filter() You can specify a method to call before certain actions are run
  • 119. DRY up Your Views Lab Your book has instructions on how to remove the duplication in your code

Editor's Notes