menu_helper 0.0.5 → 0.1.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/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