Rails Demo 4: Making things pretty with Bootstrap

Bootstrap is a popular front-end library released by Twitter that makes it easy to add professional styling to our web app. This demo continues the blog app you wrote previously.

The instructions for configuring Rails 6 to use Bootstrap were provided by this video: https://gorails.com/episodes/how-to-use-bootstrap-with-webpack-and-rails.

Step 1: First we need to install Bootstrap into our Rails app.

  1. Use yarn to install the bootstrap, jquery, and popper.js packages

     yarn add bootstrap jquery popper.js
    
  2. Modify config/webpack/environment.js so that it looks like this:

    const { environment } = require('@rails/webpacker')
       
    const webpack = require("webpack");
    environment.plugins.append("Provide", new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      Popper: ['popper.js', 'default']
    }));
       
    module.exports = environment
    

    The “Provide” plugin makes the $, jQuery, and Popper names available to Bootstrap.

  3. Create a file named app/javascript/stylesheets/application.scss that contains one line: @import "~bootstrap/scss/bootstrap"
    • You will need to create the app/javascript/stylesheets directory.
    • Importing this scss file makes various bootstrap CSS variables available to JavaScript code.
    • Note: This application.scss file is different from app/assets/stylesheets/application.scss.
  4. Modify app/javascript/packs/application.js so that it looks like this:

    require("@rails/ujs").start()
    require("turbolinks").start()
    require("@rails/activestorage").start()
    require("channels")
       
    import "bootstrap"
    import "../stylesheets/application"
       
    document.addEventListener("turbolinks:load", () => {
      $('[data-toggle="tooltip"]').tooltip();
      $('[data-toggle="popover"]').popover();
    });
    
    • import "bootstrap" imports the Bootstrap-related JavaScript code.
    • The addEventListener reacts to a page load and runs the code necessary to make tooltips and popovers work.
  5. Add the following line to app/views/layouts/application.html

       <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    
    • application.html.erb is the template used by all views.
    • The erb code you write in your views is inserted by the yield.
    • The stylesheet_pack_tag causes every page to load the css packaged up by Webpacker.
      • This package contains the Bootstrap CSS
    • Similarly, the javascript_pack_tag causes every page to load the JavaScript packaged up by Webpacker

Step 2: Show the various templates / components available with BootStrap:**

Step 3: Set up a Home page

  1. Generate a Home controller

    rails generate controller Home 
    
  2. Make sure the controller has an index method:

    class HomeController < ApplicationController
      def index
      end
    end
    
  3. Add this route to config/routes.rb:

    root 'home#index'
    
  4. Create the home page template: views/home/index.html.erb (You don’t need any content yet.)

    • Copy code from basicColumns.html to verify that the Bootstrap CSS is available and working. (Add some borders into the home.scss to make it easier to see what’s going on.)

Step 4: Now Let’s add a Jumbotron to our homepage!

  1. Download a background image
  2. Add the following to views/home/index.html.erb:

    <div class="jumbotron-fluid">
      <div class="container">
        <h1>Welcome to my world of bees!</h1>
         <p>The happiness of the bee and the dolphin is to exist. For man it is to know that and to wonder at it.</p>
         <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more &raquo;</a></p> 
       </div>
     </div>
    
  3. Add the following to home.scss **

     .jumbotron-fluid {
         background-image: asset-url('bees.jpg');
         background-size: cover;
         height: 400px;
     }
    
     .jumbotron-fluid h1 {
        color: #fff;
        text-align: center;
        margin-bottom: 30px;
        letter-spacing: -1px;
        font-weight: bold;
     }
    
     .jumbotron-fluid p {
        color: #fff;
        text-align: center;
        margin-bottom: 30px;
        font-weight: bold;
     }
    
  4. To see the bee image, you may have to
    • Stop the server
      • run rake tmp:cache:clear
      • start the server.

Step 5: Nice! Now let’s call out our most recent articles under the Jumbotron

  1. Add the following to index.html.erb

    <div class="container-fluid">
      <!-- Example row of columns -->
      <div class="row">
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris        condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.        Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris        condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod.        Donec sed odio dui. </p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
       </div>
        <div class="col-md-4">
          <h2>Heading</h2>
          <p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta        felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum        massa justo sit amet risus.</p>
          <p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
        </div>
      </div>
         
      <hr>
         
      <footer>
        <p>&copy; 2018 Company, Inc.</p>
      </footer>
    </div> 
    
  2. In your home controller, implement the index method to do the query.

    def index
       @posts = Post.last(3)
    end
    
  3. Now render these posts using a similar HTML structure to that from Step 1. Replace the hardwired Heading divs from with this:

    <% @posts.each do |post| %>
       <div class="col-md-4">
          <h2><%= post.title%></h2>
          <p><%=post.article.truncate_words(30)%></p>
          <p>
            <%= link_to 'Read more &raquo;'.html_safe, post, class: "btn btn-default"%>
          </p>
       </div>
    <% end %>
    

Step 6: Now let’s add a standard nav bar to our app throughout.

  1. Create a new partial named views/layouts/_navigation.html.erb and place this code in it

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <a class="navbar-brand" href="#">Bee Blog</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"           aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active">
          <a class="nav-link navbar-dark" href="/">Home <span class="sr-only">(current)</span></a>
        </li>
        <li class="nav-item">
          <a class="nav-link navbar-dark" href="/authors">Authors</a>
        </li>
         <li class="nav-item">
          <a class="nav-link navbar-dark" href="/posts">Posts</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle navbar-dark" href="#" id="navbarDropdown" role="button"   data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Other Sites
          </a>
          <div class="dropdown-menu" aria-labelledby="navbarDropdown">
            <a class="dropdown-item" href="https://www.gvsu.edu">GVSU</a>
            <a class="dropdown-item" href="https://www.cis.gvsu.edu">CIS</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="https://www.gatech.edu">Georgia Tech</a>
          </div>
        </li>
      </ul>
      <form class="form-inline my-2 my-lg-0">
        <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
      </form>
      </div>
    </nav>
    
  2. Now invoke this partial in views/layouts/application.html.erb:**

    <%= render 'layouts/navigation' %> <%= yield %>

Step 7: Spruce up our Author pages