menu_helper 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,40 @@
1
+ == master
2
+
3
+ == 0.1.0 / 2008-10-26
4
+
5
+ * Update tests to use ActionView::TestCase
6
+ * Embed menu content within a span element for better style control
7
+ * Rename :auto_link option to :link
8
+ * Add ability to render active submenus on a different part of the page for better layout control
9
+ * Add ability to turn off automatically setting html ids for menus
10
+ * Allow default class names to be configured on a per-application basis
11
+ * Change id/class css naming conventions to following something more similar to jQuery UI
12
+ * Require that the menu content always be defined (even if it's just nil) if the url isn't a hash
13
+ * Use consistent API for internals
14
+
15
+ == 0.0.5 / 2008-06-22
16
+
17
+ * Remove log files from gems
18
+
19
+ == 0.0.4 / 2008-06-01
20
+
21
+ * Remove dependency on set_or_append
22
+
23
+ == 0.0.3 / 2008-05-05
24
+
25
+ * Updated documentation
26
+
27
+ == 0.0.2 / 2007-09-26
28
+
29
+ * Add gem dependency on set_or_append
30
+ * Convert dos newlines to unix newlines
31
+ * Fix too many :nodoc: tags so that rdocs are generated properly
32
+
33
+ == 0.0.1 / 2007-08-16
34
+
35
+ * Add README documentation
36
+ * Add api documentation
37
+ * Add dependency on plugin_test_helper in order to simplify the test setup code
38
+ * Remove MainMenuBar in favor of providing a default id for MenuBar
39
+ * Refactor helper classes into individual files
40
+ * Add unit tests
File without changes
@@ -4,21 +4,21 @@
4
4
 
5
5
  == Resources
6
6
 
7
- Wiki
8
-
9
- * http://wiki.pluginaweek.org/Menu_helper
10
-
11
7
  API
12
8
 
13
9
  * http://api.pluginaweek.org/menu_helper
14
10
 
11
+ Bugs
12
+
13
+ * http://pluginaweek.lighthouseapp.com/projects/13280-menu_helper
14
+
15
15
  Development
16
16
 
17
- * http://dev.pluginaweek.org/browser/trunk/plugins/action_pack/menu_helper
17
+ * http://github.com/pluginaweek/menu_helper
18
18
 
19
19
  Source
20
20
 
21
- * http://svn.pluginaweek.org/trunk/plugins/action_pack/menu_helper
21
+ * git://github.com/pluginaweek/menu_helper.git
22
22
 
23
23
  == Description
24
24
 
@@ -37,21 +37,16 @@ routes.rb:
37
37
  end
38
38
 
39
39
  map.with_options(:controller => 'about_us') do |about_us|
40
- about_us.about_us 'about_us', :action => 'index'
41
- about_us.contact 'about_us/contact', :action => 'contact'
42
- about_us.who_we_are 'about_us/who_we_are', :action => 'who_we_are'
40
+ about_us.about_us 'about_us', :action => 'index'
41
+ about_us.contact 'about_us/contact', :action => 'contact'
42
+ about_us.who_we_are 'about_us/who_we_are', :action => 'who_we_are'
43
43
  end
44
44
 
45
- map.with_options(:controller => 'products') do |products|
46
- products.products 'products', :action => 'index'
47
- end
48
-
49
- map.with_options(:controller => 'services') do |services|
50
- services.services 'services', :action => 'index'
51
- end
45
+ map.resources :products
46
+ map.resources :services
52
47
  end
53
48
 
54
- _menubar.rhtml:
49
+ _menu_bar.html.erb:
55
50
  <%=
56
51
  menu_bar do |main|
57
52
  main.menu :home
@@ -67,17 +62,18 @@ _menubar.rhtml:
67
62
  %>
68
63
 
69
64
  Output (formatted for sanity):
70
- <ul id="menubar">
71
- <li id="home"><a href="http://example.com/">Home</a></li>
72
- <li id="products"><a href="http://example.com/products">Products</a></li>
73
- <li id="services"><a href="http://example.com/services">Services</a></li>
74
- <li class="selected" id="about_us"><a href="http://example.com/about_us">About Us</a>
75
- <ul id="about_us_menubar">
76
- <li id="overview"><a href="http://example.com/about_us">Overview</a></li>
77
- <li class="selected" id="who_we_are"><a href="http://example.com/about_us/who_we_are">Who We Are</a></li>
78
- <li class="last" id="contact"><a href="http://example.com/about_us/contact">Contact Us</a></li>
65
+ <ul class="menubar menubar-1">
66
+ <li><a href="http://example.com/"><span>Home</span></a></li>
67
+ <li><a href="http://example.com/products"><span>Products</span></a></li>
68
+ <li><a href="http://example.com/services"><span>Services</span></a></li>
69
+ <li class="menubar-selected"><a href="http://example.com/about_us"><span>About Us</span></a>
70
+ <ul class="menubar menubar-2 menubar-selected">
71
+ <li><a href="http://example.com/about_us"><span>Overview</span></a></li>
72
+ <li class="menubar-selected"><a href="http://example.com/about_us/who_we_are"><span>Who We Are</span></a></li>
73
+ <li class="menubar-last"><a href="http://example.com/about_us/contact"><span>Contact Us</span></a></li>
79
74
  </ul>
80
- <li class="search ir" id="search"><a href="http://www.google.com">Search!</a></li>
75
+ </li>
76
+ <li class="ir menubar-last"><a href="http://www.google.com"><span>Search!</span></a></li>
81
77
  </ul>
82
78
 
83
79
  === Caveat Emptor
@@ -87,13 +83,13 @@ use this plugin if you're writing a very, very simple menubar. The advantages
87
83
  of this helper are consistency, DRYness, and decreased complexity if you have
88
84
  lots of submenus.
89
85
 
90
- I wrote this plugin mostly as an educational/experimental piece, so I don't using
91
- this in a production application, but rather a prototype.
86
+ I wrote this plugin mostly as an educational/experimental piece, so I don't
87
+ recommend using this in a production application, but rather a prototype.
92
88
 
93
89
  == Testing
94
90
 
95
91
  To test this plugin, the following gems must be installed:
96
- * plugin_test_helper[http://wiki.pluginaweek.org/Plugin_test_helper]
92
+ * plugin_test_helper[http://github.com/pluginaweek/plugin_test_helper]
97
93
 
98
94
  To run against a specific version of Rails:
99
95
 
data/Rakefile CHANGED
@@ -3,46 +3,54 @@ require 'rake/rdoctask'
3
3
  require 'rake/gempackagetask'
4
4
  require 'rake/contrib/sshpublisher'
5
5
 
6
- PKG_NAME = 'menu_helper'
7
- PKG_VERSION = '0.0.5'
8
- PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
9
- RUBY_FORGE_PROJECT = 'pluginaweek'
10
-
11
- desc 'Default: run unit tests.'
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'menu_helper'
8
+ s.version = '0.1.0'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'Adds a helper method for generating a menubar'
11
+
12
+ s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
13
+ s.require_path = 'lib'
14
+ s.has_rdoc = true
15
+ s.test_files = Dir['test/**/*_test.rb']
16
+
17
+ s.author = 'Aaron Pfeifer'
18
+ s.email = 'aaron@pluginaweek.org'
19
+ s.homepage = 'http://www.pluginaweek.org'
20
+ s.rubyforge_project = 'pluginaweek'
21
+ end
22
+
23
+ desc 'Default: run all tests.'
12
24
  task :default => :test
13
25
 
14
- desc 'Test the menu_helper plugin.'
26
+ desc "Test the #{spec.name} plugin."
15
27
  Rake::TestTask.new(:test) do |t|
16
28
  t.libs << 'lib'
17
- t.pattern = 'test/**/*_test.rb'
29
+ t.test_files = spec.test_files
18
30
  t.verbose = true
19
31
  end
20
32
 
21
- desc 'Generate documentation for the menu_helper plugin.'
33
+ begin
34
+ require 'rcov/rcovtask'
35
+ namespace :test do
36
+ desc "Test the #{spec.name} plugin with Rcov."
37
+ Rcov::RcovTask.new(:rcov) do |t|
38
+ t.libs << 'lib'
39
+ t.test_files = spec.test_files
40
+ t.rcov_opts << '--exclude="^(?!lib/)"'
41
+ t.verbose = true
42
+ end
43
+ end
44
+ rescue LoadError
45
+ end
46
+
47
+ desc "Generate documentation for the #{spec.name} plugin."
22
48
  Rake::RDocTask.new(:rdoc) do |rdoc|
23
49
  rdoc.rdoc_dir = 'rdoc'
24
- rdoc.title = 'MenuHelper'
50
+ rdoc.title = spec.name
25
51
  rdoc.template = '../rdoc_template.rb'
26
52
  rdoc.options << '--line-numbers' << '--inline-source'
27
- rdoc.rdoc_files.include('README')
28
- rdoc.rdoc_files.include('lib/**/*.rb')
29
- end
30
-
31
- spec = Gem::Specification.new do |s|
32
- s.name = PKG_NAME
33
- s.version = PKG_VERSION
34
- s.platform = Gem::Platform::RUBY
35
- s.summary = 'Adds a helper method for generating a menubar'
36
-
37
- s.files = FileList['{lib,test}/**/*'].to_a - FileList['test/app_root/log/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
38
- s.require_path = 'lib'
39
- s.autorequire = 'menu_helper'
40
- s.has_rdoc = true
41
- s.test_files = Dir['test/**/*_test.rb']
42
-
43
- s.author = 'Aaron Pfeifer'
44
- s.email = 'aaron@pluginaweek.org'
45
- s.homepage = 'http://www.pluginaweek.org'
53
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
46
54
  end
47
55
 
48
56
  Rake::GemPackageTask.new(spec) do |p|
@@ -51,14 +59,14 @@ Rake::GemPackageTask.new(spec) do |p|
51
59
  p.need_zip = true
52
60
  end
53
61
 
54
- desc 'Publish the beta gem'
62
+ desc 'Publish the beta gem.'
55
63
  task :pgem => [:package] do
56
- Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{PKG_FILE_NAME}.gem").upload
64
+ Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
57
65
  end
58
66
 
59
- desc 'Publish the API documentation'
67
+ desc 'Publish the API documentation.'
60
68
  task :pdoc => [:rdoc] do
61
- Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{PKG_NAME}", 'rdoc').upload
69
+ Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
62
70
  end
63
71
 
64
72
  desc 'Publish the API docs and gem'
@@ -71,10 +79,10 @@ task :release => [:gem, :package] do
71
79
  ruby_forge = RubyForge.new.configure
72
80
  ruby_forge.login
73
81
 
74
- %w( gem tgz zip ).each do |ext|
75
- file = "pkg/#{PKG_FILE_NAME}.#{ext}"
82
+ %w(gem tgz zip).each do |ext|
83
+ file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
76
84
  puts "Releasing #{File.basename(file)}..."
77
85
 
78
- ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
86
+ ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
79
87
  end
80
88
  end
data/lib/menu_helper.rb CHANGED
@@ -3,42 +3,78 @@ require 'menu_helper/menu_bar'
3
3
  require 'menu_helper/menu'
4
4
 
5
5
  module PluginAWeek #:nodoc:
6
- # Provides a builder for generating html menubars. The structure of the
7
- # menubars/menus is based on lists and should be styled using css.
6
+ # Provides a builder for generating html menu bars. The structure of the
7
+ # menus/menu bars is based on lists and should be styled using css.
8
8
  module MenuHelper
9
- # Creates a new 1st-level menu bar. The first parameter is the menubar's
10
- # configuration options. The second parameter is the menubar's html
11
- # options. Both of these parameters are optional.
9
+ # Creates a new first-level menu bar. This takes the configuration options
10
+ # for the menu bar, followed by html options. Both of these parameters are
11
+ # optional.
12
12
  #
13
13
  # Configuration options:
14
- # * +auto_set_id+ - Whether or not to automatically add ids to each menu.
14
+ # * +auto_set_ids+ - Whether or not to automatically add ids to each menu/menu bar. Default is true.
15
+ # * +attach_active_submenus+ - Whether any active sub-menu bar should be rendered as part of its parent menu. Default is true.
16
+ # * +content_for+ - The base block name to use when detaching active submenus. Default is "menu_bar". For example, this will render sub-menu bars to menu_bar_level_2
15
17
  #
16
18
  # == Examples
17
19
  #
18
- # menu_bar {}, :id => 'menus', :class => 'pretty' do |main|
20
+ # menu_bar({}, :id => 'nav', :class => 'pretty') do |main|
19
21
  # main.menu :home
20
22
  # main.menu :about_us do |about_us|
21
- # about_us.who_we_are
22
- # about_us.what_we_do
23
- # about_us.where_we_are
24
- # about_us.contact, 'Contact', 'mailto:contact@us.com'
23
+ # about_us.menu :who_we_are
24
+ # about_us.menu :what_we_do
25
+ # about_us.menu :where_we_are
26
+ # about_us.menu :contact, 'Contact', 'mailto:contact@us.com'
25
27
  # end
26
28
  # end
27
- # #=>
28
- # <ul id="menus" class="pretty">
29
- # <li id="about_us">About Us
30
- # <ul id="about_us_menubar">
31
- # <li id="who_we_are"><a href="/about_us/who_we_are">Who We Are</a></li>
32
- # <li id="what_we_do"><a href="/about_us/what_we_do">What We Do</a></li>
33
- # <li id="contact"><a href="mailto:contact@us.com">Contact</a></li>
29
+ #
30
+ # ...generates the following html if +about_us+ is selected...
31
+ #
32
+ # <ul id="nav" class="pretty menubar menubar-1">
33
+ # <li id="nav-home"><a href="/"><span>Home</span></a></li>
34
+ # <li id="nav-about_us" class="menubar-selected"><a href="/about_us"><span>About Us</span></a>
35
+ # <ul class="menubar menubar-2" class="menubar-selected">
36
+ # <li id="nav-about_us-who_we_are"><a href="/about_us/who_we_are"><span>Who We Are</span></a></li>
37
+ # <li id="nav-about_us-what_we_do"><a href="/about_us/what_we_do"><span>What We Do</span></a></li>
38
+ # <li id="nav-about_us-contact"><a href="mailto:contact@us.com"><span>Contact</span></a></li>
34
39
  # </ul>
35
40
  # </li>
36
41
  # </ul>
37
42
  #
43
+ # Submenus can be detached from the original parent menu for greater control
44
+ # over layout. For example,
45
+ #
46
+ # menu_bar({:attach_active_submenus => false}, :id => 'nav') do |main|
47
+ # main.menu :home
48
+ # main.menu :about_us do |about_us|
49
+ # about_us.menu :who_we_are
50
+ # about_us.menu :what_we_do
51
+ # about_us.menu :where_we_are
52
+ # end
53
+ # end
54
+ #
55
+ # <div id="subnav">
56
+ # <%= yield :menu_bar_level_2 %>
57
+ # </div>
58
+ #
59
+ # ...generates the following html if +about_us+ is selected...
60
+ #
61
+ # <ul id="nav" class="menubar menubar-1">
62
+ # <li id="nav-home"><a href="/"><span>Home</span></a></li>
63
+ # <li id="nav-about_us" class="menubar-selected"><a href="/about_us"><span>About Us</span></a></li>
64
+ # </ul>
65
+ #
66
+ # <div id="subnav">
67
+ # <ul class="menubar menubar-2 menubar-selected">
68
+ # <li id="nav-about_us-who_we_are"><a href="/about_us/who_we_are"><span>Who We Are</span></a></li>
69
+ # <li id="nav-about_us-what_we_do"><a href="/about_us/what_we_do"><span>What We Do</span></a></li>
70
+ # <li id="nav-about_us-contact"><a href="mailto:contact@us.com"><span>Contact</span></a></li>
71
+ # </ul>
72
+ # </div>
73
+ #
38
74
  # == Menu Selection
39
75
  #
40
- # The currently selected menu is based on the current page that the user
41
- # is currently on. If the url that the menu links to is the same as the
76
+ # The currently selected menu is based on the current page that is displayed
77
+ # to the user. If the url that the menu links to is the same as the
42
78
  # current page, then that menu will be selected. This menu uses
43
79
  # ActionView::Helpers::UrlHelper#current_page? to determine whether or not
44
80
  # it is the currently selected menu.
@@ -46,18 +82,19 @@ module PluginAWeek #:nodoc:
46
82
  # If the menu that is selected is nested within another menu, then those
47
83
  # menus will be selected as well.
48
84
  #
49
- # A "selected" menu is indicated by an additional class html attribute
50
- # that is added to the list item.
85
+ # A "selected" menu/menu bar is indicated by an additional css class that is
86
+ # added to the element.
51
87
  #
52
- # For example, if a submenu is selected, the html generated from the
53
- # above full example would look like so:
88
+ # For example, if a sub-menu like +who_we_are+ is selected, the html
89
+ # generated from the above full example would look like so:
54
90
  #
55
- # <ul id="menus" class="pretty">
56
- # <li id="about_us" class="selected">About Us
57
- # <ul id="about_us_menubar">
58
- # <li id="who_we_are" class="selected"><a href="/about_us/who_we_are">Who We Are</a></li>
59
- # <li id="what_we_do"><a href="/about_us/what_we_do">What We Do</a></li>
60
- # <li id="contact"><a href="mailto:contact@us.com">Contact</a></li>
91
+ # <ul id="nav" class="pretty menubar menubar-1">
92
+ # <li id="nav-home"><a href="/"><span>Home</span></a></li>
93
+ # <li id="nav-about_us" class="menubar-selected"><span>About Us</span>
94
+ # <ul class="menubar menubar-2 menubar-selected">
95
+ # <li id="nav-about_us-who_we_are" class="menubar-selected"><a href="/about_us/who_we_are"><span>Who We Are</span></a></li>
96
+ # <li id="nav-about_us-what_we_do"><a href="/about_us/what_we_do"><span>What We Do</span></a></li>
97
+ # <li id="nav-about_us-contact"><a href="mailto:contact@us.com"><span>Contact</span></a></li>
61
98
  # </ul>
62
99
  # </li>
63
100
  # </ul>
@@ -65,9 +102,9 @@ module PluginAWeek #:nodoc:
65
102
  # == Menu Creation
66
103
  #
67
104
  # For more information about how menus are created, see the documentation
68
- # for MenuBar#menu.
69
- def menu_bar(*args, &block)
70
- MenuBar.new(@controller, *args, &block).html
105
+ # for PluginAWeek::MenuHelper::MenuBar#menu.
106
+ def menu_bar(options = {}, html_options = {}, &block)
107
+ MenuBar.new(@controller, options, html_options, &block).html
71
108
  end
72
109
  end
73
110
  end
@@ -4,64 +4,107 @@ module PluginAWeek #:nodoc:
4
4
  class Menu < HtmlElement
5
5
  include ActionView::Helpers::UrlHelper
6
6
 
7
- # The url where this menu is linked to
7
+ # The css class to apply when a menu is selected
8
+ cattr_accessor :selected_class
9
+ @@selected_class = 'menubar-selected'
10
+
11
+ # The css class for the last menu in the menu bar
12
+ cattr_accessor :last_class
13
+ @@last_class = 'menubar-last'
14
+
15
+ # The unique name assigned to this menu
16
+ attr_reader :name
17
+
18
+ # The url where this menu is linked to. This can either be a hash of
19
+ # url options or a string representing the actual url
8
20
  attr_reader :url_options
9
21
 
10
- # If there are submenus under this menu, they are stored in here
11
- attr_reader :menu_bar
22
+ # The menu bar in which this menu exists
23
+ attr_reader :parent_menu_bar
24
+
25
+ # Add shortcuts to the menu bar configuration
26
+ delegate :request_controller,
27
+ :parent_menu,
28
+ :auto_set_ids?,
29
+ :attach_active_submenus?,
30
+ :to => :parent_menu_bar
12
31
 
13
- # Allow submenus to be created
14
- delegate :menu,
15
- :to => :menu_bar
32
+ # Add ability to add menus *after* creation
33
+ delegate :menu,
34
+ :to => '@menu_bar'
16
35
 
17
- def initialize(id, request_controller, parent = nil, *args) #:nodoc
18
- id = id.to_s
19
- @controller = @request_controller = request_controller
20
- @parent = parent
21
- @content = args.first.is_a?(String) ? args.shift : id.underscore.titleize
22
- @url_options = args.shift || {}
23
- super(args.shift || {})
36
+ def initialize(parent_menu_bar, name, content = nil, url_options = {}, html_options = {}) #:nodoc
37
+ # Allow the content parameter to be skipped
38
+ content, url_options, html_options = nil, content, url_options if content.is_a?(Hash)
24
39
 
25
- # Set the default html options
26
- @html_options[:id] ||= id
40
+ # Remove non-html options that are specific to this element and shouldn't
41
+ # be rendered as an html attribute
42
+ @options = html_options.slice(:link)
43
+ html_options.except!(:link)
27
44
 
28
- @menu_bar = MenuBar.new(@request_controller, {}, {:id => "#{self[:id]}_menubar"}, self)
45
+ super(html_options)
29
46
 
30
- # Build the url for the menu
31
- url, @url_options = build_url(@url_options)
32
- @content = link_to(@content, url) if auto_link?
47
+ @parent_menu_bar = parent_menu_bar
48
+ @name = name.to_s
33
49
 
34
- yield self if block_given?
35
- end
36
-
37
- # Should we try to automatically generate the link?
38
- def auto_link?
39
- !@url_options.is_a?(Hash) || !@url_options.include?(:auto_link) || @url_options[:auto_link]
50
+ # Set context of the menu for url generation
51
+ @controller = request_controller
52
+
53
+ # Generate the text-based content of the menu
54
+ @content = content_tag(:span, content || @name.underscore.titleize)
55
+
56
+ # Set up url
57
+ url, @url_options = build_url(url_options)
58
+ @content = link_to(@content, url) if @options[:link] != false
59
+
60
+ # Set up default html options
61
+ id_prefix = parent_menu_bar[:id] || parent_menu && parent_menu[:id]
62
+ self[:id] ||= "#{id_prefix}-#{@name}" if auto_set_ids? && id_prefix
63
+
64
+ # Create the menu bar for sub-menus in case any are generated. Use the
65
+ # same configuration as the parent menu bar.
66
+ @menu_bar = MenuBar.new(request_controller, parent_menu_bar.options.merge(:parent_menu => self))
67
+
68
+ yield @menu_bar if block_given?
40
69
  end
41
70
 
42
71
  # Is this menu selected? A menu is considered selected if it or any of
43
- # its submenus are selected
72
+ # its sub-menus are selected
44
73
  def selected?
45
- current_page?(@url_options) || @menu_bar.menus.any? {|menu| menu.selected?}
74
+ current_page?(url_options) || @menu_bar.selected?
46
75
  end
47
76
 
48
77
  # Builds the actual html of the menu
49
78
  def html(last = false)
50
79
  html_options = @html_options.dup
51
- html_options[:class] = (html_options[:class].to_s + ' selected').strip if selected?
52
- html_options[:class] = (html_options[:class].to_s + ' last').strip if last
80
+ html_options[:class] = "#{html_options[:class]} #{selected_class}".strip if selected?
81
+ html_options[:class] = "#{html_options[:class]} #{last_class}".strip if last
53
82
 
54
83
  content_tag(tag_name, content, html_options)
55
84
  end
56
85
 
57
86
  private
87
+ # List item
58
88
  def tag_name
59
89
  'li'
60
90
  end
61
91
 
92
+ # Generate the html for the menu
62
93
  def content
63
94
  content = @content
64
- content << @menu_bar.html if @menu_bar.menus.any?
95
+
96
+ if @menu_bar.menus.any?
97
+ # sub-menus have been defined: render markup
98
+ html = @menu_bar.html
99
+
100
+ if attach_active_submenus? || !selected?
101
+ content << html
102
+ else
103
+ # sub-menu bar will be generated elsewhere
104
+ request_controller.instance_variable_set(@menu_bar.content_for_variable, html)
105
+ end
106
+ end
107
+
65
108
  content
66
109
  end
67
110
 
@@ -69,11 +112,11 @@ module PluginAWeek #:nodoc:
69
112
  # the menu
70
113
  def build_url(options = {})
71
114
  # Check if the name given for the menu is a named route
72
- if options.blank? && route_options = (named_route(self[:id], @parent) || named_route(self[:id]))
115
+ if options.blank? && route_options = (named_route(name) || named_route(name, false))
73
116
  options = route_options
74
117
  elsif options.is_a?(Hash)
75
118
  options[:controller] ||= find_controller(options)
76
- options[:action] ||= self[:id] unless options[:controller] == self[:id]
119
+ options[:action] ||= name unless options[:controller] == name
77
120
  options[:only_path] ||= false
78
121
  end
79
122
 
@@ -81,25 +124,24 @@ module PluginAWeek #:nodoc:
81
124
  return url, options
82
125
  end
83
126
 
84
- # Finds the most likely controller that this menu should link to, in
85
- # order of:
86
- # 1. The specified controller in the menu link options
87
- # 2. The name of the menu (e.g. products = ProductsController)
88
- # 3. The parent's controller
89
- # 4. The request controller
127
+ # Finds the most likely controller that this menu should link to
90
128
  def find_controller(options)
129
+ # 1. Specified controller in the menu link options
91
130
  options[:controller] ||
92
- (begin; "#{self[:id].camelize}Controller".constantize.controller_path; rescue; nil; end) ||
93
- @parent && @parent.url_options[:controller] ||
94
- @request_controller.params[:controller]
131
+ # 2. The name of the menu (e.g. products = ProductsController)
132
+ (begin; "#{name.camelize}Controller".constantize.controller_path; rescue; end) ||
133
+ # 3. The parent's controller
134
+ parent_menu && parent_menu.url_options[:controller] ||
135
+ # 4. The request controller
136
+ request_controller.class.controller_path
95
137
  end
96
138
 
97
139
  # Finds the named route that is being linked to (if that route exists)
98
- def named_route(name, parent = nil)
99
- name = "#{parent[:id]}_#{name}" if parent
140
+ def named_route(name, include_parent = true)
141
+ name = "#{parent_menu.name}_#{name}" if parent_menu && include_parent
100
142
  method_name = "hash_for_#{name}_url"
101
143
 
102
- @request_controller.send(method_name) if @request_controller.respond_to?(method_name)
144
+ request_controller.send(method_name) if request_controller.respond_to?(method_name)
103
145
  end
104
146
  end
105
147
  end