menu_helper 0.0.1

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2007 Aaron Pfeifer & Neil Abraham
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
@@ -0,0 +1,108 @@
1
+ = menu_helper
2
+
3
+ menu_helper adds a helper method for generating a menubar.
4
+
5
+ == Resources
6
+
7
+ API
8
+
9
+ * http://api.pluginaweek.org/menu_helper
10
+
11
+ Wiki
12
+
13
+ * http://wiki.pluginaweek.org/Menu_helper
14
+
15
+ Announcement
16
+
17
+ * http://www.pluginaweek.org/
18
+
19
+ Source
20
+
21
+ * http://svn.pluginaweek.org/trunk/plugins/action_pack/menu_helper
22
+
23
+ Development
24
+
25
+ * http://dev.pluginaweek.org/browser/trunk/plugins/action_pack/menu_helper
26
+
27
+ == Description
28
+
29
+ The generation of a menubar's structure can often be a repetitive and unDRY
30
+ process. A standard using unordered lists is generally followed when creating
31
+ a menubar. menu_helper attempts to following this standard in addition to
32
+ automatically adding ids, classes for selected menus, and default urls each
33
+ menu is linked to (base on various information, such as the name of the menu).
34
+
35
+ == Example
36
+
37
+ routes.rb:
38
+ ActionController::Routing::Routes.draw do |map|
39
+ map.with_options(:controller => 'site') do |site|
40
+ site.home '', :action => 'index'
41
+ end
42
+
43
+ map.with_options(:controller => 'about_us') do |about_us|
44
+ about_us.about_us 'about_us', :action => 'index'
45
+ about_us.contact 'about_us/contact', :action => 'contact'
46
+ about_us.who_we_are 'about_us/who_we_are', :action => 'who_we_are'
47
+ end
48
+
49
+ map.with_options(:controller => 'products') do |products|
50
+ products.products 'products', :action => 'index'
51
+ end
52
+
53
+ map.with_options(:controller => 'services') do |services|
54
+ services.services 'services', :action => 'index'
55
+ end
56
+ end
57
+
58
+ _menubar.rhtml:
59
+ <%=
60
+ menu_bar do |main|
61
+ main.menu :home
62
+ main.menu :products
63
+ main.menu :services
64
+ main.menu :about_us do |about_us|
65
+ about_us.menu :overview, 'Overview', about_us_url
66
+ about_us.menu :who_we_are
67
+ about_us.menu :contact, 'Contact Us'
68
+ end
69
+ main.menu :search, 'Search!', 'http://www.google.com', :class => 'ir'
70
+ end
71
+ %>
72
+
73
+ Output (formatted for sanity):
74
+ <ul id="menubar">
75
+ <li id="home"><a href="http://example.com/">Home</a></li>
76
+ <li id="products"><a href="http://example.com/products">Products</a></li>
77
+ <li id="services"><a href="http://example.com/services">Services</a></li>
78
+ <li class="selected" id="about_us"><a href="http://example.com/about_us">About Us</a>
79
+ <ul id="about_us_menubar">
80
+ <li id="overview"><a href="http://example.com/about_us">Overview</a></li>
81
+ <li class="selected" id="who_we_are"><a href="http://example.com/about_us/who_we_are">Who We Are</a></li>
82
+ <li class="last" id="contact"><a href="http://example.com/about_us/contact">Contact Us</a></li>
83
+ </ul>
84
+ <li class="search ir" id="search"><a href="http://www.google.com">Search!</a></li>
85
+ </ul>
86
+
87
+ == Using this plugin
88
+
89
+ Remember one of the basic principles of programming: KISS. There's no need to
90
+ use this plugin if you're writing a very, very simple menubar. The advantages
91
+ of this helper are consistency, DRYness, and decreased complexity if you have
92
+ lots of submenus.
93
+
94
+ I wrote this plugin half as an experiment and half to actually use in a
95
+ production application. I recommend trying it out and seeing if it actually
96
+ fits the needs of your application before committing to using it.
97
+
98
+ == Testing
99
+
100
+ This plugin requires that the plugin_test_helper gem be installed in order to
101
+ run the unit tests. To install this gem:
102
+
103
+ gem install plugin_test_helper
104
+
105
+ == Dependencies
106
+
107
+ This plugin depends on the presence of the following plugins:
108
+ # set_or_append - http://wiki.pluginaweek.org/Set_or_append
data/Rakefile ADDED
@@ -0,0 +1,79 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/contrib/sshpublisher'
5
+
6
+ PKG_NAME = 'menu_helper'
7
+ PKG_VERSION = '0.0.1'
8
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
9
+ RUBY_FORGE_PROJECT = 'pluginaweek'
10
+
11
+ desc 'Default: run unit tests.'
12
+ task :default => :test
13
+
14
+ desc 'Test the menu_helper plugin.'
15
+ Rake::TestTask.new(:test) do |t|
16
+ t.libs << 'lib'
17
+ t.pattern = 'test/**/*_test.rb'
18
+ t.verbose = true
19
+ end
20
+
21
+ desc 'Generate documentation for the menu_helper plugin.'
22
+ Rake::RDocTask.new(:rdoc) do |rdoc|
23
+ rdoc.rdoc_dir = 'rdoc'
24
+ rdoc.title = 'MenuHelper'
25
+ rdoc.options << '--line-numbers' << '--inline-source'
26
+ rdoc.rdoc_files.include('README')
27
+ rdoc.rdoc_files.include('lib/**/*.rb')
28
+ end
29
+
30
+ spec = Gem::Specification.new do |s|
31
+ s.name = PKG_NAME
32
+ s.version = PKG_VERSION
33
+ s.platform = Gem::Platform::RUBY
34
+ s.summary = 'Adds a helper method for generating a menubar'
35
+
36
+ s.files = FileList['{lib,tasks,test}/**/*'].to_a + %w(init.rb MIT-LICENSE Rakefile README)
37
+ s.require_path = 'lib'
38
+ s.autorequire = 'menu_helper'
39
+ s.has_rdoc = true
40
+ s.test_files = Dir['test/**/*_test.rb']
41
+
42
+ s.author = 'Aaron Pfeifer, Neil Abraham'
43
+ s.email = 'info@pluginaweek.org'
44
+ s.homepage = 'http://www.pluginaweek.org'
45
+ end
46
+
47
+ Rake::GemPackageTask.new(spec) do |p|
48
+ p.gem_spec = spec
49
+ p.need_tar = true
50
+ p.need_zip = true
51
+ end
52
+
53
+ desc 'Publish the beta gem'
54
+ task :pgem => [:package] do
55
+ Rake::SshFilePublisher.new('pluginaweek@pluginaweek.org', '/home/pluginaweek/gems.pluginaweek.org/gems', 'pkg', "#{PKG_FILE_NAME}.gem").upload
56
+ end
57
+
58
+ desc 'Publish the API documentation'
59
+ task :pdoc => [:rdoc] do
60
+ Rake::SshDirPublisher.new('pluginaweek@pluginaweek.org', "/home/pluginaweek/api.pluginaweek.org/#{PKG_NAME}", 'rdoc').upload
61
+ end
62
+
63
+ desc 'Publish the API docs and gem'
64
+ task :publish => [:pdoc, :release]
65
+
66
+ desc 'Publish the release files to RubyForge.'
67
+ task :release => [:gem, :package] do
68
+ require 'rubyforge'
69
+
70
+ ruby_forge = RubyForge.new
71
+ ruby_forge.login
72
+
73
+ %w( gem tgz zip ).each do |ext|
74
+ file = "pkg/#{PKG_FILE_NAME}.#{ext}"
75
+ puts "Releasing #{File.basename(file)}..."
76
+
77
+ ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
78
+ end
79
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'menu_helper'
@@ -0,0 +1,48 @@
1
+ module PluginAWeek #:nodoc:
2
+ module Helpers #:nodoc:
3
+ module MenuHelper #:nodoc:
4
+ # Represents an HTML element
5
+ #
6
+ # == Modifying HTML options
7
+ #
8
+ # HTML options can normally be specified when creating the element.
9
+ # However, if they need to be modified after the element has been created,
10
+ # you can access the properties like so:
11
+ #
12
+ # m = Menu.new
13
+ # m[:style] = 'display: none;'
14
+ #
15
+ # or for a menu bar:
16
+ #
17
+ # b = MenuBar.new
18
+ # b[:style] = 'display: none;'
19
+ class HtmlElement
20
+ include ActionView::Helpers::TagHelper
21
+
22
+ delegate :[],
23
+ :[]=,
24
+ :to => '@html_options'
25
+
26
+ def initialize(html_options = {}) #:nodoc:
27
+ @html_options = html_options.symbolize_keys
28
+ end
29
+
30
+ # Generates the html representing this element
31
+ def html
32
+ content_tag(tag_name, content, @html_options)
33
+ end
34
+
35
+ private
36
+ # The name of the element tag to use (e.g. td, th, tr, etc.)
37
+ def tag_name
38
+ ''
39
+ end
40
+
41
+ # The content that will be displayed inside of the tag
42
+ def content
43
+ ''
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,101 @@
1
+ require 'set_or_append'
2
+
3
+ module PluginAWeek #:nodoc:
4
+ module Helpers #:nodoc:
5
+ module MenuHelper #:nodoc:
6
+ # Represents a single menu within a menu bar
7
+ class Menu < HtmlElement
8
+ include ActionView::Helpers::UrlHelper
9
+
10
+ # The url where this menu is linked to
11
+ attr_reader :url_options
12
+
13
+ # If there are submenus under this menu, they are stored in here
14
+ attr_reader :menu_bar
15
+
16
+ # Allow submenus to be created
17
+ delegate :menu,
18
+ :to => :menu_bar
19
+
20
+ def initialize(id, request_controller, parent = nil, *args) #:nodoc
21
+ id = id.to_s
22
+ @controller = @request_controller = request_controller
23
+ @parent = parent
24
+ @content = args.first.is_a?(String) ? args.shift : id.underscore.titleize
25
+ @url_options = args.shift || {}
26
+ super(args.shift || {})
27
+
28
+ # Set the default html options
29
+ @html_options[:id] ||= id
30
+
31
+ @menu_bar = MenuBar.new(@request_controller, {}, {:id => "#{self[:id]}_menubar"}, self)
32
+
33
+ # Build the url for the menu
34
+ url, @url_options = build_url(@url_options)
35
+ @content = link_to(@content, url) if auto_link?
36
+
37
+ yield self if block_given?
38
+ end
39
+
40
+ # Should we try to automatically generate the link?
41
+ def auto_link?
42
+ !@url_options.is_a?(Hash) || !@url_options.include?(:auto_link)
43
+ end
44
+
45
+ # Is this menu selected? A menu is considered selected if it or any of
46
+ # its submenus are selected
47
+ def selected?
48
+ current_page?(@url_options) || @menu_bar.menus.any? {|menu| menu.selected?}
49
+ end
50
+
51
+ # Builds the actual html of the menu
52
+ def build(last = false)
53
+ html = @content + @menu_bar.build
54
+ html_options = @html_options.dup
55
+ html_options.set_or_prepend(:class, 'selected') if selected?
56
+ html_options.set_or_prepend(:class, 'last') if last
57
+
58
+ content_tag('li', html, html_options)
59
+ end
60
+
61
+ private
62
+ # Builds the url based on the options provided in the construction of
63
+ # the menu
64
+ def build_url(options = {})
65
+ # Check if the name given for the menu is a named route
66
+ if options.blank? && route_options = (named_route(self[:id], @parent) || named_route(self[:id]))
67
+ options = route_options
68
+ elsif options.is_a?(Hash)
69
+ options[:controller] ||= find_controller(options)
70
+ options[:action] ||= self[:id] unless options[:controller] == self[:id]
71
+ options[:only_path] ||= false
72
+ end
73
+
74
+ url = options.is_a?(Hash) ? url_for(options) : options
75
+ return url, options
76
+ end
77
+
78
+ # Finds the most likely controller that this menu should link to, in
79
+ # order of:
80
+ # 1. The specified controller in the menu link options
81
+ # 2. The name of the menu (e.g. products = ProductsController)
82
+ # 3. The parent's controller
83
+ # 4. The request controller
84
+ def find_controller(options)
85
+ options[:controller] ||
86
+ (begin; "#{self[:id].camelize}Controller".constantize.controller_path; rescue; nil; end) ||
87
+ @parent && @parent.url_options[:controller] ||
88
+ @request_controller.params[:controller]
89
+ end
90
+
91
+ # Finds the named route that is being linked to (if that route exists)
92
+ def named_route(name, parent = nil)
93
+ name = "#{parent[:id]}_#{name}" if parent
94
+ method_name = "hash_for_#{name}_url"
95
+
96
+ @request_controller.send(method_name) if @request_controller.respond_to?(method_name)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,142 @@
1
+ module PluginAWeek #:nodoc:
2
+ module Helpers #:nodoc:
3
+ module MenuHelper #:nodoc:
4
+ # Represents a group of menus. A menu bar can either be the main menu
5
+ # bar or a menu bar nested within a menu.
6
+ class MenuBar < HtmlElement
7
+ # The menus within this menu bar
8
+ attr_reader :menus
9
+
10
+ def initialize(request_controller, options = {}, html_options = {}, parent_menu = nil) #:nodoc:
11
+ super(html_options)
12
+
13
+ options.assert_valid_keys(:auto_set_ids)
14
+ options.reverse_merge!(:auto_set_ids => true)
15
+ @options = options
16
+ @request_controller = request_controller
17
+ @parent_menu = parent_menu
18
+
19
+ @menus = []
20
+
21
+ if @parent_menu
22
+ self[:id] ||= "#{@parent_menu[:id]}_menubar"
23
+ else
24
+ self[:id] ||= 'menubar'
25
+ end
26
+
27
+ yield self if block_given?
28
+ end
29
+
30
+ # Creates a new menu in this bar with the given id. The content
31
+ # within the menu is, by default, set to a humanized version of the id.
32
+ #
33
+ # == URLs with routes
34
+ #
35
+ # If you have named routes setup in the application, the menu attempts
36
+ # to automatically figure out what URL you're trying to link to. It
37
+ # does this by looking at the id of the menu and the id of its parent.
38
+ #
39
+ # For example, a menu_bar with the id 'home' and a menu with the id
40
+ # 'contact_us' will attempt to look for the following named routes as
41
+ # the URL to link to (in order of priority):
42
+ # 1. contact_us_url
43
+ # 2. home_contact_us_url
44
+ #
45
+ # Example routes.rb:
46
+ # ActionController::Routing::Routes.draw do |map|
47
+ # map.with_options(:controller => 'home') do |home|
48
+ # home.home '', :action => 'index'
49
+ # home.home_search 'search', :action => 'search'
50
+ # end
51
+ #
52
+ # map.with_options(:controller => 'about_us') do |about_us|
53
+ # about_us.about_us 'about_us', :action => 'index'
54
+ # end
55
+ # end
56
+ #
57
+ # Example menubar:
58
+ # menu :home do |home|
59
+ # menu :about_us
60
+ # #=> Links to about_us_url
61
+ # menu :search
62
+ # #=> Links to home_search_url
63
+ # end
64
+ #
65
+ # == URLs with url_for
66
+ #
67
+ # If neither of these named routes are being used, the url will be based
68
+ # on the options passed into the menu. The url_options takes the same
69
+ # values as +url_for+. By default, the name of the controller will be
70
+ # guessed in the following order:
71
+ # 1. The id of the menu ('contact_us' => ContactUsController)
72
+ # 2. The controller of the parent menu/menu bar
73
+ # 3. The request controller
74
+ #
75
+ # To override the default controller being linked to, you can explicitly
76
+ # define it like so:
77
+ # menu :contact, 'Contact Us', {}, :controller => 'about_us'
78
+ #
79
+ # Examples:
80
+ # menu :home do |home|
81
+ # menu :about, 'About Us', :action => 'about_us'
82
+ # #=> Links to {:controller => 'home', :action => 'about_us'}
83
+ # menu :who_we_are
84
+ # #=> Links to {:controller => 'home', :action => 'who_we_are'}
85
+ # menu :contact_us, 'Contact Us', :controller => 'contact', :action => 'index'
86
+ # #=> Links to {:controller => 'contact', :action => 'index'}
87
+ # menu :search
88
+ # #=> Links to {:controller => 'search'}
89
+ # end
90
+ #
91
+ # You can also link to an explicit URL like so:
92
+ # menu :search, 'http://www.google.com'
93
+ #
94
+ # == Turning off links
95
+ #
96
+ # If you don't want a menu to link to a URL, you can turn off linking like so:
97
+ # menu :contact_us, 'Contact Us', {}, :auto_link => false
98
+ #
99
+ # == Defining content and html attributes
100
+ #
101
+ # By default, the content within a menu will be set as a humanized
102
+ # version of the menu's id. Examples of menus which customize the
103
+ # content and/or html attributes are below:
104
+ #
105
+ # menu :contact
106
+ # #=> <li id="contact"><a href="/contact">Contact</a></li>
107
+ # menu :contact, 'Contact Us'
108
+ # #=> <li id="contact"><a href="/contact">Contact Us</a></li>
109
+ # menu :contact, :class => 'pretty'
110
+ # #=> <li id="contact" class="pretty"><a href="/contact">Contact</a></li>
111
+ # menu :contact, 'Contact Us', :class => 'pretty'
112
+ # #=> <li id="contact" class="pretty"><a href="/contact">Contact Us</a></li>
113
+ #
114
+ # == Submenus
115
+ #
116
+ # Menus can also have their own submenus by passing in a block. You can
117
+ # create submenus in the same manner that the main menus are created.
118
+ # For example,
119
+ #
120
+ # menu :about do |about|
121
+ # about.menu :who_we_are
122
+ # about.menu :contact_us
123
+ # end
124
+ def menu(id, *args, &block)
125
+ menu = Menu.new(id, @request_controller, @parent_menu, *args, &block)
126
+ @menus << menu
127
+
128
+ menu
129
+ end
130
+
131
+ # Builds the actual html for the menu bar
132
+ def build
133
+ html = @menus.inject('') do |html, menu|
134
+ html << menu.build(@menus.last == menu)
135
+ end
136
+
137
+ html.blank? ? html : content_tag('ul', html, @html_options)
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,78 @@
1
+ require 'menu_helper/html_element'
2
+ require 'menu_helper/menu_bar'
3
+ require 'menu_helper/menu'
4
+
5
+ module PluginAWeek #:nodoc:
6
+ module Helpers #:nodoc:
7
+ # Provides a builder for generating html menubars. The structure of the
8
+ # menubars/menus is based on lists and should be styled using css.
9
+ module MenuHelper
10
+ # Creates a new 1st-level menu bar. The first parameter is the menubar's
11
+ # configuration options. The second parameter is the menubar's html
12
+ # options. Both of these parameters are optional.
13
+ #
14
+ # Configuration options:
15
+ # * <tt>auto_set_id</tt> - Whether or not to automatically add ids to each menu.
16
+ #
17
+ # Examples:
18
+ # menu_bar {}, :id => 'menus', :class => 'pretty' do |main|
19
+ # main.menu :home
20
+ # 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'
25
+ # end
26
+ # 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>
34
+ # </ul>
35
+ # </li>
36
+ # </ul>
37
+ #
38
+ # == Menu Selection
39
+ #
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
42
+ # current page, then that menu will be selected. This menu uses
43
+ # ActionView::Helpers::UrlHelper#current_page? to determine whether or not
44
+ # it is the currently selected menu.
45
+ #
46
+ # If the menu that is selected is nested within another menu, then those
47
+ # menus will be selected as well.
48
+ #
49
+ # A "selected" menu is indicated by an additional class html attribute
50
+ # that is added to the list item.
51
+ #
52
+ # For example, if a submenu is selected, the html generated from the
53
+ # above full example would look like so:
54
+ #
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>
61
+ # </ul>
62
+ # </li>
63
+ # </ul>
64
+ #
65
+ # == Menu Creation
66
+ #
67
+ # 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).build
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ ActionController::Base.class_eval do
77
+ helper PluginAWeek::Helpers::MenuHelper
78
+ end
@@ -0,0 +1,2 @@
1
+ class AboutUsController < ApplicationController
2
+ end
@@ -0,0 +1,2 @@
1
+ class ContactController < ApplicationController
2
+ end
@@ -0,0 +1,2 @@
1
+ class HomeController < ApplicationController
2
+ end
@@ -0,0 +1,15 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ # Home
3
+ map.with_options(:controller => 'home') do |home|
4
+ home.home '', :action => 'index'
5
+ home.home_search 'search_stuff', :action => 'search'
6
+ end
7
+
8
+ # Contact
9
+ map.with_options(:controller => 'contact') do |contact|
10
+ contact.contact 'contact', :action => 'index'
11
+ end
12
+
13
+ map.connect ':controller/:action/:id.:format'
14
+ map.connect ':controller/:action/:id'
15
+ end
@@ -0,0 +1,18 @@
1
+ $:.unshift("#{File.dirname(__FILE__)}/../../../ruby/hash/set_or_append/lib")
2
+
3
+ # Load the plugin testing framework
4
+ $:.unshift("#{File.dirname(__FILE__)}/../../../test/plugin_test_helper/lib")
5
+ require 'rubygems'
6
+ require 'plugin_test_helper'
7
+
8
+ class Test::Unit::TestCase
9
+ def setup
10
+ request = ActionController::TestRequest.new
11
+ request.request_uri = '/contact'
12
+ request.path_parameters = {:action => 'index', :controller => 'contact'}
13
+ @controller = HomeController.new
14
+ @controller.request = request
15
+ @controller.instance_eval {@_params = request.path_parameters}
16
+ @controller.send(:initialize_current_url)
17
+ end
18
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class HtmlElementTest < Test::Unit::TestCase
4
+ class DivElement < PluginAWeek::Helpers::MenuHelper::HtmlElement
5
+ def tag_name
6
+ 'div'
7
+ end
8
+ end
9
+
10
+ def test_html_options_on_initialization
11
+ e = PluginAWeek::Helpers::MenuHelper::HtmlElement.new('class' => 'fancy')
12
+ assert_equal 'fancy', e[:class]
13
+
14
+ e = PluginAWeek::Helpers::MenuHelper::HtmlElement.new(:class => 'fancy')
15
+ assert_equal 'fancy', e[:class]
16
+ end
17
+
18
+ def test_html_no_content
19
+ assert_equal '<></>', PluginAWeek::Helpers::MenuHelper::HtmlElement.new.html
20
+ end
21
+
22
+ def test_html_with_content
23
+ e = DivElement.new
24
+ e.instance_eval do
25
+ def content
26
+ 'hello world'
27
+ end
28
+ end
29
+
30
+ assert_equal '<div>hello world</div>', e.html
31
+ end
32
+
33
+ def test_html_with_html_options
34
+ e = DivElement.new
35
+ e[:class] = 'fancy'
36
+
37
+ assert_equal '<div class="fancy"></div>', e.html
38
+ end
39
+
40
+ def test_get_html_option
41
+ e = PluginAWeek::Helpers::MenuHelper::HtmlElement.new
42
+ assert_nil e[:class]
43
+ end
44
+
45
+ def test_set_html_option
46
+ e = PluginAWeek::Helpers::MenuHelper::HtmlElement.new
47
+ e[:float] = 'left'
48
+ assert_equal 'left', e[:float]
49
+ end
50
+ end
@@ -0,0 +1,60 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class MenuBarTest < Test::Unit::TestCase
4
+ def test_should_raise_exception_if_invalid_option_specified
5
+ assert_raise(ArgumentError) {create_menu_bar(:invalid => true)}
6
+ end
7
+
8
+ def test_should_have_no_menus_by_default
9
+ menu_bar = create_menu_bar
10
+ assert_equal [], menu_bar.menus
11
+ end
12
+
13
+ def test_should_set_default_id_if_no_parent_specified
14
+ menu_bar = create_menu_bar
15
+ assert_equal 'menubar', menu_bar[:id]
16
+ end
17
+
18
+ def test_should_set_default_id_based_on_parent_if_parent_specified
19
+ menu_bar = create_menu_bar({}, {}, PluginAWeek::Helpers::MenuHelper::Menu.new(:home, @controller))
20
+ assert_equal 'home_menubar', menu_bar[:id]
21
+ end
22
+
23
+ def test_should_accept_block
24
+ in_block = false
25
+ menu_bar = create_menu_bar do |main_menu|
26
+ in_block = true
27
+ end
28
+
29
+ assert in_block
30
+ end
31
+
32
+ def test_should_create_menus
33
+ menu_bar = create_menu_bar do |main|
34
+ main.menu :home
35
+ main.menu :contact
36
+ end
37
+
38
+ assert_equal 2, menu_bar.menus.size
39
+ end
40
+
41
+ def test_should_build_menu_bar_and_menus
42
+ menu_bar = create_menu_bar do |main|
43
+ main.menu :home
44
+ main.menu :contact, 'Contact Us'
45
+ end
46
+
47
+ expected = <<-eos
48
+ <ul id="menubar">
49
+ <li id="home"><a href="http://test.host/">Home</a></li>
50
+ <li class="last selected" id="contact"><a href="http://test.host/contact">Contact Us</a></li>
51
+ </ul>
52
+ eos
53
+ assert_equal expected.gsub(/\n\s*/, ''), menu_bar.build
54
+ end
55
+
56
+ private
57
+ def create_menu_bar(*args, &block)
58
+ PluginAWeek::Helpers::MenuHelper::MenuBar.new(@controller, *args, &block)
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class MenuHelperTest < Test::Unit::TestCase
4
+ include PluginAWeek::Helpers::MenuHelper
5
+
6
+ def test_should_build_menu_bar
7
+ menu_bar_html = menu_bar({}, :class => 'pretty') do |main|
8
+ main.menu :home do |home|
9
+ home.menu :browse
10
+ home.menu :search
11
+ end
12
+ main.menu :contact, 'Contact Us'
13
+ main.menu :about_us
14
+ end
15
+
16
+ expected = <<-eos
17
+ <ul class="pretty" id="menubar">
18
+ <li id="home"><a href="http://test.host/">Home</a>
19
+ <ul id="home_menubar">
20
+ <li id="browse"><a href="http://test.host/home/browse">Browse</a></li>
21
+ <li class="last" id="search"><a href="http://test.host/search_stuff">Search</a></li>
22
+ </ul>
23
+ </li>
24
+ <li class="selected" id="contact"><a href="http://test.host/contact">Contact Us</a></li>
25
+ <li class="last" id="about_us"><a href="http://test.host/about_us">About Us</a></li>
26
+ </ul>
27
+ eos
28
+ assert_equal expected.gsub(/\n\s*/, ''), menu_bar_html
29
+ end
30
+ end
@@ -0,0 +1,172 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class MenuTest < Test::Unit::TestCase
4
+ def test_default_content_should_be_humanized_id
5
+ menu = create_menu(:home)
6
+ assert_equal '<li id="home"><a href="http://test.host/">Home</a></li>', menu.build
7
+ end
8
+
9
+ def test_default_html_id_should_be_id
10
+ menu = create_menu(:home)
11
+ assert_equal 'home', menu[:id]
12
+ end
13
+
14
+ def test_should_not_linkify_if_not_auto_linking
15
+ menu = create_menu(:home, nil, :auto_link => false)
16
+ assert_equal '<li id="home">Home</li>', menu.build
17
+ end
18
+
19
+ def test_default_menubar_id_should_use_menu_id
20
+ menu = create_menu(:home, nil)
21
+ assert_equal 'home_menubar', menu.menu_bar[:id]
22
+ end
23
+
24
+ def test_should_not_auto_link_if_auto_link_is_false
25
+ menu = create_menu(:home, nil, :auto_link => false)
26
+ assert !menu.auto_link?
27
+ end
28
+
29
+ def test_should_auto_link_if_url_options_is_string
30
+ menu = create_menu(:home, nil, 'http://www.google.com')
31
+ assert menu.auto_link?
32
+ end
33
+
34
+ def test_should_auto_link_if_url_options_is_hash_without_auto_link
35
+ menu = create_menu(:home, nil, {})
36
+ assert menu.auto_link?
37
+ end
38
+
39
+ def test_should_be_selected_if_url_is_current_page
40
+ menu = create_menu(:contact)
41
+ assert menu.selected?
42
+ end
43
+
44
+ def test_should_be_selected_if_submenu_is_selected
45
+ menu = create_menu(:home) do |home|
46
+ home.menu :contact
47
+ end
48
+ assert menu.selected?
49
+ end
50
+
51
+ def test_should_be_selected_if_submenu_of_submenu_is_selected
52
+ menu = create_menu(:home) do |home|
53
+ home.menu :about_us do |about_us|
54
+ about_us.menu :contact
55
+ end
56
+ end
57
+ assert menu.selected?
58
+ end
59
+
60
+ def test_should_not_be_selected_if_url_is_not_current_page
61
+ menu = create_menu(:home)
62
+ assert !menu.selected?
63
+ end
64
+
65
+ def test_should_build_url_from_named_route_if_id_named_route_exists
66
+ menu = create_menu(:home)
67
+ expected = {:controller => 'home', :action => 'index', :only_path => false, :use_route => :home}
68
+ assert_equal expected, menu.url_options
69
+ end
70
+
71
+ def test_should_build_url_from_named_route_if_id_and_parent_named_route_exists
72
+ parent = create_menu(:home)
73
+ menu = create_menu(:search, parent)
74
+ expected = {:controller => 'home', :action => 'search', :only_path => false, :use_route => :home_search}
75
+ assert_equal expected, menu.url_options
76
+ end
77
+
78
+ def test_should_use_id_as_default_controller_if_controller_exists
79
+ menu = create_menu(:about_us)
80
+ expected = {:controller => 'about_us', :only_path => false}
81
+ assert_equal expected, menu.url_options
82
+ end
83
+
84
+ def test_should_use_parent_controller_as_default_controller_if_id_controller_does_not_exist
85
+ create_menu(:home) do |home|
86
+ menu = home.menu :privacy_policy
87
+ expected = {:controller => 'home', :action => 'privacy_policy', :only_path => false}
88
+ assert_equal expected, menu.url_options
89
+ end
90
+ end
91
+
92
+ def test_should_use_request_controller_as_default_controller_if_parent_and_id_controller_does_not_exist
93
+ menu = create_menu(:investors)
94
+ expected = {:controller => 'contact', :action => 'investors', :only_path => false}
95
+ assert_equal expected, menu.url_options
96
+ end
97
+
98
+ def test_should_use_custom_value_if_controller_is_specified
99
+ menu = create_menu(:privacy_policy, nil, :controller => 'home')
100
+ expected = {:controller => 'home', :action => 'privacy_policy', :only_path => false}
101
+ assert_equal expected, menu.url_options
102
+ end
103
+
104
+ def test_should_not_use_id_as_default_action_if_same_as_controller
105
+ menu = create_menu(:about_us, nil, :controller => 'about_us')
106
+ expected = {:controller => 'about_us', :only_path => false}
107
+ assert_equal expected, menu.url_options
108
+ end
109
+
110
+ def test_should_use_custom_value_if_action_is_specified
111
+ menu = create_menu(:privacy_policy, nil, :controller => 'home', :action => 'privacy')
112
+ expected = {:controller => 'home', :action => 'privacy', :only_path => false}
113
+ assert_equal expected, menu.url_options
114
+ end
115
+
116
+ def test_should_allow_string_urls
117
+ menu = create_menu(:search, nil, 'Search', 'http://www.google.com')
118
+ assert_equal 'http://www.google.com', menu.url_options
119
+ end
120
+
121
+ def test_should_include_selected_class_in_html_if_selected
122
+ menu = create_menu(:contact)
123
+ assert_equal '<li class="selected" id="contact"><a href="http://test.host/contact">Contact</a></li>', menu.build
124
+ end
125
+
126
+ def test_should_prepend_selected_class_if_class_attribute_already_exists
127
+ menu = create_menu(:contact, nil, {}, :class => 'pretty')
128
+ assert_equal '<li class="selected pretty" id="contact"><a href="http://test.host/contact">Contact</a></li>', menu.build
129
+ end
130
+
131
+ def test_should_include_last_class_in_html_if_last_menu
132
+ menu = create_menu(:home)
133
+ assert_equal '<li class="last" id="home"><a href="http://test.host/">Home</a></li>', menu.build(true)
134
+ end
135
+
136
+ def test_should_prepend_last_class_if_class_attribute_already_exists
137
+ menu = create_menu(:home, nil, {}, :class => 'pretty')
138
+ assert_equal '<li class="last pretty" id="home"><a href="http://test.host/">Home</a></li>', menu.build(true)
139
+ end
140
+
141
+ def test_should_not_modify_html_options_after_building_menu
142
+ menu = create_menu(:home)
143
+ menu.build
144
+ assert_nil menu[:class]
145
+ end
146
+
147
+ def test_should_include_submenus_if_submenus_exist
148
+ menu = create_menu(:home) do |home|
149
+ home.menu :about_us do |about_us|
150
+ about_us.menu :contact
151
+ end
152
+ end
153
+
154
+ expected = <<-eos
155
+ <li class="selected" id="home"><a href="http://test.host/">Home</a>
156
+ <ul id="home_menubar">
157
+ <li class="last selected" id="about_us"><a href="http://test.host/about_us">About Us</a>
158
+ <ul id="about_us_menubar">
159
+ <li class="last selected" id="contact"><a href="http://test.host/contact">Contact</a></li>
160
+ </ul>
161
+ </li>
162
+ </ul>
163
+ </li>
164
+ eos
165
+ assert_equal expected.gsub(/\n\s*/, ''), menu.build
166
+ end
167
+
168
+ private
169
+ def create_menu(id, parent = nil, *args, &block)
170
+ PluginAWeek::Helpers::MenuHelper::Menu.new(id, @controller, parent, *args, &block)
171
+ end
172
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: menu_helper
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-08-16 00:00:00 -04:00
8
+ summary: Adds a helper method for generating a menubar
9
+ require_paths:
10
+ - lib
11
+ email: info@pluginaweek.org
12
+ homepage: http://www.pluginaweek.org
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: menu_helper
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Aaron Pfeifer, Neil Abraham
31
+ files:
32
+ - lib/menu_helper.rb
33
+ - lib/menu_helper
34
+ - lib/menu_helper/html_element.rb
35
+ - lib/menu_helper/menu_bar.rb
36
+ - lib/menu_helper/menu.rb
37
+ - test/test_helper.rb
38
+ - test/app_root
39
+ - test/unit
40
+ - test/app_root/config
41
+ - test/app_root/app
42
+ - test/app_root/config/routes.rb
43
+ - test/app_root/app/controllers
44
+ - test/app_root/app/controllers/contact_controller.rb
45
+ - test/app_root/app/controllers/about_us_controller.rb
46
+ - test/app_root/app/controllers/home_controller.rb
47
+ - test/unit/html_element_test.rb
48
+ - test/unit/menu_test.rb
49
+ - test/unit/menu_helper_test.rb
50
+ - test/unit/menu_bar_test.rb
51
+ - init.rb
52
+ - MIT-LICENSE
53
+ - Rakefile
54
+ - README
55
+ test_files:
56
+ - test/unit/html_element_test.rb
57
+ - test/unit/menu_test.rb
58
+ - test/unit/menu_helper_test.rb
59
+ - test/unit/menu_bar_test.rb
60
+ rdoc_options: []
61
+
62
+ extra_rdoc_files: []
63
+
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ requirements: []
69
+
70
+ dependencies: []
71
+