merb-menus 0.1.0 → 0.2.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.
data/README CHANGED
@@ -1,4 +1 @@
1
- menu_generator
2
- ==============
3
-
4
- A plugin for the Merb framework that provides ...
1
+ this is awful and shouldn't be used
@@ -1,13 +1,13 @@
1
1
  module Merb::Menus
2
2
  class Item
3
- def initialize(opts)
3
+ def initialize(opts, &data)
4
4
  @submenu = opts[:submenu]
5
5
  @name = opts[:name]
6
6
  @anchor = opts[:anchor] || build_anchor
7
7
  @href = opts[:href] || build_url
8
8
  end
9
9
 
10
- attr_reader :name, :anchor, :href, :submenu
10
+ attr_reader :name, :anchor, :submenu, :data
11
11
 
12
12
  def inspect
13
13
  "<Merb::Menus::Item> - name~>#{name}"
@@ -17,6 +17,14 @@ module Merb::Menus
17
17
  anchor.to_s
18
18
  end
19
19
 
20
+ def needs_generation?
21
+ Proc === @href
22
+ end
23
+
24
+ def href
25
+ needs_generation? ? @href[] : @href
26
+ end
27
+
20
28
  private
21
29
 
22
30
  def build_url
@@ -46,8 +46,15 @@ module Merb::Menus
46
46
  @collection.first
47
47
  end
48
48
 
49
- def reset
50
- each{ |e| e.submenus.each{ |menu| menu.current_item = nil} ; e.current_submenu = nil}
49
+ def reset!
50
+ each do |e|
51
+ e.submenus.each do |menu|
52
+ menu.current_item = nil
53
+ menu.items.clear
54
+ end
55
+
56
+ e.current_submenu = nil
57
+ end
51
58
  end
52
59
  end
53
60
 
@@ -66,9 +73,8 @@ module Merb::Menus
66
73
  attr_accessor :current_submenu, :default_display_style, :default_url_generator
67
74
  attr_reader :name, :submenus
68
75
 
69
- def submenu(name, opts={}, &blk)
70
- submenu = Submenu.new(name, self, opts)
71
- submenu.instance_eval(&blk) if block_given?
76
+ def submenu(name, opts={}, &data)
77
+ submenu = Submenu.new(name, self, opts, &data)
72
78
  @submenus << submenu
73
79
  self
74
80
  end
@@ -1,57 +1,25 @@
1
1
  class Merb::Controller
2
- before do
3
- Merb::Menus.reset
2
+ before do; Merb::Menus.reset! end
3
+ before :generate_default_menu
4
4
 
5
- self.class.instance_variable_set(:@callback, nil)
6
-
7
- controller = params['controller']
8
- action = params['action']
9
-
10
- if top = Merb::Menus.current_menu = Merb::Menus.default
11
- if menu = top.current_submenu = get_submenu(top,controller)
12
- menu.current_item = get_item(menu,action)
13
- end
5
+ class << self
6
+ def create_menu(name, &data)
7
+ Merb::Menus::Menu.new(name).instance_eval &data
14
8
  end
15
9
 
16
- callback = self.class.instance_variable_get(:@callback)
17
- callback.call if callback
18
- end
19
-
20
- def self.create_menu(name, &blk)
21
- Merb::Menus::Menu.new(name).instance_eval(&blk)
22
- end
23
-
24
- def self.set_current
25
- end
26
-
27
- # FIXME: if only one arg is given, we probably want to set submenu only? maybe? grr
28
- def self.use_menu(*args)
29
- @callback = lambda{
30
- menu, submenu = *args
31
- top = Merb::Menus[menu]
32
- Merb::Menus.current_menu = top
33
- raise Merb::Menus::NoMenuError.new("Menu '#{menu}' does not exist") unless top
34
-
35
- if submenu
36
- top.current_submenu = get_submenu(top, submenu)
37
- raise Merb::Menus::NoMenuError.new("Menu '#{submenu}' does not exist") unless top.current_submenu
38
- end
39
- }
40
- @callback.call
41
- end
42
-
43
- # ==== Parameters
44
- # top<Merb::Menus::Menu>::
45
- # sub<Symbol>:: name of desired submenu
46
- def self.get_submenu(top, sub)
47
- top.submenus.find {|m| m.name.to_s == sub.to_s}
48
- end
10
+ # ==== Parameters
11
+ # top<Merb::Menus::Menu>::
12
+ # sub<Symbol>:: name of desired submenu
13
+ def get_submenu(top, sub)
14
+ top.submenus.find {|m| m.name.to_s == sub.to_s}
15
+ end
49
16
 
