• Stars
    star
    295
  • Rank 140,902 (Top 3 %)
  • Language
    Ruby
  • License
    MIT License
  • Created almost 16 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Tabs on Rails is a simple Rails plugin for creating and managing tabs and navigation menus.

Tabs on Rails

TabsOnRails is a simple Rails plugin for creating tabs and navigation menus. It provides helpers for generating navigation menus with a flexible interface.

Requirements

  • Rails 4.2 or Rails 5

For older versions of Ruby or Ruby on Rails, see the CHANGELOG.

Installation

Add this line to your application's Gemfile:

gem "tabs_on_rails"

And then execute bundle to install the dependencies:

$ bundle

Use Bundler and the :git option if you want to grab the latest version from the Git repository.

Usage

In your template use the tabs_tag helper to create your tab.

<%= tabs_tag do |tab| %>
  <%= tab.home      'Homepage', root_path %>
  <%= tab.dashboard 'Dashboard', dashboard_path %>
  <%= tab.account   'Account', account_path %>
<% end %>

renders

<ul>
  <li><a href="/">Homepage</a></li>
  <li><a href="/dashboard">Dashboard</a></li>
  <li><a href="/account">Account</a></li>
</ul>

The usage is similar to the Rails route file. You create named tabs with the syntax tab.name_of_tab. The name you use creating a tab is the same you're going to refer to in your controller when you want to mark a tab as the current tab.

class DashboardController < ApplicationController
  set_tab :dashboard
end

Now, if the action belongs to DashboardController, the template will automatically render the following HTML code.

<ul>
  <li><a href="/">Homepage</a></li>
  <li class="custom"><span>Dashboard</span></li>
  <li><a href="/account">Account</a></li>
</ul>

Use the current_tab helper method if you need to access the value of current tab in your controller or template.

class DashboardController < ApplicationController
  set_tab :dashboard
end

In your view

<p>The name of current tab is <%= current_tab %>.</p>

Customizing a Tab

You can pass a hash of options to customize the style and the behavior of the tab item. Behind the scenes, each time you create a tab, the #tab_for method is invoked.

<%= tabs_tag do |tab| %>
  <%= tab.home      'Homepage', root_path, :style => "padding: 10px" %>
  <%= tab.dashboard 'Dashboard', dashboard_path %>
<% end %>

renders

<ul>
  <li style="padding: 10px"><a href="/">Homepage</a></li>
  <li class="custom"><span>Dashboard</span></li>
  <li><a href="/account">Account</a></li>
</ul>

See TabsOnRails::Tabs::TabsBuilder#tab_for for more details.

Customizing open_tabs and close_tabs

The open_tabs and the close_tabs methods can be customized with the :open_tabs and :close_tabs option.

<%= tabs_tag open_tabs: { id: 'tabs', class: 'cool' } do |tab| %>
  <%= tab.home      'Homepage', root_path %>
  <%= tab.dashboard 'Dashboard', dashboard_path %>
  <%= tab.account   'Account', account_path %>
<% end %>

renders

<ul id="tabs" class="cool">
  <li><a href="/">Homepage</a></li>
  <li><a href="/dashboard">Dashboard</a></li>
  <li><a href="/account">Account</a></li>
</ul>

Further customizations require a custom Builder (see below).

Restricting set_tab scope

The set_tab method understands all options you are used to pass to a Rails controller filter. In fact, behind the scenes this method uses a before_filter to store the tab in the @tab_stack variable.

Taking advantage of Rails filter options, you can restrict a tab to a selected group of actions in the same controller.

class PostsController < ApplicationController
  set_tab :admin
  set_tab :posts, :only => %w(index show)
end

class ApplicationController < ActionController::Base
  set_tab :admin, :if => :admin_controller?
  
  def admin_controller?
    self.class.name =~ /^Admin(::|Controller)/
  end
end

Using Namespaces to create Multiple Tabs

Namespaces enable you to create and manage tabs in parallels. The best way to demonstrate namespace usage is with an example.

Let's assume your application provides a first level navigation menu with 3 elements: :home, :dashboard, :projects. The relationship between your tabs and your controllers is 1:1 so you should end up with the following source code.

class HomeController
  set_tab :home
end

class DashboardController
  set_tab :dashboard
end

class ProjectsController
  set_tab :projects
  
  def first; end
  def second; end
  def third; end
end

The project controller contains 3 actions and you might want to create a second-level navigation menu. This menu should reflect the navigation status of the user in the project page.

Without namespaces, you wouldn't be able to accomplish this task because you already set the current tab value to :projects. You need to create a parallel navigation menu and uniquely identify it with a custom namespace. Let's call it :navigation.

class ProjectsController
  set_tab :projects

  # Create an other tab navigation level
  set_tab :first, :navigation, :only => %w(first)
  set_tab :second, :navigation, :only => %w(second)
  set_tab :third, :navigation, :only => %w(third)

  def first; end
  def second; end
  def third; end
end

Voilà! That's all you need to do. And you can create an unlimited number of namespaces as long as you use an unique name to identify them.

The default namespace is called :default. Passing :default as name is the same as don't using any namespace at all. The following lines are equivalent.

set_tab :projects
set_tab :projects, :default

Rendering Tabs with Namespaces

To switch namespace in your template, just pass the :namespace option to the tabs_tag helper method.

<%= tabs_tag do |tab| %>
  <%= tab.home      'Homepage', root_path %>
  <%= tab.dashboard 'Dashboard', dashboard_path %>
  <%= tab.projects  'Projects', projects_path %>
<% end %>

<%= tabs_tag :namespace => :navigation do |tab| %>
  <%= tab.first   'First', project_first_path %>
  <%= tab.second  'Second', project_second_path %>
  <%= tab.third   'Account', project_third_path %>
