rails_nav 0.0.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>