menu_helper 0.0.1

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