menu_helper 0.0.1 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +31 -0
- data/MIT-LICENSE +2 -2
- data/README +30 -33
- data/Rakefile +9 -8
- data/lib/menu_helper/html_element.rb +45 -47
- data/lib/menu_helper/menu.rb +98 -93
- data/lib/menu_helper/menu_bar.rb +141 -141
- data/lib/menu_helper.rb +72 -73
- data/test/app_root/log/in_memory.log +1 -0
- data/test/test_helper.rb +1 -3
- data/test/unit/html_element_test.rb +73 -49
- data/test/unit/menu_bar_test.rb +31 -19
- data/test/unit/menu_helper_test.rb +5 -5
- data/test/unit/menu_test.rb +28 -23
- metadata +57 -47
data/CHANGELOG
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
*SVN*
|
2
|
+
|
3
|
+
*0.0.4* (June 1st, 2008)
|
4
|
+
|
5
|
+
* Remove dependency on set_or_append
|
6
|
+
|
7
|
+
*0.0.3* (May 5th, 2008)
|
8
|
+
|
9
|
+
* Updated documentation
|
10
|
+
|
11
|
+
*0.0.2* (September 26th, 2007)
|
12
|
+
|
13
|
+
* Add gem dependency on set_or_append
|
14
|
+
|
15
|
+
* Convert dos newlines to unix newlines
|
16
|
+
|
17
|
+
* Fix too many :nodoc: tags so that rdocs are generated properly
|
18
|
+
|
19
|
+
*0.0.1* (August 16th, 2007)
|
20
|
+
|
21
|
+
* Add README documentation
|
22
|
+
|
23
|
+
* Add api documentation
|
24
|
+
|
25
|
+
* Add dependency on plugin_test_helper in order to simplify the test setup code
|
26
|
+
|
27
|
+
* Remove MainMenuBar in favor of providing a default id for MenuBar
|
28
|
+
|
29
|
+
* Refactor helper classes into individual files
|
30
|
+
|
31
|
+
* Add unit tests
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2006-
|
1
|
+
Copyright (c) 2006-2008 Aaron Pfeifer
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
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.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
CHANGED
@@ -1,29 +1,25 @@
|
|
1
1
|
= menu_helper
|
2
2
|
|
3
|
-
menu_helper adds a helper method for generating a menubar.
|
3
|
+
+menu_helper+ adds a helper method for generating a menubar.
|
4
4
|
|
5
5
|
== Resources
|
6
6
|
|
7
|
-
API
|
8
|
-
|
9
|
-
* http://api.pluginaweek.org/menu_helper
|
10
|
-
|
11
7
|
Wiki
|
12
8
|
|
13
9
|
* http://wiki.pluginaweek.org/Menu_helper
|
14
10
|
|
15
|
-
|
16
|
-
|
17
|
-
* http://www.pluginaweek.org/
|
18
|
-
|
19
|
-
Source
|
11
|
+
API
|
20
12
|
|
21
|
-
* http://
|
13
|
+
* http://api.pluginaweek.org/menu_helper
|
22
14
|
|
23
15
|
Development
|
24
16
|
|
25
17
|
* http://dev.pluginaweek.org/browser/trunk/plugins/action_pack/menu_helper
|
26
18
|
|
19
|
+
Source
|
20
|
+
|
21
|
+
* http://svn.pluginaweek.org/trunk/plugins/action_pack/menu_helper
|
22
|
+
|
27
23
|
== Description
|
28
24
|
|
29
25
|
The generation of a menubar's structure can often be a repetitive and unDRY
|
@@ -32,7 +28,7 @@ a menubar. menu_helper attempts to following this standard in addition to
|
|
32
28
|
automatically adding ids, classes for selected menus, and default urls each
|
33
29
|
menu is linked to (base on various information, such as the name of the menu).
|
34
30
|
|
35
|
-
==
|
31
|
+
== Usage
|
36
32
|
|
37
33
|
routes.rb:
|
38
34
|
ActionController::Routing::Routes.draw do |map|
|
@@ -55,19 +51,19 @@ routes.rb:
|
|
55
51
|
end
|
56
52
|
end
|
57
53
|
|
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'
|
54
|
+
_menubar.rhtml:
|
55
|
+
<%=
|
56
|
+
menu_bar do |main|
|
57
|
+
main.menu :home
|
58
|
+
main.menu :products
|
59
|
+
main.menu :services
|
60
|
+
main.menu :about_us do |about_us|
|
61
|
+
about_us.menu :overview, 'Overview', about_us_url
|
62
|
+
about_us.menu :who_we_are
|
63
|
+
about_us.menu :contact, 'Contact Us'
|
68
64
|
end
|
69
|
-
main.menu :search, 'Search!', 'http://www.google.com', :class => 'ir'
|
70
|
-
end
|
65
|
+
main.menu :search, 'Search!', 'http://www.google.com', :class => 'ir'
|
66
|
+
end
|
71
67
|
%>
|
72
68
|
|
73
69
|
Output (formatted for sanity):
|
@@ -84,25 +80,26 @@ Output (formatted for sanity):
|
|
84
80
|
<li class="search ir" id="search"><a href="http://www.google.com">Search!</a></li>
|
85
81
|
</ul>
|
86
82
|
|
87
|
-
|
83
|
+
=== Caveat Emptor
|
88
84
|
|
89
85
|
Remember one of the basic principles of programming: KISS. There's no need to
|
90
86
|
use this plugin if you're writing a very, very simple menubar. The advantages
|
91
87
|
of this helper are consistency, DRYness, and decreased complexity if you have
|
92
88
|
lots of submenus.
|
93
89
|
|
94
|
-
I wrote this plugin
|
95
|
-
|
96
|
-
fits the needs of your application before committing to using it.
|
90
|
+
I wrote this plugin mostly as an educational/experimental piece, so I don't using
|
91
|
+
this in a production application, but rather a prototype.
|
97
92
|
|
98
93
|
== Testing
|
99
94
|
|
100
|
-
|
101
|
-
|
95
|
+
To test this plugin, the following gems must be installed:
|
96
|
+
* plugin_test_helper[http://wiki.pluginaweek.org/Plugin_test_helper]
|
97
|
+
|
98
|
+
To run against a specific version of Rails:
|
102
99
|
|
103
|
-
|
100
|
+
rake test RAILS_FRAMEWORK_ROOT=/path/to/rails
|
104
101
|
|
105
102
|
== Dependencies
|
106
103
|
|
107
|
-
|
108
|
-
|
104
|
+
* Rails 2.0 or later
|
105
|
+
* set_or_append[http://wiki.pluginaweek.org/Set_or_append]
|
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require 'rake/gempackagetask'
|
|
4
4
|
require 'rake/contrib/sshpublisher'
|
5
5
|
|
6
6
|
PKG_NAME = 'menu_helper'
|
7
|
-
PKG_VERSION = '0.0.
|
7
|
+
PKG_VERSION = '0.0.4'
|
8
8
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
9
9
|
RUBY_FORGE_PROJECT = 'pluginaweek'
|
10
10
|
|
@@ -22,6 +22,7 @@ desc 'Generate documentation for the menu_helper plugin.'
|
|
22
22
|
Rake::RDocTask.new(:rdoc) do |rdoc|
|
23
23
|
rdoc.rdoc_dir = 'rdoc'
|
24
24
|
rdoc.title = 'MenuHelper'
|
25
|
+
rdoc.template = '../rdoc_template.rb'
|
25
26
|
rdoc.options << '--line-numbers' << '--inline-source'
|
26
27
|
rdoc.rdoc_files.include('README')
|
27
28
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
@@ -33,14 +34,14 @@ spec = Gem::Specification.new do |s|
|
|
33
34
|
s.platform = Gem::Platform::RUBY
|
34
35
|
s.summary = 'Adds a helper method for generating a menubar'
|
35
36
|
|
36
|
-
s.files = FileList['{lib,
|
37
|
+
s.files = FileList['{lib,test}/**/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
|
37
38
|
s.require_path = 'lib'
|
38
39
|
s.autorequire = 'menu_helper'
|
39
40
|
s.has_rdoc = true
|
40
41
|
s.test_files = Dir['test/**/*_test.rb']
|
41
42
|
|
42
|
-
s.author = 'Aaron Pfeifer
|
43
|
-
s.email = '
|
43
|
+
s.author = 'Aaron Pfeifer'
|
44
|
+
s.email = 'aaron@pluginaweek.org'
|
44
45
|
s.homepage = 'http://www.pluginaweek.org'
|
45
46
|
end
|
46
47
|
|
@@ -52,22 +53,22 @@ end
|
|
52
53
|
|
53
54
|
desc 'Publish the beta gem'
|
54
55
|
task :pgem => [:package] do
|
55
|
-
Rake::SshFilePublisher.new('
|
56
|
+
Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{PKG_FILE_NAME}.gem").upload
|
56
57
|
end
|
57
58
|
|
58
59
|
desc 'Publish the API documentation'
|
59
60
|
task :pdoc => [:rdoc] do
|
60
|
-
Rake::SshDirPublisher.new('
|
61
|
+
Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{PKG_NAME}", 'rdoc').upload
|
61
62
|
end
|
62
63
|
|
63
64
|
desc 'Publish the API docs and gem'
|
64
|
-
task :publish => [:pdoc, :release]
|
65
|
+
task :publish => [:pgem, :pdoc, :release]
|
65
66
|
|
66
67
|
desc 'Publish the release files to RubyForge.'
|
67
68
|
task :release => [:gem, :package] do
|
68
69
|
require 'rubyforge'
|
69
70
|
|
70
|
-
ruby_forge = RubyForge.new
|
71
|
+
ruby_forge = RubyForge.new.configure
|
71
72
|
ruby_forge.login
|
72
73
|
|
73
74
|
%w( gem tgz zip ).each do |ext|
|
@@ -1,48 +1,46 @@
|
|
1
|
-
module PluginAWeek #:nodoc:
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
1
|
+
module PluginAWeek #:nodoc:
|
2
|
+
module MenuHelper
|
3
|
+
# Represents an HTML element
|
4
|
+
#
|
5
|
+
# == Modifying HTML options
|
6
|
+
#
|
7
|
+
# HTML options can normally be specified when creating the element.
|
8
|
+
# However, if they need to be modified after the element has been created,
|
9
|
+
# you can access the properties like so:
|
10
|
+
#
|
11
|
+
# m = Menu.new
|
12
|
+
# m[:style] = 'display: none;'
|
13
|
+
#
|
14
|
+
# or for a menu bar:
|
15
|
+
#
|
16
|
+
# b = MenuBar.new
|
17
|
+
# b[:style] = 'display: none;'
|
18
|
+
class HtmlElement
|
19
|
+
include ActionView::Helpers::TagHelper
|
20
|
+
|
21
|
+
delegate :[],
|
22
|
+
:[]=,
|
23
|
+
:to => '@html_options'
|
24
|
+
|
25
|
+
def initialize(html_options = {}) #:nodoc:
|
26
|
+
@html_options = html_options.symbolize_keys
|
27
|
+
end
|
28
|
+
|
29
|
+
# Generates the html representing this element
|
30
|
+
def html
|
31
|
+
content_tag(tag_name, content, @html_options)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
# The name of the element tag to use (e.g. td, th, tr, etc.)
|
36
|
+
def tag_name
|
37
|
+
''
|
38
|
+
end
|
39
|
+
|
40
|
+
# The content that will be displayed inside of the tag
|
41
|
+
def content
|
42
|
+
''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
48
46
|
end
|
data/lib/menu_helper/menu.rb
CHANGED
@@ -1,101 +1,106 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
1
|
+
module PluginAWeek #:nodoc:
|
2
|
+
module MenuHelper
|
3
|
+
# Represents a single menu within a menu bar
|
4
|
+
class Menu < HtmlElement
|
5
|
+
include ActionView::Helpers::UrlHelper
|
6
|
+
|
7
|
+
# The url where this menu is linked to
|
8
|
+
attr_reader :url_options
|
9
|
+
|
10
|
+
# If there are submenus under this menu, they are stored in here
|
11
|
+
attr_reader :menu_bar
|
12
|
+
|
13
|
+
# Allow submenus to be created
|
14
|
+
delegate :menu,
|
15
|
+
:to => :menu_bar
|
16
|
+
|
17
|
+
def initialize(id, request_controller, parent = nil, *args) #:nodoc
|
18
|
+
id = id.to_s
|
19
|
+
@controller = @request_controller = request_controller
|
20
|
+
@parent = parent
|
21
|
+
@content = args.first.is_a?(String) ? args.shift : id.underscore.titleize
|
22
|
+
@url_options = args.shift || {}
|
23
|
+
super(args.shift || {})
|
24
|
+
|
25
|
+
# Set the default html options
|
26
|
+
@html_options[:id] ||= id
|
27
|
+
|
28
|
+
@menu_bar = MenuBar.new(@request_controller, {}, {:id => "#{self[:id]}_menubar"}, self)
|
29
|
+
|
30
|
+
# Build the url for the menu
|
31
|
+
url, @url_options = build_url(@url_options)
|
32
|
+
@content = link_to(@content, url) if auto_link?
|
33
|
+
|
34
|
+
yield self if block_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Should we try to automatically generate the link?
|
38
|
+
def auto_link?
|
39
|
+
!@url_options.is_a?(Hash) || !@url_options.include?(:auto_link) || @url_options[:auto_link]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Is this menu selected? A menu is considered selected if it or any of
|
43
|
+
# its submenus are selected
|
44
|
+
def selected?
|
45
|
+
current_page?(@url_options) || @menu_bar.menus.any? {|menu| menu.selected?}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Builds the actual html of the menu
|
49
|
+
def html(last = false)
|
50
|
+
html_options = @html_options.dup
|
51
|
+
html_options[:class] = (html_options[:class].to_s + ' selected').strip if selected?
|
52
|
+
html_options[:class] = (html_options[:class].to_s + ' last').strip if last
|
53
|
+
|
54
|
+
content_tag(tag_name, content, html_options)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def tag_name
|
59
|
+
'li'
|
60
|
+
end
|
61
|
+
|
62
|
+
def content
|
63
|
+
content = @content
|
64
|
+
content << @menu_bar.html if @menu_bar.menus.any?
|
65
|
+
content
|
66
|
+
end
|
15
67
|
|
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
68
|
# 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
|
69
|
+
# the menu
|
70
|
+
def build_url(options = {})
|
71
|
+
# Check if the name given for the menu is a named route
|
72
|
+
if options.blank? && route_options = (named_route(self[:id], @parent) || named_route(self[:id]))
|
73
|
+
options = route_options
|
68
74
|
elsif options.is_a?(Hash)
|
69
|
-
options[:controller] ||= find_controller(options)
|
75
|
+
options[:controller] ||= find_controller(options)
|
70
76
|
options[:action] ||= self[:id] unless options[:controller] == self[:id]
|
71
77
|
options[:only_path] ||= false
|
72
78
|
end
|
73
79
|
|
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
|
-
|
99
|
-
|
100
|
-
end
|
80
|
+
url = options.is_a?(Hash) ? url_for(options) : options
|
81
|
+
return url, options
|
82
|
+
end
|
83
|
+
|
84
|
+
# Finds the most likely controller that this menu should link to, in
|
85
|
+
# order of:
|
86
|
+
# 1. The specified controller in the menu link options
|
87
|
+
# 2. The name of the menu (e.g. products = ProductsController)
|
88
|
+
# 3. The parent's controller
|
89
|
+
# 4. The request controller
|
90
|
+
def find_controller(options)
|
91
|
+
options[:controller] ||
|
92
|
+
(begin; "#{self[:id].camelize}Controller".constantize.controller_path; rescue; nil; end) ||
|
93
|
+
@parent && @parent.url_options[:controller] ||
|
94
|
+
@request_controller.params[:controller]
|
95
|
+
end
|
96
|
+
|
97
|
+
# Finds the named route that is being linked to (if that route exists)
|
98
|
+
def named_route(name, parent = nil)
|
99
|
+
name = "#{parent[:id]}_#{name}" if parent
|
100
|
+
method_name = "hash_for_#{name}_url"
|
101
|
+
|
102
|
+
@request_controller.send(method_name) if @request_controller.respond_to?(method_name)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
101
106
|
end
|