rails_nav 1.2.0 → 1.3.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 (3) hide show
  1. data/lib/rails_nav.rb +125 -48
  2. data/rails_nav.gemspec +1 -1
  3. metadata +3 -3
data/lib/rails_nav.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # encoding: utf-8
2
2
  #
3
+ require 'erb'
4
+
3
5
  class Nav < ::Array
4
6
  ##
5
7
  #
6
8
  def Nav.version()
7
- '1.2.0'
9
+ '1.3.0'
8
10
  end
9
11
 
10
12
  def Nav.dependencies
@@ -25,12 +27,24 @@
25
27
  require(lib)
26
28
  end
27
29
 
28
- ##
30
+ # for use in a controller
31
+ #
32
+ # nav_for(:main) do |nav|
33
+ #
34
+ # nav.link 'Home', root_path
35
+ #
36
+ # end
29
37
  #
30
38
  def Nav.for(*args, &block)
31
- new(*args, &block).tap{|nav| nav.strategy = :instance_exec}
39
+ new(*args, &block).tap do |nav|
40
+ nav.strategy = :instance_exec
41
+ end
32
42
  end
33
43
 
44
+ # for use in a view
45
+ #
46
+ # <%= nav_for(:main) %>
47
+ #
34
48
  def for(controller)
35
49
  @controller = controller
36
50
  build!
@@ -38,6 +52,28 @@
38
52
  self
39
53
  end
40
54
 
55
+ # for use when the controller instance is available *now*
56
+ #
57
+ # Nav.create do |nav|
58
+ #
59
+ # nav.link 'Home', root_path
60
+ #
61
+ # end
62
+ #
63
+ def Nav.build(*args, &block)
64
+ if defined?(::ActionController::Base)
65
+ controller = args.grep(::ActionController::Base).first
66
+ args.delete(controller)
67
+ end
68
+
69
+ new(*args, &block).tap do |nav|
70
+ nav.strategy = :call
71
+ nav.controller = controller || Current.controller || Current.mock_controller
72
+ nav.build!
73
+ nav.compute_active!
74
+ end
75
+ end
76
+
41
77
  ##
42
78
  #
43
79
  attr_accessor(:name)
@@ -45,7 +81,7 @@
45
81
  attr_accessor(:controller)
46
82
  attr_accessor(:strategy)
47
83
 
48
- def initialize(name = :nav, &block)
84
+ def initialize(name = :main, &block)
49
85
  @name = name.to_s
50
86
  @block = block
51
87
  @already_computed_active = false
@@ -53,15 +89,13 @@
53
89
  @strategy = :call
54
90
  end
55
91
 
92
+ def evaluate(block, *args)
93
+ args = args.slice(0 .. (block.arity < 0 ? -1 : block.arity))
94
+ @strategy == :instance_exec ? @controller.instance_exec(*args, &block) : block.call(*args)
95
+ end
96
+
56
97
  def build!
57
- nav = self
58
- case @strategy
59
- when :instance_exec
60
- @controller.instance_exec(nav, &@block)
61
- when :call
62
- @block.call(nav)
63
- end
64
- nav
98
+ evaluate(@block, nav = self)
65
99
  end
66
100
 
67
101
  def link(*args, &block)
@@ -71,8 +105,6 @@
71
105
  link
72
106
  end
73
107
 
74
- ##
75
- #
76
108
  def compute_active!
77
109
  unless empty?
78
110
  weights = []
@@ -111,6 +143,55 @@
111
143
  self
112
144
  end
113
145
 
146
+ def request
147
+ @controller.send(:request)
148
+ end
149
+
150
+ def fullpath
151
+ request.fullpath
152
+ end
153
+
154
+ def path_info
155
+ path_info = fullpath.scan(%r{[^/]+})
156
+ end
157
+
158
+ class Template < ::String
159
+ def initialize(template = nil, &block)
160
+ @erb = ERB.new(template || block.call)
161
+ @binding = block.binding
162
+ end
163
+
164
+ def render
165
+ @erb.result(@binding)
166
+ end
167
+ end
168
+
169
+ def template
170
+ @template ||= Template.new do
171
+ <<-__
172
+ <nav class="nav-<%= name %>">
173
+ <ul>
174
+ <% each do |link| %>
175
+ <li class="<%= link.active ? :active : :inactive %>">
176
+ <a href="<%= link.url %>" class="<%= link.active ? :active : :inactive %>"><%= link.content %></a>
177
+ </li>
178
+ <% end %>
179
+ </ul>
180
+ </nav>
181
+ __
182
+ end
183
+ end
184
+
185
+ def template=(template)
186
+ @template = Template.new(template.to_s){}
187
+ end
188
+
189
+ def to_html
190
+ template.render
191
+ end
192
+
193
+ alias_method(:to_s, :to_html)
194
+
114
195
  ##
