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 +20 -0
- data/README +108 -0
- data/Rakefile +79 -0
- data/init.rb +1 -0
- data/lib/menu_helper/html_element.rb +48 -0
- data/lib/menu_helper/menu.rb +101 -0
- data/lib/menu_helper/menu_bar.rb +142 -0
- data/lib/menu_helper.rb +78 -0
- data/test/app_root/app/controllers/about_us_controller.rb +2 -0
- data/test/app_root/app/controllers/contact_controller.rb +2 -0
- data/test/app_root/app/controllers/home_controller.rb +2 -0
- data/test/app_root/config/routes.rb +15 -0
- data/test/test_helper.rb +18 -0
- data/test/unit/html_element_test.rb +50 -0
- data/test/unit/menu_bar_test.rb +60 -0
- data/test/unit/menu_helper_test.rb +30 -0
- data/test/unit/menu_test.rb +172 -0
- metadata +71 -0
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
|
data/lib/menu_helper.rb
ADDED
@@ -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,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
|
data/test/test_helper.rb
ADDED
@@ -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
|
+
|