jonuts-merb-menus 0.0.5 → 0.0.6
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.
- data/Rakefile +8 -7
- data/lib/merb-menus/item.rb +32 -0
- data/lib/merb-menus/menu.rb +118 -0
- data/lib/merb-menus/merb_controller.rb +100 -0
- data/lib/merb-menus/merbtasks.rb +6 -0
- data/lib/merb-menus/rule.rb +39 -0
- data/lib/merb-menus/submenu.rb +45 -0
- data/lib/merb-menus/version.rb +10 -0
- data/lib/merb-menus.rb +51 -0
- metadata +12 -4
data/Rakefile
CHANGED
@@ -4,15 +4,16 @@ require 'rake/gempackagetask'
|
|
4
4
|
require 'merb-core'
|
5
5
|
require 'merb-core/tasks/merb'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
require File.dirname(__FILE__) + '/lib/merb-menus/version'
|
8
|
+
|
9
|
+
GEM_NAME = "merb-menus"
|
10
|
+
GEM_VERSION = Merb::Menus::VERSION
|
11
|
+
AUTHOR = "jonah honeyman"
|
12
|
+
EMAIL = "jonah@honeyman.org"
|
13
|
+
HOMEPAGE = "http://github.com/jonuts/merb-menus"
|
14
|
+
SUMMARY = "Merb plugin that provides dot dot dot uh menus"
|
13
15
|
|
14
16
|
spec = Gem::Specification.new do |s|
|
15
|
-
s.rubyforge_project = 'merb'
|
16
17
|
s.name = GEM_NAME
|
17
18
|
s.version = GEM_VERSION
|
18
19
|
s.platform = Gem::Platform::RUBY
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Merb::Menus
|
2
|
+
class Item
|
3
|
+
def initialize(opts)
|
4
|
+
@submenu = opts[:submenu]
|
5
|
+
@name = opts[:name]
|
6
|
+
@anchor = opts[:anchor] || build_anchor
|
7
|
+
@href = opts[:href] || build_url
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :name, :anchor, :href, :submenu
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
"<Merb::Menus::Item> - name~>#{name}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
anchor.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def build_url
|
23
|
+
submenu.url_generator.rule.call(@submenu.name,@name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_anchor
|
27
|
+
submenu.display_style.rule.call(@name)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Merb::Menus
|
2
|
+
|
3
|
+
# This is the top level menu
|
4
|
+
#
|
5
|
+
# ==== Usage
|
6
|
+
# Generate a menu in a controller:
|
7
|
+
#
|
8
|
+
# create_menu :main_menu do
|
9
|
+
# # add some display styles
|
10
|
+
# display_style(:splitncap) {|thing| thing.to_s.split("_").map{|e| e.capitalize}.join(" ")}
|
11
|
+
# display_style(:dollarify) {|thing| "$#{thing.to_s.gsub(/_/,',')}"}
|
12
|
+
# default_display_style :splitncap
|
13
|
+
#
|
14
|
+
# # define all of the submenus with their individual items
|
15
|
+
# submenu :videos do
|
16
|
+
# item :home, :url => '/videos'
|
17
|
+
#
|
18
|
+
# #this item will be generated with href '/videos/humor' and text 'Humor'
|
19
|
+
# item :humor
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# submenu :audio do
|
23
|
+
# display_style :dollarify
|
24
|
+
#
|
25
|
+
# item :home, :href => '/audio'
|
26
|
+
# item :humor, :anchor => "LOL!!!"
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
#
|
31
|
+
class Menu
|
32
|
+
extend Enumerable
|
33
|
+
|
34
|
+
class << self
|
35
|
+
attr_reader :collection
|
36
|
+
|
37
|
+
def each
|
38
|
+
@collection.each{|i| yield i}
|
39
|
+
end
|
40
|
+
|
41
|
+
def [](name)
|
42
|
+
find{|e| e.name == name}
|
43
|
+
end
|
44
|
+
|
45
|
+
def first
|
46
|
+
@collection.first
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset
|
50
|
+
each{ |e| e.submenus.each{ |menu| menu.current_item = nil} ; e.current_submenu = nil}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
@collection ||= []
|
55
|
+
|
56
|
+
def initialize(name, is_default=false)
|
57
|
+
@name = name
|
58
|
+
@is_default = is_default
|
59
|
+
@submenus = []
|
60
|
+
create_default_rules
|
61
|
+
use_display_style :default
|
62
|
+
use_url_generator :default
|
63
|
+
add_self_to_collection
|
64
|
+
end
|
65
|
+
|
66
|
+
attr_accessor :current_submenu, :default_display_style, :default_url_generator
|
67
|
+
attr_reader :name, :submenus
|
68
|
+
|
69
|
+
def submenu(name, opts={}, &blk)
|
70
|
+
submenu = Submenu.new(name, self, opts)
|
71
|
+
submenu.instance_eval(&blk)
|
72
|
+
@submenus << submenu
|
73
|
+
self
|
74
|
+
end
|
75
|
+
|
76
|
+
def display_style(key, &rule)
|
77
|
+
DisplayStyle.add_rule(key, self, &rule)
|
78
|
+
end
|
79
|
+
|
80
|
+
def url_generator(key, &rule)
|
81
|
+
UrlGenerator.add_rule(key, self, &rule)
|
82
|
+
end
|
83
|
+
|
84
|
+
def use_display_style(rule)
|
85
|
+
self.default_display_style = DisplayStyle[rule]
|
86
|
+
end
|
87
|
+
|
88
|
+
def use_url_generator(rule)
|
89
|
+
self.default_url_generator = UrlGenerator[rule]
|
90
|
+
end
|
91
|
+
|
92
|
+
def default?
|
93
|
+
@is_default
|
94
|
+
end
|
95
|
+
|
96
|
+
def inspect
|
97
|
+
"Merb::Menus::Menu - name~>#{self.name} - submenus~>[#{submenus.map{|e| e.name}.join(", ")}]"
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_s
|
101
|
+
name.to_s
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def add_self_to_collection
|
107
|
+
Menu.collection << self unless Menu[name]
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
def create_default_rules
|
112
|
+
display_style(:default){|thing| thing.to_s}
|
113
|
+
url_generator(:default){|menu, item| "/#{menu}/#{item}"}
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class Merb::Controller
|
2
|
+
before do
|
3
|
+
Merb::Menus.reset
|
4
|
+
|
5
|
+
controller = params[:controller]
|
6
|
+
action = params[:action]
|
7
|
+
|
8
|
+
if top = Merb::Menus.current_menu = Merb::Menus.default
|
9
|
+
if menu = top.current_submenu = get_submenu(top,controller)
|
10
|
+
menu.current_item = get_item(menu,action)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
callback = self.class.instance_variable_get(:@callback)
|
15
|
+
callback.call if callback
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_menu(name, &blk)
|
19
|
+
Merb::Menus::Menu.new(name).instance_eval(&blk)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.set_current
|
23
|
+
end
|
24
|
+
|
25
|
+
# FIXME: if only one arg is given, we probably want to set submenu only? maybe? grr
|
26
|
+
def self.use_menu(*args)
|
27
|
+
@callback = lambda{
|
28
|
+
menu, submenu = *args
|
29
|
+
top = Merb::Menus[menu]
|
30
|
+
Merb::Menus.current_menu = top
|
31
|
+
raise Merb::Menus::NoMenuError.new("Menu '#{menu}' does not exist") unless top
|
32
|
+
|
33
|
+
if submenu
|
34
|
+
top.current_submenu = get_submenu(top, submenu)
|
35
|
+
raise Merb::Menus::NoMenuError.new("Menu '#{submenu}' does not exist") unless top.current_submenu
|
36
|
+
end
|
37
|
+
}
|
38
|
+
@callback.call
|
39
|
+
end
|
40
|
+
|
41
|
+
# ==== Parameters
|
42
|
+
# top<Merb::Menus::Menu>::
|
43
|
+
# sub<Symbol>:: name of desired submenu
|
44
|
+
def self.get_submenu(top, sub)
|
45
|
+
top.submenus.find {|m| m.name.to_s == sub.to_s}
|
46
|
+
end
|
47
|
+
|
48
|
+
# ==== Parameters
|
49
|
+
# menu<Merb::Menus::Submenu>::
|
50
|
+
# item<Symbol>:: name of desired item
|
51
|
+
def self.get_item(menu, item)
|
52
|
+
menu.items.find{|e| e.name.to_s == item.to_s}
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_submenu(top, sub)
|
56
|
+
self.class.get_submenu(top, sub)
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_item(menu, item)
|
60
|
+
self.class.get_item(menu, item)
|
61
|
+
end
|
62
|
+
|
63
|
+
def menu_item(*args)
|
64
|
+
case args.size
|
65
|
+
when 3
|
66
|
+
menu, submenu, item = *args
|
67
|
+
self.class.use_menu(menu, submenu)
|
68
|
+
top = Merb::Menus[menu]
|
69
|
+
menu = get_submenu(top,submenu)
|
70
|
+
menu.current_item = get_item(menu,item)
|
71
|
+
when 2
|
72
|
+
submenu, item = *args
|
73
|
+
top = Merb::Menus.default
|
74
|
+
self.class.use_menu(top.name,submenu)
|
75
|
+
menu = get_submenu(top,submenu)
|
76
|
+
menu.current_item = get_item(menu,item)
|
77
|
+
when 1
|
78
|
+
item = *args
|
79
|
+
top = Merb::Menus.default
|
80
|
+
menu = top.current_submenu
|
81
|
+
menu.current_item = get_item(menu,item)
|
82
|
+
else
|
83
|
+
raise ArgumentError.new("Wrong number of arguments given (#{args.size} for 1)")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def current_menu
|
88
|
+
Merb::Menus.current_menu
|
89
|
+
end
|
90
|
+
|
91
|
+
def current_submenu
|
92
|
+
Merb::Menus.current_submenu
|
93
|
+
end
|
94
|
+
|
95
|
+
def current_item
|
96
|
+
Merb::Menus.current_item
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Merb::Menus
|
2
|
+
class Rule
|
3
|
+
extend Enumerable
|
4
|
+
|
5
|
+
class << self
|
6
|
+
attr_reader :collection
|
7
|
+
|
8
|
+
def add_rule(key, owner, &rule)
|
9
|
+
return nil unless block_given? and unique?(key, owner)
|
10
|
+
@collection << new(key, &rule)
|
11
|
+
end
|
12
|
+
|
13
|
+
def each
|
14
|
+
@collection.each{|i| yield i}
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
find{|rule| rule.key == key}
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def unique?(key, owner)
|
24
|
+
!find{|rule| rule.key == key && rule.owner == owner}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(key, &rule)
|
29
|
+
@key = key
|
30
|
+
@rule = rule
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :key, :rule, :owner
|
34
|
+
end
|
35
|
+
|
36
|
+
class UrlGenerator < Rule; @collection ||= []; end
|
37
|
+
class DisplayStyle < Rule; @collection ||= []; end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Merb::Menus
|
2
|
+
class Submenu
|
3
|
+
def initialize(name, menu, opts={})
|
4
|
+
@name = name
|
5
|
+
@menu = menu
|
6
|
+
@display_style = @menu.default_display_style
|
7
|
+
@url_generator = @menu.default_url_generator
|
8
|
+
@details = Item.new(opts.merge({:name => name, :submenu => self}))
|
9
|
+
@items = []
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :current_item
|
13
|
+
attr_reader :name, :items, :menu, :display_style, :url_generator
|
14
|
+
|
15
|
+
def anchor
|
16
|
+
@details.anchor
|
17
|
+
end
|
18
|
+
|
19
|
+
def href
|
20
|
+
@details.href
|
21
|
+
end
|
22
|
+
|
23
|
+
def item(name, opts={})
|
24
|
+
@items << Item.new(opts.merge({:name => name, :submenu => self}))
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def use_display_style(name)
|
29
|
+
@display_style = DisplayStyle[name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def use_url_generator(name)
|
33
|
+
@url_generator = UrlGenerator[name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def inspect
|
37
|
+
"Merb::Menus::Submenu - name~>#{name} - items~>[#{items.map{|e| e.name}.join(", ")}]"
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
anchor
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
data/lib/merb-menus.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# make sure we're running inside Merb
|
2
|
+
if defined?(Merb::Plugins)
|
3
|
+
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
|
4
|
+
Merb::Plugins.config[:merb_menus] = {
|
5
|
+
:chickens => false
|
6
|
+
}
|
7
|
+
|
8
|
+
Merb::BootLoader.before_app_loads do
|
9
|
+
$:.push File.dirname(__FILE__)
|
10
|
+
|
11
|
+
require 'merb-menus/merb_controller'
|
12
|
+
require 'merb-menus/rule'
|
13
|
+
require 'merb-menus/menu'
|
14
|
+
require 'merb-menus/submenu'
|
15
|
+
require 'merb-menus/item'
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
Merb::BootLoader.after_app_loads do
|
20
|
+
end
|
21
|
+
|
22
|
+
Merb::Plugins.add_rakefiles "merb-menus/merbtasks"
|
23
|
+
|
24
|
+
module Merb::Menus
|
25
|
+
class << self; attr_accessor :current_menu; end
|
26
|
+
|
27
|
+
class NoMenuError < StandardError;end
|
28
|
+
|
29
|
+
def self.[](menu)
|
30
|
+
Menu[menu]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.default
|
34
|
+
Menu.find{|menu| menu.default?} || Menu.first
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.reset
|
38
|
+
Menu.reset
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.current_submenu
|
42
|
+
current_menu.current_submenu rescue nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.current_item
|
46
|
+
current_submenu.current_item rescue nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jonuts-merb-menus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jonah honeyman
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-06 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Merb plugin that provides dot dot dot
|
16
|
+
description: Merb plugin that provides dot dot dot uh menus!
|
17
17
|
email: jonah@honeyman.org
|
18
18
|
executables: []
|
19
19
|
|
@@ -22,6 +22,14 @@ extensions: []
|
|
22
22
|
extra_rdoc_files: []
|
23
23
|
|
24
24
|
files:
|
25
|
+
- lib/merb-menus.rb
|
26
|
+
- lib/merb-menus/item.rb
|
27
|
+
- lib/merb-menus/menu.rb
|
28
|
+
- lib/merb-menus/merb_controller.rb
|
29
|
+
- lib/merb-menus/merbtasks.rb
|
30
|
+
- lib/merb-menus/rule.rb
|
31
|
+
- lib/merb-menus/submenu.rb
|
32
|
+
- lib/merb-menus/version.rb
|
25
33
|
- LICENSE
|
26
34
|
- README
|
27
35
|
- Rakefile
|
@@ -53,6 +61,6 @@ rubyforge_project:
|
|
53
61
|
rubygems_version: 1.2.0
|
54
62
|
signing_key:
|
55
63
|
specification_version: 2
|
56
|
-
summary: Merb plugin that provides dot dot dot
|
64
|
+
summary: Merb plugin that provides dot dot dot uh menus!
|
57
65
|
test_files: []
|
58
66
|
|