merb-menus 0.1.0 → 0.2.0

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