rails_nav 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README +48 -14
  2. data/lib/rails_nav.rb +160 -155
  3. data/rails_nav.gemspec +6 -7
  4. metadata +25 -4
  5. data/nav.html +0 -7
data/README CHANGED
@@ -1,21 +1,55 @@
1
+ NAME
2
+ rails_nav.rb
1
3
 
2
- class FooController
4
+ SYNOPSIS
5
+ encapsulates only the concept of a
3
6
 
4
- nav_for :su do |list|
5
- list.label :root
7
+ "named list of linkys"
6
8
 
7
- list.item(:su, su_path)
8
- list.item(:provision, su_path(:action => :provision))
9
- list.item(:licenses, su_licenses_path)
10
- list.item(:producers, su_producers_path)
11
- list.item(:raw, su_path(:action => :raw))
12
- list.item(:super_users, su_super_users_path)
13
- end
14
-
15
- end
9
+ and
16
10
 
11
+ "how to make one 'em active"
17
12
 
13
+ it does *not* to any htmly stuff for you
18
14
 
19
- ... in a view
20
15
 
21
- <%= nav_for :su %>
16
+ USAGE
17
+
18
+ in a controller
19
+
20
+ class ApplicationController < ActionController::Base
21
+
22
+ nav_for :main do |list|
23
+ if current_user
24
+ list.link(:home, root_path)
25
+ list.link(:test, test_path)
26
+ end
27
+
28
+ if current_user.admin?
29
+ list.link(:admin, admin_path)
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ # pass a block to list.link(...){ } to supply logic for when a link is
36
+ # active. otherwise a sane default will be built for you.
37
+
38
+ in a view
39
+
40
+ <%=
41
+
42
+ nav_{
43
+ ul_(:class => 'nav nav-pills'){
44
+ nav_for(:main).each do |link|
45
+
46
+ li_(:class => (link.active ? :active : :inactive)){
47
+ a_(:href => link.href){ link }
48
+ }
49
+
50
+ end
51
+ }
52
+ }
53
+
54
+ %>
55
+
data/lib/rails_nav.rb CHANGED
@@ -1,23 +1,119 @@
1
1
  # encoding: utf-8
2
-
3
2
  #
4
- require 'rails_current'
5
- require 'rails_helper'
6
- require 'tagz'
7
-
8
- module Nav
3
+ class Nav < ::Array
4
+ ##
5
+ #
9
6
  def Nav.version()
10
- '0.0.4'
7
+ '1.0.0'
8
+ end
9
+
10
+ def Nav.dependencies
11
+ {
12
+ 'rails_current' => [ 'rails_current' , ' >= 1.6' ],
13
+ 'rails_helper' => [ 'rails_helper' , ' >= 1.2' ]
14
+ }
15
+ end
16
+
17
+ begin
18
+ require 'rubygems'
19
+ rescue LoadError
20
+ nil
21
+ end
22
+
23
+ Nav.dependencies.each do |lib, dependency|
24
+ gem(*dependency) if defined?(gem)
25
+ require(lib)
26
+ end
27
+
28
+ ##
29
+ #
30
+ def Nav.for(*args, &block)
31
+ new(*args, &block)
32
+ end
33
+
34
+ def for(controller)
35
+ @controller = controller
36
+ build!
37
+ compute_active!
38
+ self
39
+ end
40
+
41
+ ##
42
+ #
43
+ attr_accessor(:name)
44
+ attr_accessor(:block)
45
+ attr_accessor(:controller)
46
+
47
+ def initialize(name, &block)
48
+ @name = name.to_s
49
+ @block = block
50
+ @already_computed_active = false
51
+ @controller = nil
52
+ end
53
+
54
+ def build!
55
+ @controller.instance_exec(self, &@block)
56
+ self
11
57
  end
12
58
 
13
- class Item
14
- attr_accessor(:label)
59
+ def link(*args, &block)
60
+ link = Link.new(self, *args, &block)
61
+ push(link)
62
+ link
63
+ end
64
+
65
+ ##
66
+ #
67
+ def compute_active!
68
+ weights = []
69
+
70
+ each_with_index do |link, index|
71
+ link.controller = @controller
72
+ active = link.compute_active!
73
+
74
+ weights[index] =
75
+ case active
76
+ when nil, false
77
+ -1
78
+ when true
79
+ 0
80
+ else
81
+ Integer(active)
82
+ end
83
+ end
84
+
85
+ each_with_index do |link, index|
86
+ link.active = false
87
+ end
88
+
89
+ active_link = self[weights.index(weights.max)]
90
+
91
+ active_link.active = true
92
+
93
+ self
94
+ ensure
95
+ @already_computed_active = true
96
+ end
97
+
98
+ def compute_active
99
+ compute_active! unless @already_computed_active
100
+ self
101
+ end
102
+
103
+ ##
104
+ #
105
+ class Link
106
+ attr_accessor(:nav)
107
+ attr_accessor(:controller)
108
+ attr_accessor(:content)
15
109
  attr_accessor(:options)
