Skip to content

Commit

Permalink
Added support for Twitter Bootstrap (version 2).
Browse files Browse the repository at this point in the history
  • Loading branch information
techiferous committed Feb 7, 2012
1 parent d861622 commit 1b977d0
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rdoc
@@ -1,3 +1,7 @@
== 1.2.0 (February 8, 2012)
* Added support for Twitter Bootstrap (version 2).
* Noted in the documentation that tabulous works with Rails 3.2.

== 1.1.0 (January 10, 2012)
* Deprecated the raise_error_if_no_tab_found configuration setting. Replaced it with
config.when_action_has_no_tab.
Expand Down
19 changes: 18 additions & 1 deletion README.rdoc
Expand Up @@ -6,7 +6,7 @@ Tabulous provides an easy way to add tabs to your Rails application.

== Requirements

Tabulous only works with Rails 3.0 and 3.1. It has been tested on Ruby 1.8.7 and 1.9.2.
Tabulous works with Rails 3.0, 3.1 and 3.2. It has been tested on Ruby 1.8.7 and 1.9.2.

== Usage

Expand Down Expand Up @@ -66,6 +66,23 @@ There is a tutorial at http://techiferous.com/2011/03/tutorial-for-adding-tabs-t
Also, look in this gem's test/applications directory to find working example applications.
Look at their app/tabs/tabulous.rb and app/layouts/application.html.erb files.

== Twitter Bootstrap

To get tabulous to work with Twitter Bootstrap version 2, make sure the
following values are set in app/tabs/tabulous.rb:

* config.css.scaffolding = false
* config.tabs_ul_class = "nav nav-pills" # or whatever Bootstrap class you want
* config.bootstrap_style_subtabs = true
* config.active_tab_clickable = true

When config.bootstrap_style_subtabs is set to true, the subtabs are rendered
inside the tab markup, so you only need to call the tabs helper in your
layout, not the subtabs helper.

Also note that if you use Twitter Bootstrap, you lose the ability to disable
individual subtabs.

== Contributing

Developers are encouraged to contribute ideas or code.
Expand Down
30 changes: 23 additions & 7 deletions lib/generators/tabs/templates/tabulous.rb
Expand Up @@ -122,9 +122,9 @@
s << ' end'
Tabulous::Formatter.format(s).join("\n") %>

#-------------
# OPTIONS
#-------------
#---------------------
# GENERAL OPTIONS
#---------------------

# By default, you cannot click on the active tab.
config.active_tab_clickable = false
Expand All @@ -140,13 +140,28 @@
# config.when_action_has_no_tab = :render # the tab navigation HTML will be generated,
# but no tab or subtab will be active

#--------------------
# MARKUP OPTIONS
#--------------------

# By default, div elements are used in the tab markup. When html5 is
# true, nav elements are used instead.
config.html5 = false

#------------
# STYLES
#------------
# This gives you control over what class the <ul> element that wraps the tabs
# will have. Good for interfacing with third-party code like Twitter
# Bootstrap.
# config.tabs_ul_class = "nav nav-pills"

# Set this to true to have subtabs rendered in markup that Twitter Bootstrap
# understands. If this is set to true, you don't need to call subtabs in
# your layout, just tabs.
# config.bootstrap_style_subtabs = true


#-------------------
# STYLE OPTIONS
#-------------------
#
# The markup that is generated has the following properties:
#
Expand All @@ -161,7 +176,8 @@
# Some styles will be generated for you to get you off to a good start.
# Scaffolded styles are not meant to be used in production as they
# generate invalid HTML markup. They are merely meant to give you a
# head start or an easy way to prototype quickly.
# head start or an easy way to prototype quickly. Set this to false if
# you are using Twitter Bootstrap.
#
config.css.scaffolding = true

Expand Down
6 changes: 6 additions & 0 deletions lib/tabulous/options.rb
Expand Up @@ -34,6 +34,12 @@ def initialize
mattr_accessor :html5
@@html5 = false