115
196
  #
116
197
  class Link
@@ -122,8 +203,8 @@
122
203
  attr_accessor(:active)
123
204
  attr_accessor(:compute_active)
124
205
 
125
- def initialize(*args, &block)
126
- @nav = args.grep(Nav).first and args.delete(@nav)
206
+ def initialize(nav, *args, &block)
207
+ @nav = nav
127
208
 
128
209
  options =
129
210
  if args.size == 1 and args.last.is_a?(Hash)
@@ -139,55 +220,53 @@
139
220
 
140
221
  @already_computed_active = nil
141
222
  @active = nil
142
- @controller = nil
143
223
  end
144
224
 
145
- def to_s
146
- content.to_s
225
+ def compute_active!
226
+ @active = @nav.evaluate(@compute_active, link = self)
227
+ ensure
228
+ @already_computed_active = true
229
+ end
230
+
231
+ def compute_active
232
+ compute_active! unless @already_computed_active
233
+ @active
234
+ end
235
+
236
+ def active?
237
+ !!@active
238
+ end
239
+
240
+ %w( controller request fullpath path_info ).each do |method|
241
+ class_eval <<-__, __FILE__, __LINE__
242
+ def #{ method }(*args, &block)
243
+ @nav.#{ method }(*args, &block)
244
+ end
245
+ __
147
246
  end
148
247
 
149
248
  def url
150
- @controller.send(:url_for, @options)
249
+ controller.send(:url_for, @options)
151
250
  end
152
251
  alias_method(:href, :url)
153
252
 
253
+ def to_s
254
+ content.to_s
255
+ end
256
+
154
257
  def Link.default_active_pattern_for(content)
155
258
  %r/\b#{ content.to_s.strip.downcase.sub(/\s+/, '_') }\b/i
156
259
  end
157
260
 
158
261
  def Link.default_active_block_for(pattern)
159
- proc do |*args|
160
- path_info = request.fullpath.scan(%r{[^/]+})
262
+ proc do |link|
263
+ path_info = link.path_info
161
264
  depth = -1
162
265
  matched = false
163
266
  path_info.each{|path| depth += 1; break if(matched = path =~ pattern)}
164
267
  weight = matched ? depth : nil
165
268
  end
166
269
  end
167
-
168
- def compute_active!
169
- block = @compute_active
170
- args = [self].slice(0 .. (block.arity < 0 ? -1 : block.arity))
171
-
172
- @active =
173
- case @nav.strategy
174
- when :instance_exec
175
- @controller.send(:instance_exec, *args, &block)
176
- when :call
177
- block.call(*args)
178
- end
179
- ensure
180
- @already_computed_active = true
181
- end
182
-
183
- def compute_active
184
- compute_active! unless @already_computed_active
185
- @active
186
- end
187
-
188
- def active?
189
- !!@active
190
- end
191
270
  end
192
271
  end
193
272
 
@@ -201,9 +280,7 @@
201
280
  options = args.extract_options!.to_options!
202
281
  name = args.first || options[:name] || :main
203
282
  which_nav = [:nav, name].join('_')
204
-
205
283
  define_method(which_nav){ Nav.for(name, &block) }
206
-
207
284
  protected(which_nav)
208
285
  end
209
286
  alias_method(:nav, :nav_for)
data/rails_nav.gemspec CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "rails_nav"
6
- spec.version = "1.2.0"
6
+ spec.version = "1.3.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "rails_nav"
9
9
  spec.description = "description: rails_nav kicks the ass"
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: 1.2.0
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-28 00:00:00.000000000 Z
12
+ date: 2012-06-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails_current
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  version: '0'
74
74
  requirements: []
75
75
  rubyforge_project: codeforpeople
76
- rubygems_version: 1.8.23
76
+ rubygems_version: 1.8.24
77
77
  signing_key:
78
78
  specification_version: 3
79
79
  summary: rails_nav