Passing Data

& Bootstrap

How the Pieces Fit Together

Like a Boss

Controller - The Boss

A controller is a middle man between models and views. Its job is to parse requests, interact with models, and create view outputs. 

 

View Master

View - The Presentation

The presentation is handled by views.  It's the surface layer that is encountered by users.  Views are basically page templates.  Ruby and html are combined to make them dynamic. 

Travel App

$ rails new travel

Let's generate a brand spankin' new Rails application called travel

$ cd travel

We'll change directories into the travel folder, start our server and browse our localhost.

$ rails s
$ rails g controller Welcome index about

Create a Controller

In terminal let's leave our server running in one tab and open another to run some commands. We'll generate a controller: Welcome which contains two actions:  index and about.

Notice all the files that were generated after running this command. Open up Sublime and let's take a look at some of them.

Welcome Controller

You now have a controller called WelcomeController.rb

app/controllers/welcome_controller.rb
class WelcomeController < ApplicationController
  def index
  end

  def about
  end
end

WelcomeController inherits all the properties of the ApplicationController and provides two actions to work with. These actions correspond to two views: index.html.erb and about.html.erb.

Enjoy the View(s)

Rails generated a few views in the form of combined html & embedded ruby files. It's up to you to modify the code to make it more presentable.

<h1>Welcome#index</h1>
<p>Find me in app/views/welcome/index.html.erb</p>
<h1>Welcome#about</h1>
<p>Find me in app/views/welcome/about.html.erb</p>
app/views/welcome/index.html.erb
app/views/welcome/about.html.erb
<h1>Welcome to my Travel Site</h1>
<p>This is my very awesome travel site.</p>

Home + Root Route

Let's add some meaningful tags to our home (index) page.

root 'welcome#index'
config/routes.rb

And route this page to be our root.

get 'about' => 'welcome#about'

Also update the about controller to point to /about instead of welcome/about

ERB

Embedded Ruby

<% ... %>
<%= ... %>

Run the code but do not return anything. Used for conditions, loops or blocks.

Run the code and print the return value.

INCORRECT

Hi there <% puts "Jaime" %>

Hi there <%= @name %>

CORRECT

class WelcomeController < ApplicationController
  def index
    @homeland = 'Italy'
  end

  def about
  end
end

Passing Data 

From Controller to View 

Let's store a variable called "homeland" in the index action of our Welcome Controller.

 
app/controllers/welcome_controller.rb
<h1>Welcome to my Travel Site</h1>
<p>This is my very awesome travel site.</p>

<!-- correct -->
<%= @homeland %>

<!-- incorrect -->
<% @homeland %>

We can now display this data from our controller using erb tags in the view.

Displaying the Data

app/views/welcome/index.html.erb

Passing an Array

Let's store an array called "countries" in our welcome controller. Add a list of your favorite countries.

class WelcomeController < ApplicationController
  def index
    @homeland = 'Italy'
    @countries = ['Norway','Sweden','Peru']
  end

  def about
  end
end
app/controllers/welcome_controller.rb

Displaying the Data

<% @countries.each do |country| %>
  <%= country %>
<% end %>

We can now display this data using erb tags and an each loop. (Remember Ruby?) 

app/views/welcome/index.html.erb

How could we make this display in a list?

Displaying in a List


<ul>
  <% @countries.each do |country| %>
    <li><%= country %></li>
  <% end %>
</ul>

Here's the list solution. By weaving list tags into our erb we can dynamically generate a list. Powerful stuff.

app/views/welcome/index.html.erb

Displaying Images

The image_tag helper builds an HTML <img /> tag to the specified file. By default, files are loaded from assets/images so no folder path is required.

 

 

 

<%= image_tag "peru.png" %>
<%= image_tag "assets/images/peru.png" %>

Correct:

Incorrect:

Images with Attributes

<%= image_tag "peru.png", alt: "Machu Picchu",
                          id: "peru",
                          class: "country" %>

Alt tag and css selectors may be specified like so:

Inspect this tag in the browser and notice the source code. 

Image Activity

Add 4 images to your homepage using erb tags.

 

 

Challenge!

Image Arrays 

Add an array of images to a controller and display the images on the corresponding view.

 

Hint: Use the image file names.

 

<% @travel_pics.each do |pic| %>
  <%= image_tag pic %>
<% end %>

Challenge Solution

app/views/welcome/index.html.erb
@travel_pics = ['peru.jpg', 'peru2.jpg', 'peru3.jpg']
app/controllers/welcome_controller.rb

Query Strings

We can also pass data through query strings in the URL.

 

Real world example:

Our example:

http://localhost:3000/about?color=blue

Query Strings

We can output content to the view using a parameter passed through the query string. The variable is declared in our controller and called in our view with erb.

 def about
   @color = params[:color]
 end
app/controllers/welcome_controller.rb
app/views/welcome/about.html.erb
<h1>About me</h1>
<p>Lots of interesting stuffs.</p>
<p>My favorite color is <%= @color %></p>

Big Foot Activity