16
- attr_accessor(:html_options)
17
110
  attr_accessor(:pattern)
18
111
  attr_accessor(:active)
112
+ attr_accessor(:compute_active)
19
113
 
20
114
  def initialize(*args, &block)
115
+ @nav = args.grep(Nav).first and args.delete(@nav)
116
+
21
117
  options =
22
118
  if args.size == 1 and args.last.is_a?(Hash)
23
119
  args.extract_options!.to_options!
@@ -25,20 +121,31 @@
25
121
  {}
26
122
  end
27
123
 
28
- @label = options[:label] || args.shift || 'Slash'
29
- @options = options[:options] || args.shift || '/'
30
- @html_options = options[:html_options] || args.shift || {}
31
- @pattern = options[:pattern] || args.shift || default_active_pattern
32
- @active = options[:active] || block || default_active_block
124
+ @content = options[:content] || args.shift || 'Slash'
125
+ @options = options[:options] || args.shift || {}
126
+ @pattern = options[:pattern] || args.shift || Link.default_active_pattern_for(@content)
127
+ @compute_active = options[:active] || block || Link.default_active_block_for(@pattern)
128
+
129
+ @already_computed_active = nil
130
+ @active = nil
131
+ @controller = nil
33
132
  end
34
133
 
35
- def default_active_pattern
36
- %r/\b#{ label.to_s.strip.downcase.sub(/\s+/, '_') }\b/i
134
+ def to_s
135
+ content.to_s
37
136
  end
38
137
 
39
- def default_active_block
40
- pattern = @pattern
41
- proc do
138
+ def url
139
+ @controller.send(:url_for, @options)
140
+ end
141
+ alias_method(:href, :url)
142
+
143
+ def Link.default_active_pattern_for(content)
144
+ %r/\b#{ content.to_s.strip.downcase.sub(/\s+/, '_') }\b/i
145
+ end
146
+
147
+ def Link.default_active_block_for(pattern)
148
+ proc do |*args|
42
149
  path_info = request.fullpath.scan(%r{[^/]+})
43
150
  depth = -1
44
151
  matched = false
@@ -47,154 +154,51 @@
47
154
  end
48
155
  end
49
156
 
50
- def active?(&block)
51
- if block
52
- @active = block
53
- else
54
- Current.controller.instance_eval(&@active)
55
- end
56
- end
57
- alias_method('active', 'active?')
58
- alias_method('activate', 'active?')
59
- end
60
-
61
- class List < ::Array
62
- extend Tagz.globally
63
- include Tagz.globally
64
-
65
- def item(*args, &block)
66
- push(Nav::Item.new(*args, &block))
67
- end
68
- %w( add nav tab ).each{|dst| alias_method(dst, 'item')}
69
-
70
- %w( name label ).each do |attr|
71
- module_eval <<-__
72
- def #{ attr }(*args)
73
- @#{ attr } = args.join(' ') unless args.blank?
74
- @#{ attr }
75
- end
76
- alias_method('#{ attr }=', '#{ attr }')
77
- __
78
- end
79
-
80
- def options(opts = {})
81
- (@options ||= Map.new).tap{|options| options.update(opts)}
82
- end
83
-
84
- def to_html(*args, &block)
85
- List.to_html(self, *args, &block)
157
+ def compute_active!
158
+ block = @compute_active
159
+ args = [self].slice(0 .. (block.arity < 0 ? -1 : block.arity))
160
+ @active = @controller.send(:instance_exec, *args, &block)
161
+ ensure
162
+ @already_computed_active = true
86
163
  end
87
- alias_method(:to_s, :to_html)
88
164
 
89
- def List.strategy(*value)
90
- @strategy ||= (value.first || :dl).to_s
165
+ def compute_active
166
+ compute_active! unless @already_computed_active
167
+ @active
91
168
  end
92
169
 
93
- def List.strategy=(value)
94
- @strategy = value.first.to_s
95
- end
96
-
97
- def List.to_html(*args, &block)
98
- list = args.shift
99
- options = args.extract_options!.to_options!
100
- weights = []
101
-
102
- list.each_with_index do |item, index|
103
- is_active = item.active?
104
- weights[index] = case is_active
105
- when nil, false then 0
106
- when true then 1
107
- else Integer(is_active)
108
- end
109
- end
110
-
111
- active = Array.new(weights.size){ false }
112
- active[weights.index(weights.max)] = true
113
-
114
- helper = Helper.new
115
-
116
- if list.name
117
- options[:id] ||= list.name
118
- options[:class] = [options[:class], list.name].join(' ')
119
- end
120
-
121
- options.update(list.options)
122
-
123
- list_ = List.strategy =~ /dl/ ? :dl_ : :ul_
124
- item_ = List.strategy =~ /dl/ ? :dd_ : :li_
125
-
126
- nav_(options){
127
- unless List.strategy =~ /dl/
128
- label_{ list.label } unless list.label.blank?
129
- end
130
-
131
- send(list_){
132
- first_index = 0
133
- last_index = list.size - 1
134
-
135
- if List.strategy =~ /dl/
136
- dt_{ list.label } unless list.label.blank?
137
- end
138
-
139
- list.each_with_index do |element, index|
140
- css_id = "nav-#{ index }"
141
- css_class = active[index] ? 'active' : 'inactive'
142
- css_class += ' nav'
143
- css_class += ' first' if index == first_index
144
- css_class += ' last' if index == last_index
145
-
146
- send(item_, :id => css_id, :class => css_class){
147
- options = element.html_options || {}
148
- options[:href] = helper.url_for(element.options)
149
- options[:class] = active[index] ? 'active' : ''
150
- a_(options){ element.label }
151
- }
152
- end
153
- }
154
- }
170
+ def active?
171
+ !!@active
155
172
  end
