merb-menus 0.0.7
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/LICENSE +20 -0
- data/README +4 -0
- data/Rakefile +52 -0
- data/TODO +5 -0
- 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
- data/spec/merb-menus/item_spec.rb +37 -0
- data/spec/merb-menus/menu_spec.rb +30 -0
- data/spec/merb-menus/rule.rb +23 -0
- data/spec/merb-menus/submenu_spec.rb +28 -0
- data/spec/merb-menus_spec.rb +137 -0
- data/spec/spec_helper.rb +16 -0
- metadata +74 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 YOUR NAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
|
4
|
+
require 'merb-core'
|
5
|
+
require 'merb-core/tasks/merb'
|
6
|
+
|
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"
|
15
|
+
|
16
|
+
spec = Gem::Specification.new do |s|
|
17
|
+
s.name = GEM_NAME
|
18
|
+
s.version = GEM_VERSION
|
19
|
+
s.platform = Gem::Platform::RUBY
|
20
|
+
s.has_rdoc = true
|
21
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
22
|
+
s.summary = SUMMARY
|
23
|
+
s.description = s.summary
|
24
|
+
s.author = AUTHOR
|
25
|
+
s.email = EMAIL
|
26
|
+
s.homepage = HOMEPAGE
|
27
|
+
#s.add_dependency('merb', '>= 1.0.11')
|
28
|
+
s.require_path = 'lib'
|
29
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
34
|
+
pkg.gem_spec = spec
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "install the plugin as a gem"
|
38
|
+
task :install do
|
39
|
+
Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Uninstall the gem"
|
43
|
+
task :uninstall do
|
44
|
+
Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Create a gemspec file"
|
48
|
+
task :gemspec do
|
49
|
+
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
50
|
+
file.puts spec.to_ruby
|
51
|
+
end
|
52
|
+
end
|
data/TODO
ADDED
@@ -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) if block_given?
|
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
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Merb::Menus::Item do
|
4
|
+
before do
|
5
|
+
@menu = Merb::Menus::Menu.new(:foo)
|
6
|
+
@menu.display_style(:split) {|thing| thing.to_s.split("_").join(" ")}
|
7
|
+
|
8
|
+
@submenu = Merb::Menus::Submenu.new(:cakes, @menu)
|
9
|
+
@submenu.use_display_style(:split)
|
10
|
+
|
11
|
+
@cheesecake = Merb::Menus::Item.new(:name => :cheese_cake, :submenu => @submenu)
|
12
|
+
@spongecake = Merb::Menus::Item.new(:name => :sponge, :submenu => @submenu, :anchor => "sPOnge cAkE")
|
13
|
+
@poundcake = Merb::Menus::Item.new(:name => :pound, :submenu => @submenu, :href => "http://bettercakesite")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has a unique key"
|
17
|
+
it "has a submenu" do
|
18
|
+
@cheesecake.submenu.should == @submenu
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets the anchor based on display rule in submenu" do
|
22
|
+
@cheesecake.anchor.should == "cheese cake"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "overrides default display style if given in opts" do
|
26
|
+
@spongecake.anchor.should == "sPOnge cAkE"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "generates a url" do
|
30
|
+
@cheesecake.href.should == "/cakes/cheese_cake"
|
31
|
+
@spongecake.href.should == "/cakes/sponge"
|
32
|
+
@poundcake.href.should == "http://bettercakesite"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Merb::Menus::Menu do
|
4
|
+
before do
|
5
|
+
@menu = Merb::Menus::Menu.new(:foo)
|
6
|
+
@menu.submenu(:wutup){}
|
7
|
+
@menu.submenu(:dog){}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "tracks submenus" do
|
11
|
+
@menu.submenus.should have(2).things
|
12
|
+
end
|
13
|
+
|
14
|
+
it "stores different display rules"
|
15
|
+
it "defines a url generator"
|
16
|
+
it "has a default url generation method"
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Merb::Menus::Menu, "#submenu" do
|
20
|
+
before do
|
21
|
+
@menu = Merb::Menus::Menu.new(:hellothar)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "creates a submenu without taking a block" do
|
25
|
+
lambda{@menu.submenu(:foo)}.should_not raise_error(ArgumentError)
|
26
|
+
@menu.submenus.should have(1).item
|
27
|
+
@menu.submenus.first.name.should == :foo
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Merb::Menus::DisplayStyle do
|
4
|
+
before do
|
5
|
+
@menu = Merb::Menus::Menu.new(:foo)
|
6
|
+
@split_rule = Merb::Menus::DisplayStyle.new(:split,@menu){|thing| thing.to_s.split("_").join(" ")}
|
7
|
+
@splitncap = Merb::Menus::DisplayStyle.new(:split,@menu){|thing| thing.to_s.split("_").join(" ")}
|
8
|
+
@dollarfy = Merb::Menus::DisplayStyle.new(:dollar,@menu){|thing| "$#{thing.to_s.gsub(/_/,',')}"}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a unique key" do
|
12
|
+
@split_rule.key.should == :split
|
13
|
+
@splitncap.key.should == :split
|
14
|
+
|
15
|
+
@split_rule.rule.call("hello_thar").should == "hello thar"
|
16
|
+
@splitncap.rule.call("wut_the_deal").should == "wut the deal"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has a styling rule" do
|
20
|
+
Merb::Menus::DisplayStyle.add_rule(:feh).should be_nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Merb::Menus::Submenu do
|
4
|
+
before do
|
5
|
+
Merb::Menus::Menu.new :foo
|
6
|
+
@submenu = Merb::Menus::Submenu.new(:berries, Merb::Menus::Menu[:foo])
|
7
|
+
@submenu.item(:straw)
|
8
|
+
@submenu.item(:rasp)
|
9
|
+
@submenu.item(:black, :anchor => "HELLOTHAR", :url => "eek")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has a unique key" do
|
13
|
+
@submenu.name.should == :berries
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has a collection of items" do
|
17
|
+
@submenu.items.should have(3).things
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'sets item properly' do
|
21
|
+
item = @submenu.items.first
|
22
|
+
item.name.should == :straw
|
23
|
+
item.submenu.should == @submenu
|
24
|
+
item.anchor.should == "straw"
|
25
|
+
item.href.should == "/berries/straw"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
class Application < Merb::Controller
|
4
|
+
create_menu :main do
|
5
|
+
submenu :cakes, :href => "/cakes" do
|
6
|
+
item :cheese
|
7
|
+
item :chocolate
|
8
|
+
item :devils_food, :anchor => "Devil's Food"
|
9
|
+
end
|
10
|
+
|
11
|
+
submenu :beers, :href => "/beers" do
|
12
|
+
item :budweiser
|
13
|
+
item :rolling_rock
|
14
|
+
item :fosters, :anchor => "Foster's"
|
15
|
+
item :fat_tire
|
16
|
+
end
|
17
|
+
|
18
|
+
submenu :drinks, :href => "/drinks" do
|
19
|
+
item :soda
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Cakes < Application
|
26
|
+
use_menu :main
|
27
|
+
|
28
|
+
# this should be associated with item :cheese
|
29
|
+
def cheese
|
30
|
+
'hello'
|
31
|
+
end
|
32
|
+
|
33
|
+
def chocolate
|
34
|
+
menu_item :beers, :budweiser
|
35
|
+
|
36
|
+
'word up'
|
37
|
+
end
|
38
|
+
|
39
|
+
def not_devils_food
|
40
|
+
# associate this action with item :devils_food
|
41
|
+
menu_item :devils_food
|
42
|
+
|
43
|
+
':)'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Beers < Application
|
48
|
+
def fat_tire
|
49
|
+
'yoink'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Snack < Application
|
54
|
+
use_menu :main, :cakes
|
55
|
+
|
56
|
+
def cheese_cake
|
57
|
+
menu_item :cheese
|
58
|
+
|
59
|
+
[current_menu, current_submenu, current_item].join(" ")
|
60
|
+
end
|
61
|
+
|
62
|
+
def pistachios
|
63
|
+
[current_menu, current_submenu, current_item].join(" ")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Drinks < Application
|
68
|
+
def soda
|
69
|
+
"#{current_menu}/#{current_submenu}/#{current_item}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "menu generator", "Merb::Controller" do
|
74
|
+
before do
|
75
|
+
@menu = Merb::Menus[:main]
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should create the menu" do
|
79
|
+
@menu.name.should == :main
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should create all the submenus" do
|
83
|
+
@menu.submenus.should have(3).things
|
84
|
+
@menu.submenus.first.name.should == :cakes
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should create the submenu items" do
|
88
|
+
@menu.submenus.first.items.should have(3).things
|
89
|
+
@menu.submenus.first.items.map{|e| e.name}.should == [:cheese, :chocolate, :devils_food]
|
90
|
+
|
91
|
+
@menu.submenus[1].items.should have(4).things
|
92
|
+
@menu.submenus[1].items.map{|e| e.name}.should == [:budweiser, :rolling_rock, :fosters, :fat_tire]
|
93
|
+
end
|
94
|
+
|
95
|
+
it "is accessible from child controllers"
|
96
|
+
|
97
|
+
it "sets the current menu properly" do
|
98
|
+
request('/cakes/cheese')
|
99
|
+
top = Merb::Menus[:main]
|
100
|
+
top.current_submenu.name.should == :cakes
|
101
|
+
top.current_submenu.current_item.name.should == :cheese
|
102
|
+
end
|
103
|
+
|
104
|
+
it "overrides actions default menu item" do
|
105
|
+
request('/cakes/chocolate')
|
106
|
+
top = Merb::Menus[:main]
|
107
|
+
top.current_submenu.name.should == :beers
|
108
|
+
top.current_submenu.current_item.name.should == :budweiser
|
109
|
+
end
|
110
|
+
|
111
|
+
it "finds the correct controller/action combo automagically" do
|
112
|
+
request '/beers/fat_tire'
|
113
|
+
Merb::Menus.current_menu.name.should == :main
|
114
|
+
Merb::Menus.current_menu.current_submenu.name.should == :beers
|
115
|
+
Merb::Menus.current_menu.current_submenu.current_item.name.should == :fat_tire
|
116
|
+
end
|
117
|
+
|
118
|
+
it "has helpers to access current menu data" do
|
119
|
+
req = request '/drinks/soda'
|
120
|
+
|
121
|
+
req.body.to_s.should == "main/drinks/soda"
|
122
|
+
end
|
123
|
+
|
124
|
+
it do
|
125
|
+
req = request '/snack/cheese_cake'
|
126
|
+
req.body.to_s.should == "main cakes cheese"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "resets all current menus before each request" do
|
130
|
+
req = request '/snack/pistachios'
|
131
|
+
req.body.to_s.should_not == "main cakes cheese" #this would happen w/o the reset
|
132
|
+
req.body.to_s.should == "main cakes "
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
end
|
137
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'spec'
|
5
|
+
require 'merb-core'
|
6
|
+
require 'merb-core/test'
|
7
|
+
require 'merb-menus'
|
8
|
+
|
9
|
+
Merb::Router.prepare {default_routes}
|
10
|
+
|
11
|
+
Merb.start :environment => "test", :adapter => "runner"
|
12
|
+
|
13
|
+
Spec::Runner.configure {|config|
|
14
|
+
config.include(Merb::Test::RouteHelper)
|
15
|
+
}
|
16
|
+
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: merb-menus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jonah honeyman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-03 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Merb plugin that provides dot dot dot uh menus
|
17
|
+
email: jonah@honeyman.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
- LICENSE
|
25
|
+
- TODO
|
26
|
+
files:
|
27
|
+
- LICENSE
|
28
|
+
- README
|
29
|
+
- Rakefile
|
30
|
+
- TODO
|
31
|
+
- lib/merb-menus/version.rb
|
32
|
+
- lib/merb-menus/merb_controller.rb
|
33
|
+
- lib/merb-menus/submenu.rb
|
34
|
+
- lib/merb-menus/item.rb
|
35
|
+
- lib/merb-menus/merbtasks.rb
|
36
|
+
- lib/merb-menus/rule.rb
|
37
|
+
- lib/merb-menus/menu.rb
|
38
|
+
- lib/merb-menus.rb
|
39
|
+
- spec/merb-menus/submenu_spec.rb
|
40
|
+
- spec/merb-menus/item_spec.rb
|
41
|
+
- spec/merb-menus/rule.rb
|
42
|
+
- spec/merb-menus/menu_spec.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
- spec/merb-menus_spec.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/jonuts/merb-menus
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.5
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Merb plugin that provides dot dot dot uh menus
|
73
|
+
test_files: []
|
74
|
+
|