50
- # ==== Parameters
51
- # menu<Merb::Menus::Submenu>::
52
- # item<Symbol>:: name of desired item
53
- def self.get_item(menu, item)
54
- menu.items.find{|e| e.name.to_s == item.to_s}
17
+ # ==== Parameters
18
+ # menu<Merb::Menus::Submenu>::
19
+ # item<Symbol>:: name of desired item
20
+ def get_item(menu, item)
21
+ item = menu.items.find{|e| e.name.to_s == item.to_s}
22
+ end
55
23
  end
56
24
 
57
25
  def get_submenu(top, sub)
@@ -63,27 +31,20 @@ class Merb::Controller
63
31
  end
64
32
 
65
33
  def menu_item(*args)
66
- case args.size
67
- when 3
68
- menu, submenu, item = *args
69
- self.class.use_menu(menu, submenu)
70
- top = Merb::Menus[menu]
71
- menu = get_submenu(top,submenu)
72
- menu.current_item = get_item(menu,item)
73
- when 2
74
- submenu, item = *args
75
- top = Merb::Menus.default
76
- self.class.use_menu(top.name,submenu)
77
- menu = get_submenu(top,submenu)
78
- menu.current_item = get_item(menu,item)
79
- when 1
80
- item = *args
81
- top = Merb::Menus.default
82
- menu = top.current_submenu
83
- menu.current_item = get_item(menu,item)
84
- else
85
- raise ArgumentError.new("Wrong number of arguments given (#{args.size} for 1)")
34
+ menu, submenu, item = *args
35
+
36
+ if item.nil?
37
+ item = submenu
38
+ submenu = menu
39
+ menu = Merb::Menus.default.name
86
40
  end
41
+
42
+ top = Merb::Menus[menu]
43
+ Merb::Menus.current_menu = top
44
+ generate_menu(top)
45
+ submenu = get_submenu(top, submenu)
46
+ top.current_submenu = submenu
47
+ submenu.current_item = get_item(submenu, item)
87
48
  end
88
49
 
89
50
  def current_menu
@@ -98,5 +59,30 @@ class Merb::Controller
98
59
  Merb::Menus.current_item
99
60
  end
100
61
 
62
+ # Generate items in the context of our current controller instance
63
+ # so that we can generate urls with merb's url helpers
64
+ def item(*args)
65
+ @__submenu_generation__.item(*args)
66
+ end
67
+
68
+ def generate_menu(menu)
69
+ menu.submenus.each do |m|
70
+ @__submenu_generation__ = m
71
+ instance_eval &m.data
72
+ m.generated!
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def generate_default_menu
79
+ if top = Merb::Menus.current_menu = Merb::Menus.default
80
+ generate_menu(top)
81
+
82
+ if menu = top.current_submenu = get_submenu(top, controller_name)
83
+ menu.current_item = get_item(menu, action_name)
84
+ end
85
+ end
86
+ end
101
87
  end
102
88
 
@@ -1,16 +1,17 @@
1
1
  module Merb::Menus
2
2
  class Submenu
3
- def initialize(name, menu, opts={})
3
+ def initialize(name, menu, opts={}, &data)
4
4
  @name = name
5
5
  @menu = menu
6
6
  @display_style = @menu.default_display_style
7
7
  @url_generator = @menu.default_url_generator
8
8
  @details = Item.new(opts.merge({:name => name, :submenu => self}))
9
9
  @items = []
10
+ @data = data
10
11
  end
11
12
 
12
13
  attr_accessor :current_item
13
- attr_reader :name, :items, :menu, :display_style, :url_generator
14
+ attr_reader :name, :items, :menu, :display_style, :url_generator, :data
14
15
 
15
16
  def anchor
16
17
  @details.anchor
@@ -21,7 +22,8 @@ module Merb::Menus
21
22
  end
22
23
 
