rails_nav 0.0.1

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 +21 -0
  2. data/Rakefile +390 -0
  3. data/lib/rails_nav.rb +198 -0
  4. data/rails_nav.gemspec +28 -0
  5. metadata +48 -0
data/README ADDED
@@ -0,0 +1,21 @@
1
+
2
+ class FooController
3
+
4
+ nav_for :su do |list|
5
+ list.label :root
6
+
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
16
+
17
+
18
+
19
+ ... in a view
20
+
21
+ <%= nav_for :su %>
data/Rakefile ADDED
@@ -0,0 +1,390 @@
1
+ This.rubyforge_project = 'codeforpeople'
2
+ This.author = "Ara T. Howard"
3
+ This.email = "ara.t.howard@gmail.com"
4
+ This.homepage = "https://github.com/ahoward/#{ This.lib }"
5
+
6
+
7
+ task :default do
8
+ puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
9
+ end
10
+
11
+ task :test do
12
+ run_tests!
13
+ end
14
+
15
+ namespace :test do
16
+ task(:unit){ run_tests!(:unit) }
17
+ task(:functional){ run_tests!(:functional) }
18
+ task(:integration){ run_tests!(:integration) }
19
+ end
20
+
21
+ def run_tests!(which = nil)
22
+ which ||= '**'
23
+ test_dir = File.join(This.dir, "test")
24
+ test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
25
+ test_rbs = Dir.glob(test_glob).sort
26
+
27
+ div = ('=' * 119)
28
+ line = ('-' * 119)
29
+
30
+ test_rbs.each_with_index do |test_rb, index|
31
+ testno = index + 1
32
+ command = "#{ File.basename(This.ruby) } -I ./lib -I ./test/lib #{ test_rb }"
33
+
34
+ puts
35
+ say(div, :color => :cyan, :bold => true)
36
+ say("@#{ testno } => ", :bold => true, :method => :print)
37
+ say(command, :color => :cyan, :bold => true)
38
+ say(line, :color => :cyan, :bold => true)
39
+
40
+ system(command)
41
+
42
+ say(line, :color => :cyan, :bold => true)
43
+
44
+ status = $?.exitstatus
45
+
46
+ if status.zero?
47
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
48
+ say("SUCCESS", :color => :green, :bold => true)
49
+ else
50
+ say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
51
+ say("FAILURE", :color => :red, :bold => true)
52
+ end
53
+ say(line, :color => :cyan, :bold => true)
54
+
55
+ exit(status) unless status.zero?
56
+ end
57
+ end
58
+
59
+
60
+ task :gemspec do
61
+ ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
62
+ ignore_directories = ['pkg']
63
+ ignore_files = ['test/log', 'a.rb'] + Dir['db/*'] + %w'db'
64
+
65
+ shiteless =
66
+ lambda do |list|
67
+ list.delete_if do |entry|
68
+ next unless test(?e, entry)
69
+ extension = File.basename(entry).split(%r/[.]/).last
70
+ ignore_extensions.any?{|ext| ext === extension}
71
+ end
72
+ list.delete_if do |entry|
73
+ next unless test(?d, entry)
74
+ dirname = File.expand_path(entry)
75
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
76
+ end
77
+ list.delete_if do |entry|
78
+ next unless test(?f, entry)
79
+ filename = File.expand_path(entry)
80
+ ignore_files.any?{|file| File.expand_path(file) == filename}
81
+ end
82
+ end
83
+
84
+ lib = This.lib
85
+ object = This.object
86
+ version = This.version
87
+ files = shiteless[Dir::glob("**/**")]
88
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
89
+ #has_rdoc = true #File.exist?('doc')
90
+ test_files = test(?e, "test/#{ lib }.rb") ? "test/#{ lib }.rb" : nil
91
+ summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
92
+ description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
93
+
94
+ if This.extensions.nil?
95
+ This.extensions = []
96
+ extensions = This.extensions
97
+ %w( Makefile configure extconf.rb ).each do |ext|
98
+ extensions << ext if File.exists?(ext)
99
+ end
100
+ end
101
+ extensions = [extensions].flatten.compact
102
+
103
+ # TODO
104
+ if This.dependencies.nil?
105
+ dependencies = []
106
+ else
107
+ case This.dependencies
108
+ when Hash
109
+ dependencies = This.dependencies.values
110
+ when Array
111
+ dependencies = This.dependencies
112
+ end
113
+ end
114
+
115
+ template =
116
+ if test(?e, 'gemspec.erb')
117
+ Template{ IO.read('gemspec.erb') }
118
+ else
119
+ Template {
120
+ <<-__
121
+ ## <%= lib %>.gemspec
122
+ #
123
+
124
+ Gem::Specification::new do |spec|
125
+ spec.name = <%= lib.inspect %>
126
+ spec.version = <%= version.inspect %>
127
+ spec.platform = Gem::Platform::RUBY
128
+ spec.summary = <%= lib.inspect %>
129
+ spec.description = <%= description.inspect %>
130
+
131
+ spec.files =\n<%= files.sort.pretty_inspect %>
132
+ spec.executables = <%= executables.inspect %>
133
+
134
+ spec.require_path = "lib"
135
+
136
+ spec.test_files = <%= test_files.inspect %>
137
+
138
+ <% dependencies.each do |lib_version| %>
139
+ spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
140
+ <% end %>
141
+
142
+ spec.extensions.push(*<%= extensions.inspect %>)
143
+
144
+ spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
145
+ spec.author = <%= This.author.inspect %>
146
+ spec.email = <%= This.email.inspect %>
147
+ spec.homepage = <%= This.homepage.inspect %>
148
+ end
149
+ __
150
+ }
151
+ end
152
+
153
+ Fu.mkdir_p(This.pkgdir)
154
+ gemspec = "#{ lib }.gemspec"
155
+ open(gemspec, "w"){|fd| fd.puts(template)}
156
+ This.gemspec = gemspec
157
+ end
158
+
159
+ task :gem => [:clean, :gemspec] do
160
+ Fu.mkdir_p(This.pkgdir)
161
+ before = Dir['*.gem']
162
+ cmd = "gem build #{ This.gemspec }"
163
+ `#{ cmd }`
164
+ after = Dir['*.gem']
165
+ gem = ((after - before).first || after.first) or abort('no gem!')
166
+ Fu.mv(gem, This.pkgdir)
167
+ This.gem = File.join(This.pkgdir, File.basename(gem))
168
+ end
169
+
170
+ task :readme do
171
+ samples = ''
172
+ prompt = '~ > '
173
+ lib = This.lib
174
+ version = This.version
175
+
176
+ Dir['sample*/*'].sort.each do |sample|
177
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
178
+
179
+ cmd = "cat #{ sample }"
180
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
181
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
182
+
183
+ cmd = "ruby #{ sample }"
184
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
185
+
186
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
187
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
188
+ end
189
+
190
+ template =
191
+ if test(?e, 'readme.erb')
192
+ Template{ IO.read('readme.erb') }
193
+ else
194
+ Template {
195
+ <<-__
196
+ NAME
197
+ #{ lib }
198
+
199
+ DESCRIPTION
200
+
201
+ INSTALL
202
+ gem install #{ lib }
203
+
204
+ SAMPLES
205
+ #{ samples }
206
+ __
207
+ }
208
+ end
209
+
210
+ open("README", "w"){|fd| fd.puts template}
211
+ end
212
+
213
+
214
+ task :clean do
215
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
216
+ end
217
+
218
+
219
+ task :release => [:clean, :gemspec, :gem] do
220
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
221
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
222
+ raise "no gems?" if gems.size < 1
223
+
224
+ cmd = "gem push #{ This.gem }"
225
+ puts cmd
226
+ puts
227
+ system(cmd)
228
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
229
+
230
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
231
+ puts cmd
232
+ puts
233
+ system(cmd)
234
+ abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
235
+ end
236
+
237
+
238
+
239
+
240
+
241
+ BEGIN {
242
+ # support for this rakefile
243
+ #
244
+ $VERBOSE = nil
245
+
246
+ require 'ostruct'
247
+ require 'erb'
248
+ require 'fileutils'
249
+ require 'rbconfig'
250
+ require 'pp'
251
+
252
+ # fu shortcut
253
+ #
254
+ Fu = FileUtils
255
+
256
+ # cache a bunch of stuff about this rakefile/environment
257
+ #
258
+ This = OpenStruct.new
259
+
260
+ This.file = File.expand_path(__FILE__)
261
+ This.dir = File.dirname(This.file)
262
+ This.pkgdir = File.join(This.dir, 'pkg')
263
+
264
+ # grok lib
265
+ #
266
+ lib = ENV['LIB']
267
+ unless lib
268
+ lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
269
+ end
270
+ This.lib = lib
271
+
272
+ # grok version
273
+ #
274
+ version = ENV['VERSION']
275
+ unless version
276
+ require "./lib/#{ This.lib }"
277
+ This.name = lib.capitalize
278
+ This.object = eval(This.name)
279
+ version = This.object.send(:version)
280
+ end
281
+ This.version = version
282
+
283
+ # see if dependencies are export by the module
284
+ #
285
+ if This.object.respond_to?(:dependencies)
286
+ This.dependencies = This.object.dependencies
287
+ end
288
+
289
+ # we need to know the name of the lib an it's version
290
+ #
291
+ abort('no lib') unless This.lib
292
+ abort('no version') unless This.version
293
+
294
+ # discover full path to this ruby executable
295
+ #
296
+ c = RbConfig::CONFIG
297
+ bindir = c["bindir"] || c['BINDIR']
298
+ ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
299
+ ruby_ext = c['EXEEXT'] || ''
300
+ ruby = File.join(bindir, (ruby_install_name + ruby_ext))
301
+ This.ruby = ruby
302
+
303
+ # some utils
304
+ #
305
+ module Util
306
+ def indent(s, n = 2)
307
+ s = unindent(s)
308
+ ws = ' ' * n
309
+ s.gsub(%r/^/, ws)
310
+ end
311
+
312
+ def unindent(s)
313
+ indent = nil
314
+ s.each_line do |line|
315
+ next if line =~ %r/^\s*$/
316
+ indent = line[%r/^\s*/] and break
317
+ end
318
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
319
+ end
320
+ extend self
321
+ end
322
+
323
+ # template support
324
+ #
325
+ class Template
326
+ def initialize(&block)
327
+ @block = block
328
+ @template = block.call.to_s
329
+ end
330
+ def expand(b=nil)
331
+ ERB.new(Util.unindent(@template)).result((b||@block).binding)
332
+ end
333
+ alias_method 'to_s', 'expand'
334
+ end
335
+ def Template(*args, &block) Template.new(*args, &block) end
336
+
337
+ # colored console output support
338
+ #
339
+ This.ansi = {
340
+ :clear => "\e[0m",
341
+ :reset => "\e[0m",
342
+ :erase_line => "\e[K",
343
+ :erase_char => "\e[P",
344
+ :bold => "\e[1m",
345
+ :dark => "\e[2m",
346
+ :underline => "\e[4m",
347
+ :underscore => "\e[4m",
348
+ :blink => "\e[5m",
349
+ :reverse => "\e[7m",
350
+ :concealed => "\e[8m",
351
+ :black => "\e[30m",
352
+ :red => "\e[31m",
353
+ :green => "\e[32m",
354
+ :yellow => "\e[33m",
355
+ :blue => "\e[34m",
356
+ :magenta => "\e[35m",
357
+ :cyan => "\e[36m",
358
+ :white => "\e[37m",
359
+ :on_black => "\e[40m",
360
+ :on_red => "\e[41m",
361
+ :on_green => "\e[42m",
362
+ :on_yellow => "\e[43m",
363
+ :on_blue => "\e[44m",
364
+ :on_magenta => "\e[45m",
365
+ :on_cyan => "\e[46m",
366
+ :on_white => "\e[47m"
367
+ }
368
+ def say(phrase, *args)
369
+ options = args.last.is_a?(Hash) ? args.pop : {}
370
+ options[:color] = args.shift.to_s.to_sym unless args.empty?
371
+ keys = options.keys
372
+ keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
373
+
374
+ color = options[:color]
375
+ bold = options.has_key?(:bold)
376
+
377
+ parts = [phrase]
378
+ parts.unshift(This.ansi[color]) if color
379
+ parts.unshift(This.ansi[:bold]) if bold
380
+ parts.push(This.ansi[:clear]) if parts.size > 1
381
+
382
+ method = options[:method] || :puts
383
+
384
+ Kernel.send(method, parts.join)
385
+ end
386
+
387
+ # always run out of the project dir
388
+ #
389
+ Dir.chdir(This.dir)
390
+ }
data/lib/rails_nav.rb ADDED
@@ -0,0 +1,198 @@
1
+ # encoding: utf-8
2
+
3
+ #
4
+ require 'rails_current'
5
+ require 'rails_helper'
6
+ require 'tagz'
7
+
8
+ module Nav
9
+ def Nav.version()
10
+ '0.0.1'
11
+ end
12
+
13
+ class Item
14
+ attr_accessor(:label)
15
+ attr_accessor(:options)
16
+ attr_accessor(:html_options)
17
+ attr_accessor(:pattern)
18
+ attr_accessor(:active)
19
+
20
+ def initialize(*args, &block)
21
+ options =
22
+ if args.size == 1 and args.last.is_a?(Hash)
23
+ args.extract_options!.to_options!
24
+ else
25
+ {}
26
+ end
27
+
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
33
+ end
34
+
35
+ def default_active_pattern
36
+ %r/\b#{ label.to_s.strip.downcase.sub(/\s+/, '_') }\b/i
37
+ end
38
+
39
+ def default_active_block
40
+ pattern = @pattern
41
+ proc do
42
+ path_info = request.fullpath.scan(%r{[^/]+})
43
+ depth = -1
44
+ matched = false
45
+ path_info.each{|path| depth += 1; break if(matched = path =~ pattern)}
46
+ weight = matched ? depth : nil
47
+ end
48
+ end
49
+
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)
86
+ end
87
+ alias_method(:to_s, :to_html)
88
+
89
+ def List.to_html(*args, &block)
90
+ list = args.shift
91
+ options = args.extract_options!.to_options!
92
+ weights = []
93
+
94
+ list.each_with_index do |item, index|
95
+ is_active = item.active?
96
+ weights[index] = case is_active
97
+ when nil, false then 0
98
+ when true then 1
99
+ else Integer(is_active)
100
+ end
101
+ end
102
+
103
+ active = Array.new(weights.size){ false }
104
+ active[weights.index(weights.max)] = true
105
+
106
+ helper = Helper.new
107
+
108
+ if list.name
109
+ options[:id] ||= list.name
110
+ options[:class] = [options[:class], list.name].join(' ')
111
+ end
112
+
113
+ options.update(list.options)
114
+
115
+ nav_(options){
116
+ dl_{
117
+ first_index = 0
118
+ last_index = list.size - 1
119
+
120
+ dt_{ list.label } unless list.label.blank?
121
+
122
+ list.each_with_index do |element, index|
123
+ css_id = "nav-#{ index }"
124
+ css_class = active[index] ? 'active' : 'inactive'
125
+ css_class += ' nav'
126
+ css_class += ' first' if index == first_index
127
+ css_class += ' last' if index == last_index
128
+
129
+ dd_(:id => css_id, :class => css_class){
130
+ options = element.html_options || {}
131
+ options[:href] = helper.url_for(element.options)
132
+ options[:class] = active[index] ? 'active' : ''
133
+ a_(options){ element.label }
134
+ }
135
+ end
136
+ }
137
+ }
138
+ end
139
+ end
140
+ end
141
+
142
+ # factored out mixin for controllers/views
143
+ #
144
+ module Nav
145
+ def Nav.extend_action_controller!
146
+ if defined?(::ActionController::Base)
147
+ ::ActionController::Base.module_eval do
148
+ class << self
149
+ def nav(*args, &block)
150
+ options = args.extract_options!.to_options!
151
+ name = args.first || options[:name] || :main
152
+ nav_name = [:nav, name].join('_')
153
+ args.push(options)
154
+
155
+ define_method(nav_name) do
156
+ nav_list = Nav::List.new
157
+ instance_exec(nav_list, &block)
158
+ nav_list.name = name
159
+ nav_list
160
+ end
161
+
162
+ protected(nav_name)
163
+ end
164
+ alias_method(:nav_for, :nav)
165
+ end
166
+
167
+ helper do
168
+ def nav(*args, &block)
169
+ options = args.extract_options!.to_options!
170
+ name = args.first || options[:name] || :main
171
+ nav_name = [:nav, name].join('_')
172
+ args.push(options)
173
+
174
+ if controller.respond_to?(nav_name)
175
+ nav = controller.send(nav_name)
176
+ nav.to_html(*args, &block)
177
+ end
178
+ end
179
+ alias_method(:nav_for, :nav)
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ if defined?(Rails::Engine)
187
+ class Engine < Rails::Engine
188
+ config.before_initialize do
189
+ ActiveSupport.on_load(:action_controller) do
190
+ Nav.extend_action_controller!
191
+ end
192
+ end
193
+ end
194
+ else
195
+ Nav.extend_action_controller!
196
+ end
197
+
198
+ Rails_nav = Nav
data/rails_nav.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ ## rails_nav.gemspec
2
+ #
3
+
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "rails_nav"
6
+ spec.version = "0.0.1"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "rails_nav"
9
+ spec.description = "description: rails_nav kicks the ass"
10
+
11
+ spec.files =
12
+ ["README", "Rakefile", "lib", "lib/rails_nav.rb", "rails_nav.gemspec"]
13
+
14
+ spec.executables = []
15
+
16
+ spec.require_path = "lib"
17
+
18
+ spec.test_files = nil
19
+
20
+
21
+
22
+ spec.extensions.push(*[])
23
+
24
+ spec.rubyforge_project = "codeforpeople"
25
+ spec.author = "Ara T. Howard"
26
+ spec.email = "ara.t.howard@gmail.com"
27
+ spec.homepage = "https://github.com/ahoward/rails_nav"
28
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_nav
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ara T. Howard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-28 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: ! 'description: rails_nav kicks the ass'
15
+ email: ara.t.howard@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README
21
+ - Rakefile
22
+ - lib/rails_nav.rb
23
+ - rails_nav.gemspec
24
+ homepage: https://github.com/ahoward/rails_nav
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project: codeforpeople
44
+ rubygems_version: 1.8.11
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: rails_nav
48
+ test_files: []