-
Notifications
You must be signed in to change notification settings - Fork 52
/
action_controller.rb
219 lines (202 loc) · 6.93 KB
/
action_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#
# = Tabs on Rails
#
# A simple Ruby on Rails plugin for creating and managing Tabs.
#
#
# Category:: Rails
# Package:: TabsOnRails
# Author:: Simone Carletti <weppos@weppos.net>
# License:: MIT License
#
#--
#
#++
module TabsOnRails
module ActionController
extend ActiveSupport::Concern
included do
extend ClassMethods
include InstanceMethods
helper HelperMethods
helper_method :current_tab, :current_tab?
end
module ClassMethods
# Sets the value for current tab to given name.
#
# set_tab :foo
#
# If you need to manage multiple tabs, then you can pass an optional namespace.
#
# set_tab :foo, :namespace
#
# The <tt>set_tab</tt> method understands all options you are used to pass to a Rails controller filter.
# In fact, behind the scenes this method uses a <tt>before_filter</tt>
# to store the tab in the <tt>@tab_stack</tt> variable.
# For example, you can set the tab only for a restricted group of actions in the same controller
# using the <tt>:only</tt> and <tt>:except</tt> options.
#
# Examples
#
# set_tab :foo
# set_tab :foo, :except => :new
# set_tab :foo, :only => [ :index, :show ]
#
# set_tab :foo, :namespace
# set_tab :foo, :namespace, :only => [ :index, :show ]
#
def set_tab(*args)
options = args.extract_options!
name, namespace = args
before_filter(options) do |controller|
controller.send(:set_tab, name, namespace)
end
end
end
module InstanceMethods
protected
# Sets the value for current tab to given name.
# If you need to manage multiple tabs,
# then you can pass an optional namespace.
#
# Examples
#
# set_tab :homepage
# set_tab :dashboard, :menu
#
# Returns nothing.
def set_tab(name, namespace = nil)
tab_stack[namespace || :default] = name
end
# Returns the value for current tab in the default namespace,
# or nil if no tab has been set before.
# You can pass <tt>namespace</tt> to get the value
# of the current tab for a different namespace.
#
# Examples
#
# current_tab # => nil
# current_tab :menu # => nil
#
# set_tab :homepage
# set_tab :dashboard, :menu
#
# current_tab # => :homepage
# current_tab :menu # => :dashboard
#
# Returns the String/Symbol current tab.
def current_tab(namespace = nil)
tab_stack[namespace || :default]
end
# Checks if the current tab in <tt>namespace</tt>
# matches <tt>name</tt>.
#
# Returns a Boolean.
def current_tab?(name, namespace = nil)
current_tab(namespace).to_s == name.to_s
end
# Initializes and/or returns the tab stack.
# You won't probably need to use this method directly
# unless you are trying to hack the plugin architecture.
#
# Returns the Hash stack.
def tab_stack
@tab_stack ||= {}
end
end
module HelperMethods
# In your template use the <tt>tabs_tag</tt> 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 %>
#
# The example above produces the following HTML output.
#
# <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 <tt>tab.name_of_tab</tt>.
#
# 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 <tt>DashboardController</tt>,
# the template will automatically render the following HTML code.
#
# <ul>
# <li><a href="/">Homepage</a></li>
# <li class="current"><span>Dashboard</span></li>
# <li><a href="/account">Account</a></li>
# </ul>
#
# Use the <tt>current_tab</tt> 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 <tt>#tab_for</tt>
# method is invoked.
#
# <%= tabs_tag do |tab| %>
# <%= tab.home 'Homepage', root_path, :style => "padding: 10px" %>
# <%= tab.dashboard 'Dashboard', dashboard_path %>
# <%= tab.account 'Account', account_path, :class => "custom" %>
# <% end %>
#
# <ul>
# <li style="padding: 10px"><a href="/">Homepage</a></li>
# <li class="current"><span>Dashboard</span></li>
# <li class="custom"><a href="/account">Account</a></li>
# </ul>
#
# You can pass any option supported by the <li>content_tag</li> Rails helper.
# Additionally, the following options have a special meaning:
#
# * <tt>link_current</tt>: forces the current tab to be a link, instead of a span tag
#
# See <tt>TabsOnRails::Tabs::TabsBuilder#tab_for</tt> for more details.
#
# === Customizing open_tabs and close_tabs
#
# The open_tabs and the close_tabs methods can be customized
# with the <tt>:open_tabs</tt> and <tt>:close_tabs</tt> 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 %>
#
# <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 <tt>Builder</tt>.
#
def tabs_tag(options = {}, &block)
Tabs.new(self, { :namespace => :default }.merge(options)).render(&block)
end
end
end
end