156
173
  end
157
174
  end
158
175
 
159
176
  # factored out mixin for controllers/views
160
177
  #
161
- module Nav
162
- def Nav.extend_action_controller!
163
- if defined?(::ActionController::Base)
164
- ::ActionController::Base.module_eval do
165
- class << self
166
- def nav(*args, &block)
167
- options = args.extract_options!.to_options!
168
- name = args.first || options[:name] || :main
169
- nav_name = [:nav, name].join('_')
170
- args.push(options)
171
-
172
- define_method(nav_name) do
173
- nav_list = Nav::List.new
174
- instance_exec(nav_list, &block)
175
- nav_list.name = name
176
- nav_list
177
- end
178
-
179
- protected(nav_name)
180
- end
181
- alias_method(:nav_for, :nav)
178
+ def Nav.extend_action_controller!
179
+ if defined?(::ActionController::Base)
180
+ ::ActionController::Base.module_eval do
181
+ class << self
182
+ def nav_for(*args, &block)
183
+ options = args.extract_options!.to_options!
184
+ name = args.first || options[:name] || :main
185
+ which_nav = [:nav, name].join('_')
186
+
187
+ define_method(which_nav){ Nav.for(name, &block) }
188
+
189
+ protected(which_nav)
182
190
  end
191
+ alias_method(:nav, :nav_for)
192
+ end
183
193
 
184
- helper do
185
- def nav(*args, &block)
186
- options = args.extract_options!.to_options!
187
- name = args.first || options[:name] || :main
188
- nav_name = [:nav, name].join('_')
189
- args.push(options)
190
-
191
- if controller.respond_to?(nav_name)
192
- nav = controller.send(nav_name)
193
- nav.to_html(*args, &block)
194
- end
195
- end
196
- alias_method(:nav_for, :nav)
194
+ helper do
195
+ def nav_for(*args, &block)
196
+ options = args.extract_options!.to_options!
197
+ name = args.first || options[:name] || :main
198
+ which_nav = [:nav, name].join('_')
199
+ nav = controller.send(which_nav).for(controller)
197
200
  end
201
+ alias_method(:nav, :nav_for)
198
202
  end
199
203
  end
200
204
  end
@@ -213,3 +217,4 @@
213
217
  end
214
218
 
215
219
  Rails_nav = Nav
220
+ Nav
data/rails_nav.gemspec CHANGED
@@ -3,18 +3,13 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "rails_nav"
6
- spec.version = "0.0.4"
6
+ spec.version = "1.0.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "rails_nav"
9
9
  spec.description = "description: rails_nav kicks the ass"
10
10
 
11
11
  spec.files =
12
- ["README",
13
- "Rakefile",
14
- "lib",
15
- "lib/rails_nav.rb",
16
- "nav.html",
17
- "rails_nav.gemspec"]
12
+ ["README", "Rakefile", "lib", "lib/rails_nav.rb", "rails_nav.gemspec"]
18
13
 
19
14
  spec.executables = []
20
15
 
@@ -23,6 +18,10 @@ Gem::Specification::new do |spec|
23
18
  spec.test_files = nil
24
19
 
25
20
 
21
+ spec.add_dependency(*["rails_current", " >= 1.6"])
22
+
23
+ spec.add_dependency(*["rails_helper", " >= 1.2"])
24
+
26
25
 
27
26
  spec.extensions.push(*[])
28
27
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_nav
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-31 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2012-03-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails_current
16
+ requirement: &70363954688740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '1.6'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70363954688740
25
+ - !ruby/object:Gem::Dependency
26
+ name: rails_helper
27
+ requirement: &70363954688240 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '1.2'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70363954688240
14
36
  description: ! 'description: rails_nav kicks the ass'
15
37
  email: ara.t.howard@gmail.com
16
38
  executables: []
@@ -20,7 +42,6 @@ files:
20
42
  - README
21
43
  - Rakefile
22
44
  - lib/rails_nav.rb
23
- - nav.html
24
45
  - rails_nav.gemspec
25
46
  homepage: https://github.com/ahoward/rails_nav
26
47
  licenses: []
data/nav.html DELETED
@@ -1,7 +0,0 @@
1
- <nav>
2
- <label></label>
3
- <ul>
4
- <li></li>
5
- <li></li>
6
- </ul>
7
- </nav>