rails_nav 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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