<% end %>

Namespace scope

As a bonus feature, the namespace needs to be unique within current request scope, not necessarily across the entire application.

Back to the previous example, you can reuse the same namespace in the other controllers. In this way, you can reuse your templates as well.

class HomeController
  set_tab :home
end

class DashboardController
  set_tab :dashboard

  set_tab :index,  :navigation, :only => %w(index)
  set_tab :common, :navigation, :only => %w(foo bar)
  
  # ...
end

class ProjectsController
  set_tab :projects

  set_tab :first,  :navigation, :only => %w(first)
  set_tab :second, :navigation, :only => %w(second)
  set_tab :third,  :navigation, :only => %w(third)
  
  # ...
end

Tab Builders

The Builder is responsible for creating the tabs HTML code. This library is bundled with two Builders:

  • Tabs::Builder: this is the abstract interface for any custom builder.
  • Tabs::TabsBuilder: this is the default builder.

Understanding the Builder

Builders act as formatters. A Builder encapsulates all the logic behind the tab creation including the code required to toggle tabs status.

When the tabs_tag helper is called, it creates a new Tabs instance with selected Builder. If you don't provide a custom builder, then Tabs::TabsBuilder is used by default.

Creating a custom Builder

All builders must extend the base Tabs::Builder class and implement at least the tab_for method. Additional overridable methods include:

  • open_tabs: the method called before the tab set
  • close_tabs: the method called after the tab set
  • tab_for: the method called to create a single tab item

The following example creates a custom tab builder called MenuTabBuilder.

class MenuTabBuilder < TabsOnRails::Tabs::Builder
  def open_tabs(options = {})
    @context.tag("ul", options, open = true)
  end

  def close_tabs(options = {})
    "</ul>".html_safe
  end

  def tab_for(tab, name, options, item_options = {})
    item_options[:class] = (current_tab?(tab) ? 'active' : '')
    @context.content_tag(:li, item_options) do
      @context.link_to(name, options)
    end
  end
end

Using a custom Builder

In your view, simply pass the builder class to the tabs_tag method.

<%= tabs_tag(:builder => MenuTabBuilder) do |tab| %>
  <%= tab.home        'Homepage', root_path %>
  <%= tab.dashboard,  'Dashboard', dashboard_path %>
  <%= tab.account     'Account', account_path, style: 'float: right;' %>
<% end %>

renders

<ul>
  <li class=""><a href="/">Homepage</a></li>
  <li class="active"><a href="/dashboard">Dashboard</a></li>
  <li class="" style="float: right;"><a href="/account">Account</a></li>
</ul>

Credits

TabsOnRails was created and is maintained by Simone Carletti. Many improvements and bugfixes were contributed by the open source community.

Contributing

Direct questions and discussions to Stack Overflow.

Pull requests are very welcome! Please include tests for every patch, and create a topic branch for every separate change you make.

Report issues or feature requests to GitHub Issues.

More Information

License

Copyright (c) 2009-2017 Simone Carletti. This is Free Software distributed under the MIT license.

More Repositories

1

whois

An intelligent — pure Ruby — WHOIS client and parser.
Ruby
1,096
star
2

breadcrumbs_on_rails

A simple Ruby on Rails plugin for creating and managing a breadcrumb navigation.
Ruby
937
star
3

publicsuffix-ruby

Domain name parser for Ruby based on the Public Suffix List.
Ruby
609
star
4

publicsuffix-go

Domain name parser for Go based on the Public Suffix List.
Go
170
star
5

whois-parser

An intelligent — pure Ruby — WHOIS parser.
Ruby
97
star
6

dnscaa

Go
69
star
7

www-delicious

Ruby client for delicious.com API.
Ruby
62
star
8

apachelogregex

Ruby parser for Apache log files based on regular expressions.
Ruby
54
star
9

actionmailer_with_request

A simple plugin to make the Rails request context available for generating URLs in ActionMailer.
Ruby
54
star
10

ruby-4-rails.showoff

Learning Ruby, with Rails in mind.
Ruby
45
star
11

rubyist

Ruby Quality Guidelines
Ruby
34
star
12

brighella

A simple URL-masking redirect service built on Go.
Go
14
star
13

apachelog2feed

ApacheLogAnalyzer2Feed is a really powerful open source PHP 5 class to parse and analyze Apache Web Server log files.
PHP
13
star
14

activerecord-multiconditions

DISCONTINUED - An ActiveRecord plugin for dealing with complex search :conditions.
Ruby
8
star
15

docbook5-tmbundle

TextMate bundle for DocBook 5.
6
star
16

whois-debian

Various versions of the Whois debian packages tracked in a single Git repository.
C
5
star
17

wordpress-mtimporter

WordPress Importer utilities to finalize your migration from Movable Type to Wordpress.
PHP
5
star
18

helperful

DISCONTINUED - A collection of useful Rails helpers.
Ruby
5
star
19

asg

ASP Stats Generator
ASP
4
star
20

fileiterator

PHP
4
star
21

whois.js

JavaScript
3
star
22

gomotion2015

A practical introduction to go
Go
3
star
23

movabletype-templates

3
star
24

kirbybase

Unofficial Git repository for KirbyBase
3
star
25

letsencrypt-dnsimple

Go
3
star
26

pslint

PSLint is a linter for Public Suffix list
Go
1
star
27

squeezon-ruby

Ruby
1
star
28

digweb

Like DiG, but in HTTP flavour.
Go
1
star
29

hubot-digweb

CoffeeScript
1
star
30

domainr-go

A Go client for the Domainr API.
Go
1
star
31

public_suffix_service

The repository has moved!
1
star