23
24
  def item(name, opts={})
24
- @items << Item.new(opts.merge({:name => name, :submenu => self}))
25
+ @items << Item.new(opts.merge({:name => name, :submenu => self})) unless
26
+ @items.any? {|i| i.name == name}
25
27
  self
26
28
  end
27
29
 
@@ -40,6 +42,22 @@ module Merb::Menus
40
42
  def to_s
41
43
  anchor
42
44
  end
45
+
46
+ def generated!
47
+ @generated = true
48
+ end
49
+
50
+ def generated?
51
+ !!@generated
52
+ end
53
+
54
+ private
55
+
56
+ # Don't generate the URLs until the action is hit
57
+ # when using merb url/resource helpers
58
+ def method_missing(meth, *args, &block)
59
+ lambda {Merb::Menus.controller.send(meth, *args, &block)}
60
+ end
43
61
  end
44
62
  end
45
63
 
@@ -1,10 +1,6 @@
1
1
  module Merb
2
2
  module Menus
3
- BIG = "0"
4
- SMALL = "1"
5
- TINY = "0"
6
-
7
- VERSION = [BIG, SMALL, TINY].join(".")
3
+ VERSION = "0.2.0" unless defined?(::Merb::Menus::VERSION)
8
4
  end
9
5
  end
10
6
 
data/lib/merb-menus.rb CHANGED
@@ -22,7 +22,7 @@ if defined?(Merb::Plugins)
22
22
  Merb::Plugins.add_rakefiles "merb-menus/merbtasks"
23
23
 
24
24
  module Merb::Menus
25
- class << self; attr_accessor :current_menu; end
25
+ class << self; attr_accessor :current_menu, :controller end
26
26
 
27
27
  class NoMenuError < StandardError;end
28
28
 
@@ -34,8 +34,8 @@ if defined?(Merb::Plugins)
34
34
  Menu.find{|menu| menu.default?} || Menu.first
35
35
  end
36
36
 
37
- def self.reset
38
- Menu.reset
37
+ def self.reset!
38
+ Menu.reset!
39
39
  end
40
40
 
41
41
  def self.current_submenu
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merb-menus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - jonah honeyman
@@ -9,7 +14,7 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-11-04 00:00:00 +02:00
17
+ date: 2011-01-19 00:00:00 +02:00
13
18
  default_executable:
14
19
  dependencies: []
15
20
 
@@ -24,24 +29,18 @@ extra_rdoc_files:
24
29
  - LICENSE
25
30
  - TODO
26
31
  files:
27
- - LICENSE
28
- - README
29
- - Rakefile
30
- - TODO
31
32
  - 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
33
  - lib/merb-menus/merbtasks.rb
36
- - lib/merb-menus/rule.rb
34
+ - lib/merb-menus/submenu.rb
37
35
  - lib/merb-menus/menu.rb
36
+ - lib/merb-menus/rule.rb
37
+ - lib/merb-menus/item.rb
38
+ - lib/merb-menus/merb_controller.rb
38
39
  - 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
40
+ - LICENSE
41
+ - README
42
+ - Rakefile
43
+ - TODO
45
44
  has_rdoc: true
46
45
  homepage: http://github.com/jonuts/merb-menus
47
46
  licenses: []
@@ -52,21 +51,25 @@ rdoc_options: []
52
51
  require_paths:
53
52
  - lib
54
53
  required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
55
  requirements:
56
56
  - - ">="
57
57
  - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
58
60
  version: "0"
59
- version:
60
61
  required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
61
63
  requirements:
62
64
  - - ">="
63
65
  - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
64
68
  version: "0"
65
- version:
66
69
  requirements: []
67
70
 
68
71
  rubyforge_project:
69
- rubygems_version: 1.3.5
72
+ rubygems_version: 1.3.7
70
73
  signing_key:
71
74
  specification_version: 3
72
75
  summary: Merb plugin that provides dot dot dot uh menus
@@ -1,37 +0,0 @@
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
-
@@ -1,30 +0,0 @@
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
-
@@ -1,23 +0,0 @@
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
-
@@ -1,28 +0,0 @@
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
-
@@ -1,137 +0,0 @@
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 DELETED
@@ -1,16 +0,0 @@
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
-