Integrating Bootstrap 4 into Rails 6
We’ve all been there, you start building a new Rails application and you realize there is no style on any of your generic Rails pages. So you know in the back of your head you can grab Bootstrap and an Admin theme to get things moving. You may then find yourself asking, “What’s the best way to get Bootstrap into Rails?” and “How do I add the theme itself to the application?”. Let’s did into those questions and more in this post!
To install the a Bootstrap theme, we are going to be adding some packages, updating some configuration and adding a few additional gems/libraries to make life developing easier.
The first thing to do is to add another version manager! Since we are using Yarn/NPM/Node, it is a good idea to manage the version of Node a particular application or directory will be using. To do so, we will use NVM, and you can install NVM with the following line. If you are one to look at the github repo or the install scripts, you can here.
That line grabs the install script from Github and runs it as Bash
.
Now the current LTS (Long Term Stable) version of Node is version 12. LTS versions in the OSS (Open Source) communities is the version in which you can rely on long term stability. To install Node use the following command:
This line installs the latest updated version of version 10. Meaning, as small updates and bugfixes are released to the version 10 pipeline, they bump the version numbers under 12 (i.e., 12.3.4 -> 12.3.5). Once installed, you can tell your terminal window/pane to use node 12 with the following command:
When you created your new app, Rails should have made sure brew
and yarn
were added. Thus, you should now be able to install AdminLTE, Bootstrap, and a few other dependencies needed to get AdminLTE up and running in your application.
First, to install a version of AdminLTE that is compatible with Bootstrap 4, we will need to install through Yarn on a specific Github branch
This command is saying, install admin-lte
and use the version 3
. Next, we also install the packages for Bootstrap, jQuery and Popper.js to make sure they are available to the Rails application:
That should take care of making sure all of the packages we need for the theme are there, but it seems as though Rails does not entirely install everything needed for Webpacker to get up and running. To remedy this issue, let’s run the Webpacker install.
Alright, we are getting close to being done with setup! However, we should digress a bit in regards to Webpacker.
Webpacker
Webpacker is the Ruby (Rails mostly) wrapper gem around the Javascript tool, Webpack. Webpack is a tool that allows you to pre-process, bundle and use ES6 like syntax inside Javascript. Webpacker then takes all of those features and starts to merge the ES6 Javascript world with the Asset pipeline for CSS and other more static assets.
Webpacker introduces a concept of “packs” which are ES6 syntax Javascript files that you can then include in any template with a
pack_tag
helper. Think of packs as entry points of javascript files into specific spots in a Rails app.The most basic pattern is the
/app/javascript/application.js
pack file, which is then included in the applications’ layout file by default.As your application grows, using packs to specify specific libraries and functionality within specific templates or sections of your application helps make sure your Javascript stays modular and compartmentalized.
Running A Webpack Dev Server
If you have used Heroku or other hosting vendors, you may see reference to Procfile
. The simplest definition of a Procfile is that it allows you to specify a list of different process types and lets another system(Heroku, Foreman gem, etc.) handle startup and shutdown. Allow all of that to be dealt with one line and one terminal session/tab/pane.
When developing locally, the easiest step to take is to use the gem Foreman
. To add this gem, add it to the development group in your Gemfile
and bundle install
:
Once added, you can add your Procfile
to the root of your app’s folder structure. Meaning the same level as your Gemfile
.
You may notice that instead of rails s
, you see bundle exec puma
. This change is due to how you would want to run Puma directly in most environments.
If you were to start your environment with Foreman and this procfile, you would use the following on the command line:
That command starts up a process for each line in your Procfile. Thus, in this case, a process for Puma, to run the Rails server. However, if you visit your instance of the app, first you may notice it is now at http://localhost:5000, and it is also not outputting development logs.
So, how can we make development use rails s
to keep the fancy logs? We can
create a secondary Procfile
that is utilized just for development.
What is
webpack-dev-server
?Very simply, it is a server that runs in the background that allows you to develop your Javascript, handles automatic reloads and makes sure packs are served to you your development Rails server.
To get this Procfile running instead, you simply just need to add a field to your command line syntax:
We’re getting closer! Now if you visit http://localhost:5000, you should see the output in the terminal from your request. However, we’re still on port 5000
. This problem is easy to fix, just supply the command line with the environment variable used in the command to choose the port.
Now, you can quickly start everything up and get it running in one terminal tab.
Final Webpacker Setup
Ok, we’re getting so close to getting everything up and running. We’re down to adding just a few additions to the Webpack javascript configuration.
One of the additions are the 8 lines of plugin code that is used to make sure jQuery, Popper.js and Tether are available throughout the bundled javascript.
The Application Pack
When adding Javascript to a Rails application, there are javascript libraries, setup or variables you want throughout the application. In the world of Rails 6 and Webpacker, these items go in the Application Pack, located at app/javascript/packs/application.js
. The good news is that this file is created when you used the Rails command to create a new Rails app. Let’s go over the additions to get AdminLTE’s needs fulfilled.
The commented code and the first four lines of require
s are added by default. These are libraries or packages that Rails needs for most applications. The new lines are adding jQuery and variables that other packages or libraries may expect to exist. Lastly, bootstrap
and admin-lte
are required to make available to the entire Rails application.
Why
require
and notimport
If you have done any recent javascript development, you may question why we are using
require
and notimport
. The answer here is rather simple. Based on the packages we are using and adding in, they expect other’s to have loaded first. Most specifically,admin-lte
expects the global variablejQuery
to exist when it loads. Usingrequire
guarantees code is executed in the order of the file, whereasimport
usually is pre-processed and executed out of order.
The Application Stylesheet
Lastly, we need to add some imports to the bottom of the automatically created Application Stylesheet. If you have done any Rails development in the last few years, you may have interacted with the Asset Pipeline, which is the way Rails handled the inclusion of javascript, stylesheets and any other static assets.
You’ll notice that the name of the file is different than what was generated by Rails. For import
the extension scss
needs to be used, signaling the Asset Pipeline to run the file as Sass, then CSS.
In Sass CSS, you can include other stylesheets or fonts by using the @import
syntax. In this stylesheet above, we are adding a font from Google Fonts that are referenced in AdminLTE’s stylesheets. Next, we include stylesheets for Bootstrap and AdminLTE.
In the following section, we are going to add some Controllers and Templates to added the necessary markup to structure the application.
Before we begin implementing the layout, we need to apply a route and controller to bypass the default welcome page. We also will be using this controller in the application as we go along.
Let’s also pause to mention that Rails comes with built-in command line generators to generate controllers, models, mailers. As well as generating database migration file or even generating a scaffold of all of those combined. In our case, let’s focus on the controller generator. The general format for this generator is:
It created a controller with empty methods for the actions we included in the command line. It created template files, test files, and other auxiliary files.
Let’s make one quick edit to the route file to define a default route, adding “root to: ‘activity#mine’” to the bottom of the route file, as follows:
As we had set up the theme package, application javascript file and application stylesheet file earlier in the chapter, we can get into writing the markup needed to implement this theme rather quickly.
First, we can modify the main layout file to include the necessary elements and classes to wrap the content that will be provided by routed templates.
File: app/views/layouts/application.html.erb
:
The details of this file are not all pertinent to the addition of the Bootstrap theme, so we’ll only touch on those that matter. First, a class is added to the body element, “body class=“sidebar-mini"". Next, "
render partial:
calls allow us to add markup from other template files, in that position. In this case, it adds various larger parts of the application template such as the header, sidebar or footer. Plus, it keeps the layout to only the most necessary foundational elements to build the page structure. Then, ”<%= yield %>” which is the Rails’ template method for adding the template from the controller and action called.
Since we are using partial templates, we go ahead and create the header file next.
One thing to note here is the use of the underscore in the template file’s name. In Rails, partial template files are designated with an underscore at the beginning of the file name. What are partials? Partials are simply a way to break down templates into smaller chunks. This approach comes into far greater play in situations such as looping over a collection of items. There, you would make the template chunk to display item information a partial. For example, the header template is titled _header.erb
.
This template contains the structure to have the app title/logo, dropdowns and any additional links you may need for navigation. To get the app template structure setup, we can leave in some of the demo data and elements to show how the dropdowns would look and work.
The next partial to create is the _sidebar
template:
As you see, the sidebar partial is a bit smaller and more straightforward. It contains a little bit of user information and links to other parts of the application that we change later.
The last major piece of the layout is the footer. It is simple, and it is short. Again, it is another partial. Here is the ERB markup:
Now, to have all of this show up on a page, you can edit the root controller action’s template to use the theme’s div classes
That’s about it to get set up with Bootstrap 4 and Rails 6.