mattr_accessor :tabs_ul_class
@@tabs_ul_class = nil

mattr_accessor :bootstrap_style_subtabs
@@bootstrap_style_subtabs = false

def self.raise_error_if_no_tab_found=(value)
msg = "DEPRECATION WARNING: Tabulous's config.raise_error_if_no_tab_found "
msg << "has been replaced by config.when_action_has_no_tab. "
Expand Down
62 changes: 57 additions & 5 deletions lib/tabulous/tabulous.rb
Expand Up @@ -20,20 +20,42 @@ def self.render_tabs(view)
active_tab = active_tab(view)
active_tab_name = (active_tab ? active_tab.name : nil);
html << (@@html5 ? '<nav id="tabs">' : '<div id="tabs">')
html << '<ul>'
if @@tabs_ul_class
html << %Q{<ul class="#{@@tabs_ul_class}">}
else
html << '<ul>'
end
for tab in main_tabs
next if !tab.visible?(view)
html << render_tab(:text => tab.text(view),
:path => tab.path(view),
:active => (active_tab_name && tab.name == active_tab_name),
:enabled => tab.enabled?(view))
if @@bootstrap_style_subtabs
subtabs = tab.subtabs.select{|subtab| subtab.visible?(view)}
end
if @@bootstrap_style_subtabs && !subtabs.empty?
html << render_dropdown_tab(view,
:text => tab.text(view),
:path => tab.path(view),
:active => (active_tab_name && tab.name == active_tab_name),
:enabled => tab.enabled?(view),
:subtabs => subtabs)
else
html << render_tab(:text => tab.text(view),
:path => tab.path(view),
:active => (active_tab_name && tab.name == active_tab_name),
:enabled => tab.enabled?(view))
end
end
html << '</ul>'
html << (@@html5 ? '</nav>' : '</div>')
view.raw(html)
end

def self.render_subtabs(view)
if @@bootstrap_style_subtabs
raise TabulousError,
"You should not call the subtabs view helper when config.bootstrap_style_subtabs " +
"is set to true. Simply call the tabs helper and the subtabs will be " +
"automatically rendered."
end
initialize_tabs(view)
return if !tab_defined?(view) && @@when_action_has_no_tab == :do_not_render
controller = view.controller_name.to_sym
Expand Down Expand Up @@ -73,6 +95,36 @@ def self.render_tab(options)
html
end

# markup spefically tailored for Twitter Bootstrap
def self.render_dropdown_tab(view, options)
html = ''
klass = 'dropdown'
klass << (options[:active] ? ' active' : ' inactive')
klass << (options[:enabled] ? ' enabled' : ' disabled')
html << %Q{<li class="#{klass}">}
if (options[:active] && !@@active_tab_clickable) || options[:enabled] == false
html << %Q{<span class="tab">#{options[:text]}</span>}
else
html << %Q{<a class="dropdown-toggle tab"}
html << %Q{ data-toggle="dropdown"}
html << %Q{ href="#">}
html << %Q{#{options[:text]}<b class="caret"></b></a>}
end
html << '<ul class="dropdown-menu">'
for subtab in options[:subtabs]
if subtab.enabled?(view)
html << '<li class="enabled">'
else
html << '<li class="disabled">'
end
html << %Q{<a href="#{subtab.path(view)}">#{subtab.text(view)}</a>}
html << '</li>'
end
html << '</ul>'
html << '</li>'
html
end

def self.initialize_tabs(view)
if view.respond_to? :instance_exec # for Ruby 1.9
self.tabs = view.instance_exec(&@@tabs_block)
Expand Down
2 changes: 1 addition & 1 deletion lib/tabulous/version.rb
@@ -1,3 +1,3 @@
module Tabulous
VERSION = "1.1.0"
VERSION = "1.2.0"
end

0 comments on commit 1b977d0

Please sign in to comment.