What if we wanted to pass multiple pieces of information to the view? We have to use an ampersand instead of a question mark to separate each attribute/value pair.

http://localhost:3000/about?color=blue&size=12

Go ahead and add another variable called size and print out "My shoe size is 12" in the view.

 

Extra credit: If a shoe size greater than 12 is entered into the query string print out "I have HUGE feet!"

Big Foot Solution

Did you remember to convert size to an integer?

  def about
    @color = params[:color]
    @size = params[:size].to_i
  end
<% if @size > 12 %>
  <p>My shoe size is <%= @size %>. I have HUGE feet.</p>
<% else %>
  <p>My shoe size is <%= @size %></p>
<% end %>
app/controllers/welcome_controller.rb
app/views/welcome/about.html.erb
<style>
  body {
    background: <%= @color %>;
  }
</style>

<h1>About Me</h1>
<p>Lots of interesting stuffs.</p>

Styling w Query Strings

How would we change the background color of the entire page using a query string?

app/views/welcome/about.html.erb

Stretch Break!

Yield

Within the context of a layout, yield identifies a section where content from the view should be inserted. 

app/views/layouts/application.html.erb
<html>
<head>
  <title>Travel</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
    <%= yield %>
</body>
</html>

Add Bootstrap

<html>
<head>
  <title>Travel</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
  <%= csrf_meta_tags %>
</head>
<body>
  <div class="container">
    <%= yield %>
  </div>
</body>
</html>

We'll add the CDN Bootstrap references to the head the exact same way we did in our HTML sites. Let's also add a container that wraps all our content.

Add Navigation

Let's add a navbar so we can navigate through our app.

<a href="about">About</a>
<%= link_to "About", about_path %>

HTML way to link:

ERB way to link:

Now inspect the about link in Chrome. Notice the html code that was generated.

Nav with Attributes

<a class="navbar-brand" href="/">Travel</a>
<%= link_to "Travel", root_path, class: "navbar-brand" %>

HTML with a class:

ERB with a class:

Add a Contact Page

What if we wanted to add another page called contact to our site? How would we do this once the controller has been generated?

We have to do 3 things:

  1. add an action to our welcome controller
  2. add a corresponding view 
  3. add a route

A Contact Page is Born

class WelcomeController < ApplicationController
  def index
    @countries = ['Norway', 'Sweden', 'Peru']
  end

  def about
  end

  def contact
  end
end
<h1>Contact Me</h1>
<p>Write me a note!</p>
app/controllers/welcome_controller.rb
app/views/welcome/contact.html.erb
app/config/routes.rb
  root 'welcome#index'
  get 'about' => 'welcome#about'
  get 'contact' => 'welcome#contact'

1

2

3

 *= require_tree .

The Boss Stylesheet

Let's open up app/assets/stylesheets/application.css. The styles we write here will be applied to the entire site.

ensures that all CSS files in the app/assets/stylesheets directory are included into the application CSS

 *= require_self

ensures that the application.css file itself gets included

Background Images

Now let's get to stylin'! How would we style a background image for the entire site? Let's save an image into our app/assets/images folder and reference it in our stylesheet.

body {
  background: url(<%= asset_path "bg.png" %>) no-repeat;
  background-size: cover;
}
body {
  background: url("assets/images/bg.jpg") no-repeat;
  background-size: cover;
}

CSS way - does it work?

Ruby way  - must rename to application.css.erb

Contain Yourself

Let's style our container to have a background color of white with a bit of opacity. This way we can see a hint of our sweet background image and still read the text on our pages.

.container {
  background: rgba(255,255,255,0.8);
}
app/assets/stylesheets/application.css

Hash it out...

Create a hash in a controller called united_states. The keys are "capital_city", "favorite_city", "favorite_state" and "flag_colors". The values are up to you (flag_colors should be an array).

 

Display this data in the view in a nicely formatted table. 
NO HARD CODING. :)

 

sample output:

<table class="table">
  <tr>
    <% @united_states.each do |key,value| %>
	  <th><%= key.titleize %></th>
    <% end %>
  </tr>
  <tr>
    <% @united_states.each do |key,value| %>      
      <% if value.kind_of?(Array) %>
          <td><%= value.join(", ") %></td>
      <% else %>
         <td><%= value %></td>
      <% end %> 
    <% end %>
  </tr>
</table>

Hash it out Solution

 def index
   @united_states = {"capital city" => "Washington, DC", 
                     "favorite city" => "Asheville, NC", 
                     "favorite state" => "Oregon", 
                     "flag colors" => ["red", "white", "blue"]}
 end
app/controllers/welcome_controller.rb
app/views/welcome/index.html.erb

Homework

  • Add Bootstrap to your blog sites
  • Add a navigation
  • Add a contact page
  • Add some images to the about page
  • Add a sitewide background image or color
  • Push to Github periodically while you work
    ex: git commit -a -m 'added navigation'

Travel App Part I

By tts-jaime

Travel App Part I

Part I of Views/Controllers week (PT)

  • 1,425