Sinatra, SimpleNavigation and Bootstrap
After getting a handle on it, I was really surprised that Twitter’s excellent Bootstrap UI framework
didn’t have functionality to cover tabs on other pages of the site. Much like the slick ScrollSpy, where various menu items are highlighted when you scroll to their div id
on the page, I was expecting a “PageSpy” type functionality to do the same with navigation tabs, and set a tab to active if the target url matched the URL the browser was on (especially since bootstrap does the more difficult in-page tab functionality. In fact, I was so surprised, I actually asked around and took a look at the js
source code as I thought I was missing something obvious.
So, I was stuck with coming up with a simple highlighting primary nav bar for my speedy little Sinatra app that integrated with Bootstrap. Looking around for simple tab gems that worked on more than Rails (tabulous is Rails-only, for example), the excellent simple-navigation gem popped out as being the simplest thing that would work (bar writing my own javascript).
A number of people have written custom renderers to get the old version of Bootstrap working directly with Subnavs and such, but if all your require is a primary nav bar using nav-tabs
or nav-pills
that’s overkill and you can shortcut all of this and use the basic setup below.
After putting gem 'simple-navigation'
in your Gemfile
and doing your bundle install
you simply need to add the following in your main app.rb file (or similar). I use the modular style of building Sinatra apps which needs the register directive you see. If you’re going even simpler, you won’t need that.
require 'rubygems'
require 'sinatra/base'
require 'sinatra/simple-navigation'
class App < Sinatra::Base
register Sinatra::SimpleNavigation
# Application code starts here
Then it’s a simple matter of creating a file (and possibly new directory if you’re not using /config) navigation.rb
SimpleNavigation::Configuration.run do |navigation|
# sets selected tab/pill to .active class that Bootstrap uses
navigation.selected_class = 'active'
# optional: an extra class simplnav applies changed for clarity
navigation.active_leaf_class = 'active-leaf'
navigation.items do |primary|
# sets the containing ul class="nav nav tab" for Bootstrap
primary.dom_class = 'nav nav-tab'
# optional: id set to "", this changed for clarity
primary.dom_id = 'nav-tabs'
primary.item :projects, 'Projects', '/projects'
primary.item :archives, 'Archives', '/archives'
primary.item :about, 'About', '/about'
end
end
Since my application dynamically sets all but the special pages (ie. like Archives), I just pass along the path URL to find the pages and SimpleNavigation takes care of the rest. Schmicko.
In the view (note: I’m using haml
), I simply call the render_navigation
helper now in my layout.rb
.
%body
.navbar.navbar-fixed-top
.navbar-inner
.container
%a.brand{:href => "/"} Tundramonkey
%a.btn.btn-navbar(data-toggle="collapse" data-target=".nav-collapse")
%span.icon-bar
%span.icon-bar
%span.icon-bar
.nav_collapse
= render_navigation
= yield
And that’s it. Seriously. Simple as the gem name implies and works with either nav-tabs
or the nav-pills
UI styles in Bootstrap.
The rest is simply styling up the default bootstrap css to your needs or using the default and pushing your multi-page app online.