tiny_navigation 0.1.1 → 0.1.3
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/.gitignore +2 -0
- data/.specification +119 -0
- data/README.rdoc +2 -2
- data/Rakefile +7 -3
- data/VERSION +1 -1
- data/init.rb +1 -2
- data/lib/tiny_navigation/controller/base.rb +36 -0
- data/lib/tiny_navigation/data/config.rb +46 -0
- data/lib/tiny_navigation/data/item.rb +78 -0
- data/lib/tiny_navigation/data/navigation.rb +68 -0
- data/lib/tiny_navigation.rb +40 -39
- data/rails/init.rb +1 -0
- data/test/navigation_test.rb +66 -11
- data/test/test_helper.rb +9 -3
- data/tiny_navigation.gemspec +19 -11
- metadata +49 -11
- data/lib/tiny_navigation/item.rb +0 -66
- data/lib/tiny_navigation/navigation.rb +0 -47
- data/pkg/simple_navigation-0.1.0.gem +0 -0
- data/pkg/tiny_navigation-0.1.0.gem +0 -0
- data/uninstall.rb +0 -1
data/.gitignore
ADDED
data/.specification
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tiny_navigation
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Coroutine
|
14
|
+
- Tim Lowrimore
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-07-12 00:00:00 -05:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: actionpack
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 11
|
31
|
+
segments:
|
32
|
+
- 2
|
33
|
+
- 3
|
34
|
+
- 4
|
35
|
+
version: 2.3.4
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: activesupport
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 11
|
47
|
+
segments:
|
48
|
+
- 2
|
49
|
+
- 3
|
50
|
+
- 4
|
51
|
+
version: 2.3.4
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
description: TinyNavigation makes it easy to define site navigation using a small DSL.
|
55
|
+
email: gems@coroutine.com
|
56
|
+
executables: []
|
57
|
+
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
extra_rdoc_files:
|
61
|
+
- README.rdoc
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- .specification
|
65
|
+
- MIT-LICENSE
|
66
|
+
- README.rdoc
|
67
|
+
- Rakefile
|
68
|
+
- VERSION
|
69
|
+
- generators/tiny_navigation/USAGE
|
70
|
+
- generators/tiny_navigation/templates/tiny_navigation.rb
|
71
|
+
- generators/tiny_navigation/tiny_navigation_generator.rb
|
72
|
+
- init.rb
|
73
|
+
- lib/tiny_navigation.rb
|
74
|
+
- lib/tiny_navigation/controller/base.rb
|
75
|
+
- lib/tiny_navigation/data/config.rb
|
76
|
+
- lib/tiny_navigation/data/item.rb
|
77
|
+
- lib/tiny_navigation/data/navigation.rb
|
78
|
+
- rails/init.rb
|
79
|
+
- test/navigation_test.rb
|
80
|
+
- test/test_helper.rb
|
81
|
+
- tiny_navigation.gemspec
|
82
|
+
has_rdoc: true
|
83
|
+
homepage: http://github.com/coroutine/tiny_navigation
|
84
|
+
licenses: []
|
85
|
+
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options:
|
88
|
+
- --charset=UTF-8
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
version: "0"
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
version: "0"
|
109
|
+
requirements: []
|
110
|
+
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 1.3.7
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: TinyNavigation provides an easy-to-use DSL for defining navigation structures.
|
116
|
+
test_files:
|
117
|
+
- test/navigation_test.rb
|
118
|
+
- test/test_helper.rb
|
119
|
+
|
data/README.rdoc
CHANGED
@@ -111,7 +111,7 @@ The resulting structure could be used to generate the markup. For example:
|
|
111
111
|
|
112
112
|
*IMPORTANT* if a custom attribute is defined on an item, as mentioned earlier,
|
113
113
|
it will take precedence over a controller attribute of the same name, thus
|
114
|
-
hiding access to the controller attribute.
|
114
|
+
hiding access to the controller attribute from within the config file.
|
115
115
|
|
116
116
|
=== Here are a couple things that TinyNavigation WILL NOT do:
|
117
117
|
|
@@ -119,7 +119,7 @@ The resulting structure could be used to generate the markup. For example:
|
|
119
119
|
to you. You may want to render your nav items into <tt>div</tt> tags, while
|
120
120
|
I may want to use an unordered list. That's fine, go for it.
|
121
121
|
|
122
|
-
* TinyNavigation does provide authorization logic for limiting access to
|
122
|
+
* TinyNavigation does not provide authorization logic for limiting access to
|
123
123
|
navigation items; that's a separate concern. It's easy enough to use
|
124
124
|
an authorization gem that does that job quite well, and by allowing for calls
|
125
125
|
to the current controller from within config/tiny_navigation.rb, you can
|
data/Rakefile
CHANGED
@@ -25,12 +25,16 @@ end
|
|
25
25
|
begin
|
26
26
|
require 'jeweler'
|
27
27
|
Jeweler::Tasks.new do |gemspec|
|
28
|
-
gemspec.
|
29
|
-
gemspec.summary = "TinyNavigation provides an easy-to-use DSL for defining navigation structures."
|
28
|
+
gemspec.authors = ["Coroutine", "Tim Lowrimore"]
|
30
29
|
gemspec.description = "TinyNavigation makes it easy to define site navigation using a small DSL."
|
31
30
|
gemspec.email = "gems@coroutine.com"
|
32
31
|
gemspec.homepage = "http://github.com/coroutine/tiny_navigation"
|
33
|
-
gemspec.
|
32
|
+
gemspec.name = "tiny_navigation"
|
33
|
+
gemspec.summary = "TinyNavigation provides an easy-to-use DSL for defining navigation structures."
|
34
|
+
|
35
|
+
gemspec.add_dependency("actionpack", ">= 2.3.4")
|
36
|
+
gemspec.add_development_dependency("activesupport", ">= 2.3.4")
|
37
|
+
gemspec.files.include("lib/**/*.rb")
|
34
38
|
end
|
35
39
|
Jeweler::GemcutterTasks.new
|
36
40
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/init.rb
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
require "
|
2
|
-
ActionController::Base.class_eval { include Coroutine::TinyNavigation::ControllerMethods }
|
1
|
+
require File.dirname(__FILE__) + "/rails/init.rb"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Coroutine #:nodoc:
|
2
|
+
module TinyNavigation #:nodoc:
|
3
|
+
module Controller #:nodoc:
|
4
|
+
|
5
|
+
# This module provides the core controller functionality implemented by
|
6
|
+
# the gem.
|
7
|
+
#
|
8
|
+
module Base
|
9
|
+
|
10
|
+
def self.included(base) #:nodoc:
|
11
|
+
base.send(:include, InstanceMethods)
|
12
|
+
base.send(:helper_method, :navigation)
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
# This module contains instance methods that will be mixed into the extended
|
17
|
+
# controller.
|
18
|
+
#
|
19
|
+
module InstanceMethods
|
20
|
+
private
|
21
|
+
|
22
|
+
# This method returns a Coroutine::TinyNavigation::Data::Navigation object for
|
23
|
+
# the supplied navigation name.
|
24
|
+
#
|
25
|
+
def navigation(which_navigation)
|
26
|
+
config = Coroutine::TinyNavigation::Data::Config.new self
|
27
|
+
config.nav[which_navigation]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Coroutine #:nodoc:
|
2
|
+
module TinyNavigation #:nodoc:
|
3
|
+
module Data #:nodoc:
|
4
|
+
|
5
|
+
# This class represents a configuration object. It is responsible for reading in the
|
6
|
+
# DSL and converting it to a structured set of navigation objects.
|
7
|
+
#
|
8
|
+
class Config #:nodoc:
|
9
|
+
|
10
|
+
attr_reader :nav
|
11
|
+
|
12
|
+
# This method creates a new configuration object. It reads in the configuration
|
13
|
+
# file and saves the contents to a class variable so it only has to be loaded
|
14
|
+
# once.
|
15
|
+
#
|
16
|
+
# <tt>current_controller</tt> is a reference to the controller object being extended.
|
17
|
+
#
|
18
|
+
# <tt>config</tt> is the location of the config file to load. Defaults to the generated
|
19
|
+
# file.
|
20
|
+
#
|
21
|
+
def initialize(current_controller, conf=File.join(Rails.root, "config", "tiny_navigation.rb"))
|
22
|
+
@current_controller = current_controller
|
23
|
+
@nav = {}
|
24
|
+
|
25
|
+
Config.class_eval { class << self; attr_reader :file end; @file ||= File.read(conf) }
|
26
|
+
|
27
|
+
self.instance_eval(Config.file);
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# This method adds a navigation structure to the application.
|
34
|
+
#
|
35
|
+
# <tt>name</tt> is the key in the navigation hash.
|
36
|
+
#
|
37
|
+
def navigation(name, &block)
|
38
|
+
raise "Navigation names must be unique. You specified '#{name}' twice." if @nav.has_key?(name)
|
39
|
+
@nav[name] = Navigation.new(name, @current_controller, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Coroutine #:nodoc:
|
2
|
+
module TinyNavigation #:nodoc:
|
3
|
+
module Data #:nodoc:
|
4
|
+
|
5
|
+
# This class represents a navigation item. It holds all the data for item
|
6
|
+
# and provides a number of convenience methods related to that item.
|
7
|
+
#
|
8
|
+
class Item < Navigation
|
9
|
+
|
10
|
+
# This method creates a new instance of a navigation item.
|
11
|
+
#
|
12
|
+
# <tt>name</tt> is the name of the navigation item. The name should
|
13
|
+
# be used for the label text when rendering the navigation item.
|
14
|
+
#
|
15
|
+
# <tt>current_controller</tt> the currently loaded controller
|
16
|
+
#
|
17
|
+
# <tt>options</tt> provide configuration options and custom properties
|
18
|
+
# to the nav item. Currently, the only configuration option is
|
19
|
+
# <tt>:to</tt> which is used to generate the URL of the navigation item.
|
20
|
+
# All other options provided to via the <tt>options</tt> hash will be
|
21
|
+
# treated as custom properties on the navigation item. These custom
|
22
|
+
# properties can be accessed as methods on the navigation item.
|
23
|
+
#
|
24
|
+
# The block given to the navigation item is used to define sub-navigation
|
25
|
+
# items of this item.
|
26
|
+
#
|
27
|
+
def initialize(name, current_controller, options={}, &block)
|
28
|
+
super name, current_controller, &block
|
29
|
+
set_controller_and_action options.delete(:to)
|
30
|
+
@extra_options = options
|
31
|
+
end
|
32
|
+
|
33
|
+
# This method indicates whether the navigation item is currently selected.
|
34
|
+
# This takes into account any sub-nav items such that a parent item is
|
35
|
+
# selected if it has a selected child.
|
36
|
+
#
|
37
|
+
def selected?
|
38
|
+
@controller_name == @current_controller.controller_name || @items.any?(&:selected?)
|
39
|
+
end
|
40
|
+
|
41
|
+
# This method returns the URL to which the navigation item points. This
|
42
|
+
# should be used in a scenario where the navigation item represents a link
|
43
|
+
# and the URL is the href of that link.
|
44
|
+
#
|
45
|
+
def url
|
46
|
+
@current_controller.url_for :controller => @controller_name, :action => @action_name
|
47
|
+
end
|
48
|
+
|
49
|
+
# This method uses the extra_options hash takes precendence when looking
|
50
|
+
# for the called method. Otherwise, we'll let the super-class forward
|
51
|
+
# the method call to the current controller.
|
52
|
+
#
|
53
|
+
def method_missing(method_name, *args) #:nodoc:
|
54
|
+
if @extra_options.has_key? method_name
|
55
|
+
@extra_options[method_name]
|
56
|
+
else
|
57
|
+
super method_name, *args
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# This method converts the :to option value into controller and action
|
65
|
+
# values.
|
66
|
+
#
|
67
|
+
def set_controller_and_action(to)
|
68
|
+
if to
|
69
|
+
controller_and_action = to.split "#"
|
70
|
+
@controller_name = controller_and_action.shift
|
71
|
+
@action_name = controller_and_action.shift || "index"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Coroutine #:nodoc:
|
2
|
+
module TinyNavigation #:nodoc:
|
3
|
+
module Data #:nodoc:
|
4
|
+
|
5
|
+
# This class represents a navigation tree. It holds all the data for tree
|
6
|
+
# and provides a number of convenience methods related to that tree.
|
7
|
+
#
|
8
|
+
class Navigation
|
9
|
+
|
10
|
+
attr_reader :name, :items
|
11
|
+
|
12
|
+
# This method creates a new navigation data object.
|
13
|
+
#
|
14
|
+
# <tt>name</tt> is the unique identifer of the navigation.
|
15
|
+
#
|
16
|
+
# <tt>current_controller</tt> the currently loaded controller
|
17
|
+
#
|
18
|
+
# The block given to the navigation item is used to define navigation
|
19
|
+
# items of this navigation object.
|
20
|
+
#
|
21
|
+
def initialize(name, current_controller, &block)
|
22
|
+
@items = []
|
23
|
+
@name = name
|
24
|
+
@current_controller = current_controller
|
25
|
+
|
26
|
+
self.instance_eval(&block) if block_given?
|
27
|
+
end
|
28
|
+
|
29
|
+
# This method returns an array of selected navigation items. The array
|
30
|
+
# represents a bread-crumb list in that the head of the list represents
|
31
|
+
# a top-level navigation item, and the tail of the list represents selected
|
32
|
+
# sub-navigation items.
|
33
|
+
#
|
34
|
+
# <tt>item</tt> is the reference point for the calculation.
|
35
|
+
#
|
36
|
+
def selected(item=self)
|
37
|
+
items = []
|
38
|
+
item.items.each do |item|
|
39
|
+
items << item << selected(item) if item.selected?
|
40
|
+
end
|
41
|
+
items.flatten
|
42
|
+
end
|
43
|
+
|
44
|
+
# This method delegates method missing calls to the controller, in case
|
45
|
+
# the navigation item has user-defined properties.
|
46
|
+
#
|
47
|
+
def method_missing(method_name, *args) #:nodoc:
|
48
|
+
@current_controller.send method_name, *args
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# This method adds a new item to the items collection.
|
55
|
+
#
|
56
|
+
# <tt>name</tt> is the friendly name for the navigation item.
|
57
|
+
#
|
58
|
+
# <tt>options</tt> is a hash containing any user-defined properties.
|
59
|
+
#
|
60
|
+
def item(name, options={}, &block)
|
61
|
+
@items << Item.new(name, @current_controller, options, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/tiny_navigation.rb
CHANGED
@@ -1,7 +1,32 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
#------------------------------------------------------------
|
2
|
+
# setup
|
3
|
+
#------------------------------------------------------------
|
3
4
|
|
4
|
-
|
5
|
+
# external gems
|
6
|
+
require "action_pack"
|
7
|
+
require "action_controller"
|
8
|
+
|
9
|
+
|
10
|
+
# add data files
|
11
|
+
require File.dirname(__FILE__) + "/tiny_navigation/data/config"
|
12
|
+
require File.dirname(__FILE__) + "/tiny_navigation/data/navigation"
|
13
|
+
require File.dirname(__FILE__) + "/tiny_navigation/data/item"
|
14
|
+
|
15
|
+
|
16
|
+
# add controller files
|
17
|
+
require File.dirname(__FILE__) + "/tiny_navigation/controller/base"
|
18
|
+
|
19
|
+
|
20
|
+
# add extensions to action controller
|
21
|
+
::ActionController::Base.send(:include, Coroutine::TinyNavigation::Controller::Base)
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
#------------------------------------------------------------
|
26
|
+
# doc namespaces
|
27
|
+
#------------------------------------------------------------
|
28
|
+
|
29
|
+
module Coroutine #:nodoc:
|
5
30
|
|
6
31
|
# TinyNavigation provides an easy-to-use DSL for defining navigation structures;
|
7
32
|
# these structures are defined in config/tiny_navigation.rb.
|
@@ -80,49 +105,25 @@ module Coroutine
|
|
80
105
|
# to you. You may want to render your nav items into <tt>div</tt> tags, while
|
81
106
|
# I may want to use an unordered list. That's fine, go for it.
|
82
107
|
#
|
83
|
-
# * TinyNavigation does provide authorization logic for limiting access to
|
108
|
+
# * TinyNavigation does not provide authorization logic for limiting access to
|
84
109
|
# navigation items; that's a separate concern. It's easy enough to use
|
85
110
|
# an authorization gem that does that job quite well, and by allowing for calls
|
86
111
|
# to the current controller from within config/tiny_navigation.rb you can
|
87
112
|
# do that.
|
113
|
+
#
|
88
114
|
module TinyNavigation
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
@current_controller = current_controller
|
95
|
-
@nav = {}
|
96
|
-
|
97
|
-
# Make sure we only load the config file the first time the navigation is loaded
|
98
|
-
# and never again.
|
99
|
-
Config.class_eval { class << self; attr_reader :file end; @file ||= File.read(conf) }
|
100
|
-
self.instance_eval(Config.file);
|
101
|
-
end
|
102
|
-
|
103
|
-
private
|
104
|
-
|
105
|
-
def navigation(name, &block)
|
106
|
-
raise "Navigation names must be unique. You specified '#{name}' twice." if @nav.has_key?(name)
|
107
|
-
@nav[name] = Navigation.new(name, @current_controller, &block)
|
108
|
-
end
|
115
|
+
|
116
|
+
# This module defines all behavior and logic related to extending controller
|
117
|
+
# behavior.
|
118
|
+
#
|
119
|
+
module Controller
|
109
120
|
end
|
110
121
|
|
111
|
-
# This module
|
112
|
-
#
|
113
|
-
|
114
|
-
|
115
|
-
base.send :helper_method, :navigation
|
116
|
-
end
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
# Returns a Coroutine::TinyNavigation::Navigation object for the supplied
|
121
|
-
# navigation name.
|
122
|
-
def navigation(which_navigation)
|
123
|
-
config = Coroutine::TinyNavigation::Config.new self
|
124
|
-
config.nav[which_navigation]
|
125
|
-
end
|
122
|
+
# This module defines all objects that primarily serve to provide data structures
|
123
|
+
# and access methods.
|
124
|
+
#
|
125
|
+
module Data
|
126
126
|
end
|
127
|
+
|
127
128
|
end
|
128
129
|
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "tiny_navigation"
|
data/test/navigation_test.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
3
|
-
require 'tiny_navigation/item'
|
2
|
+
|
4
3
|
|
5
4
|
class NavigationTest < ActiveSupport::TestCase
|
6
5
|
|
@@ -9,23 +8,74 @@ class NavigationTest < ActiveSupport::TestCase
|
|
9
8
|
@current_controller = @controller_class.new("tests")
|
10
9
|
end
|
11
10
|
|
12
|
-
|
11
|
+
|
12
|
+
#-------------------------------------------------------------------------------
|
13
|
+
# Definition tests
|
14
|
+
#-------------------------------------------------------------------------------
|
15
|
+
|
16
|
+
# flat structure
|
17
|
+
test "can create a navigation with one level of nesting" do
|
18
|
+
nav = navigation do
|
19
|
+
item "Foos", :to => "foos#index"
|
20
|
+
item "Bars", :to => "bars#index"
|
21
|
+
end
|
22
|
+
|
23
|
+
assert_equal 2, nav.items.length
|
24
|
+
end
|
25
|
+
|
26
|
+
# nested structure
|
27
|
+
test "can create a navigation with multiple levels of nesting" do
|
13
28
|
nav = navigation do
|
14
29
|
item "Foos", :to => "foos#index"
|
30
|
+
item "Bars", :to => "bars#index" do
|
31
|
+
item "Tests", :to => "tests#index"
|
32
|
+
end
|
15
33
|
end
|
16
34
|
|
17
|
-
assert_equal nav.items.length
|
35
|
+
assert_equal 2, nav.items.length
|
36
|
+
assert_equal 1, nav.items.last.items.length
|
18
37
|
end
|
19
38
|
|
39
|
+
# with conditions
|
40
|
+
test "can create a navigation with conditional inclusion" do
|
41
|
+
nav = navigation do
|
42
|
+
item "Foos", :to => "foos#index" if 1 == 1
|
43
|
+
item "Bars", :to => "bars#index" if 1 == 2
|
44
|
+
item "Tests", :to => "tests#index"
|
45
|
+
end
|
46
|
+
|
47
|
+
assert_equal 2, nav.items.length
|
48
|
+
end
|
49
|
+
|
50
|
+
# extra options
|
51
|
+
test "can create a navigation with user-defined properties on items" do
|
52
|
+
nav = navigation do
|
53
|
+
item "Foos", :to => "foos#index", :align => :left
|
54
|
+
item "Bars", :to => "bars#index", :align => :right
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal 2, nav.items.length
|
58
|
+
assert_equal :left, nav.items.first.align
|
59
|
+
assert_equal :right, nav.items.last.align
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
#-------------------------------------------------------------------------------
|
65
|
+
# Selection tests
|
66
|
+
#-------------------------------------------------------------------------------
|
67
|
+
|
68
|
+
# flat structure
|
20
69
|
test "has correct selected item in one level of nesting" do
|
21
70
|
nav = navigation do
|
22
71
|
item "Tests", :to => "tests"
|
23
72
|
end
|
24
73
|
|
25
|
-
assert_equal nav.selected.length
|
26
|
-
assert_equal nav.selected.first.name
|
74
|
+
assert_equal 1, nav.selected.length
|
75
|
+
assert_equal "Tests", nav.selected.first.name
|
27
76
|
end
|
28
77
|
|
78
|
+
# nested structure
|
29
79
|
test "has correct selected items in multiple levels of nesting" do
|
30
80
|
nav = navigation do
|
31
81
|
item "Foos", :to => "foos#index" do
|
@@ -33,17 +83,22 @@ class NavigationTest < ActiveSupport::TestCase
|
|
33
83
|
end
|
34
84
|
end
|
35
85
|
|
36
|
-
assert_equal nav.selected.length
|
37
|
-
assert_equal
|
86
|
+
assert_equal 2, nav.selected.length
|
87
|
+
assert_equal ["Foos", "Tests"], nav.selected.map(&:name)
|
38
88
|
end
|
39
89
|
|
40
|
-
|
90
|
+
|
91
|
+
|
92
|
+
#-------------------------------------------------------------------------------
|
41
93
|
# Helpers
|
42
|
-
|
94
|
+
#-------------------------------------------------------------------------------
|
43
95
|
|
44
96
|
private
|
45
97
|
|
98
|
+
# This method bootstraps a navigation call in lieu of loading a config file.
|
99
|
+
#
|
46
100
|
def navigation(name = :main, current_controller = @current_controller, &block)
|
47
|
-
Coroutine::TinyNavigation::Navigation.new(name, current_controller, &block)
|
101
|
+
Coroutine::TinyNavigation::Data::Navigation.new(name, current_controller, &block)
|
48
102
|
end
|
103
|
+
|
49
104
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
# require rails stuff
|
2
|
+
require "rubygems"
|
3
|
+
require "active_support"
|
4
|
+
require "active_support/test_case"
|
5
|
+
require "test/unit"
|
6
|
+
|
7
|
+
|
8
|
+
# require gem/plugin
|
9
|
+
require "#{File.dirname(__FILE__)}/../init"
|
data/tiny_navigation.gemspec
CHANGED
@@ -5,18 +5,20 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tiny_navigation}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Coroutine", "Tim Lowrimore"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-07-28}
|
13
13
|
s.description = %q{TinyNavigation makes it easy to define site navigation using a small DSL.}
|
14
14
|
s.email = %q{gems@coroutine.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
|
-
"
|
19
|
+
".gitignore",
|
20
|
+
".specification",
|
21
|
+
"MIT-LICENSE",
|
20
22
|
"README.rdoc",
|
21
23
|
"Rakefile",
|
22
24
|
"VERSION",
|
@@ -25,19 +27,19 @@ Gem::Specification.new do |s|
|
|
25
27
|
"generators/tiny_navigation/tiny_navigation_generator.rb",
|
26
28
|
"init.rb",
|
27
29
|
"lib/tiny_navigation.rb",
|
28
|
-
"lib/tiny_navigation/
|
29
|
-
"lib/tiny_navigation/
|
30
|
-
"
|
31
|
-
"
|
30
|
+
"lib/tiny_navigation/controller/base.rb",
|
31
|
+
"lib/tiny_navigation/data/config.rb",
|
32
|
+
"lib/tiny_navigation/data/item.rb",
|
33
|
+
"lib/tiny_navigation/data/navigation.rb",
|
34
|
+
"rails/init.rb",
|
32
35
|
"test/navigation_test.rb",
|
33
36
|
"test/test_helper.rb",
|
34
|
-
"tiny_navigation.gemspec"
|
35
|
-
"uninstall.rb"
|
37
|
+
"tiny_navigation.gemspec"
|
36
38
|
]
|
37
39
|
s.homepage = %q{http://github.com/coroutine/tiny_navigation}
|
38
40
|
s.rdoc_options = ["--charset=UTF-8"]
|
39
41
|
s.require_paths = ["lib"]
|
40
|
-
s.rubygems_version = %q{1.3.
|
42
|
+
s.rubygems_version = %q{1.3.7}
|
41
43
|
s.summary = %q{TinyNavigation provides an easy-to-use DSL for defining navigation structures.}
|
42
44
|
s.test_files = [
|
43
45
|
"test/navigation_test.rb",
|
@@ -48,10 +50,16 @@ Gem::Specification.new do |s|
|
|
48
50
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
51
|
s.specification_version = 3
|
50
52
|
|
51
|
-
if Gem::Version.new(Gem::
|
53
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
+
s.add_runtime_dependency(%q<actionpack>, [">= 2.3.4"])
|
55
|
+
s.add_development_dependency(%q<activesupport>, [">= 2.3.4"])
|
52
56
|
else
|
57
|
+
s.add_dependency(%q<actionpack>, [">= 2.3.4"])
|
58
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
53
59
|
end
|
54
60
|
else
|
61
|
+
s.add_dependency(%q<actionpack>, [">= 2.3.4"])
|
62
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.4"])
|
55
63
|
end
|
56
64
|
end
|
57
65
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tiny_navigation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Coroutine
|
@@ -15,10 +16,41 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-
|
19
|
+
date: 2010-07-28 00:00:00 -05:00
|
19
20
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: actionpack
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 11
|
31
|
+
segments:
|
32
|
+
- 2
|
33
|
+
- 3
|
34
|
+
- 4
|
35
|
+
version: 2.3.4
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: activesupport
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 11
|
47
|
+
segments:
|
48
|
+
- 2
|
49
|
+
- 3
|
50
|
+
- 4
|
51
|
+
version: 2.3.4
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
22
54
|
description: TinyNavigation makes it easy to define site navigation using a small DSL.
|
23
55
|
email: gems@coroutine.com
|
24
56
|
executables: []
|
@@ -28,6 +60,8 @@ extensions: []
|
|
28
60
|
extra_rdoc_files:
|
29
61
|
- README.rdoc
|
30
62
|
files:
|
63
|
+
- .gitignore
|
64
|
+
- .specification
|
31
65
|
- MIT-LICENSE
|
32
66
|
- README.rdoc
|
33
67
|
- Rakefile
|
@@ -37,14 +71,14 @@ files:
|
|
37
71
|
- generators/tiny_navigation/tiny_navigation_generator.rb
|
38
72
|
- init.rb
|
39
73
|
- lib/tiny_navigation.rb
|
40
|
-
- lib/tiny_navigation/
|
41
|
-
- lib/tiny_navigation/
|
42
|
-
-
|
43
|
-
-
|
74
|
+
- lib/tiny_navigation/controller/base.rb
|
75
|
+
- lib/tiny_navigation/data/config.rb
|
76
|
+
- lib/tiny_navigation/data/item.rb
|
77
|
+
- lib/tiny_navigation/data/navigation.rb
|
78
|
+
- rails/init.rb
|
44
79
|
- test/navigation_test.rb
|
45
80
|
- test/test_helper.rb
|
46
81
|
- tiny_navigation.gemspec
|
47
|
-
- uninstall.rb
|
48
82
|
has_rdoc: true
|
49
83
|
homepage: http://github.com/coroutine/tiny_navigation
|
50
84
|
licenses: []
|
@@ -55,23 +89,27 @@ rdoc_options:
|
|
55
89
|
require_paths:
|
56
90
|
- lib
|
57
91
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
58
93
|
requirements:
|
59
94
|
- - ">="
|
60
95
|
- !ruby/object:Gem::Version
|
96
|
+
hash: 3
|
61
97
|
segments:
|
62
98
|
- 0
|
63
99
|
version: "0"
|
64
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
65
102
|
requirements:
|
66
103
|
- - ">="
|
67
104
|
- !ruby/object:Gem::Version
|
105
|
+
hash: 3
|
68
106
|
segments:
|
69
107
|
- 0
|
70
108
|
version: "0"
|
71
109
|
requirements: []
|
72
110
|
|
73
111
|
rubyforge_project:
|
74
|
-
rubygems_version: 1.3.
|
112
|
+
rubygems_version: 1.3.7
|
75
113
|
signing_key:
|
76
114
|
specification_version: 3
|
77
115
|
summary: TinyNavigation provides an easy-to-use DSL for defining navigation structures.
|
data/lib/tiny_navigation/item.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'tiny_navigation/navigation'
|
2
|
-
|
3
|
-
module Coroutine
|
4
|
-
module TinyNavigation
|
5
|
-
class Item < Navigation
|
6
|
-
|
7
|
-
# Creates a new instance of a navigation item.
|
8
|
-
#
|
9
|
-
# <tt>name</tt> is the name of the navigation item. The name should
|
10
|
-
# be used for the label text when rendering the navigation item.
|
11
|
-
#
|
12
|
-
# <tt>current_controller</tt> the currently loaded controller
|
13
|
-
#
|
14
|
-
# <tt>options</tt> provide configuration options and custom properties
|
15
|
-
# to the nav item. Currently, the only configuration option is
|
16
|
-
# <tt>:to</tt> which is used to generate the URL of the navigation item.
|
17
|
-
# All other options provided to via the <tt>options</tt> hash will be
|
18
|
-
# treated as custom properties on the navigation item. These custom
|
19
|
-
# properties can be accessed as methods on the navigation item.
|
20
|
-
#
|
21
|
-
# The block given to the navigation item is used to define sub-navigation
|
22
|
-
# items of this item.
|
23
|
-
def initialize(name, current_controller, options={}, &block)
|
24
|
-
super name, current_controller, &block
|
25
|
-
set_controller_and_action options.delete(:to)
|
26
|
-
@extra_options = options
|
27
|
-
end
|
28
|
-
|
29
|
-
# Indicates whether the navigation item is currently selected. This
|
30
|
-
# takes into account any sub-nav items such that a parent item is selected
|
31
|
-
# if it has a selected child.
|
32
|
-
def selected?
|
33
|
-
@controller_name == @current_controller.controller_name || @items.any?(&:selected?)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Returns the URL to which the navigation item points. This should be
|
37
|
-
# used in a scenario where the navigation item represents a link and the
|
38
|
-
# URL is the href of that link.
|
39
|
-
def url
|
40
|
-
@current_controller.url_for :controller => @controller_name, :action => @action_name
|
41
|
-
end
|
42
|
-
|
43
|
-
def method_missing(method_name, *args) #:nodoc:
|
44
|
-
|
45
|
-
# The extra_options hash takes precendence when looking for the
|
46
|
-
# called method. Otherwise, we'll let the super-class forward
|
47
|
-
# the method call to the current controller.
|
48
|
-
if @extra_options.has_key? method_name
|
49
|
-
@extra_options[method_name]
|
50
|
-
else
|
51
|
-
super method_name, *args
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def set_controller_and_action(to)
|
58
|
-
if to
|
59
|
-
controller_and_action = to.split "#"
|
60
|
-
@controller_name = controller_and_action.shift
|
61
|
-
@action_name = controller_and_action.shift || "index"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
module Coroutine
|
2
|
-
module TinyNavigation
|
3
|
-
class Navigation
|
4
|
-
|
5
|
-
attr_reader :name, :items
|
6
|
-
|
7
|
-
# Creates a new navigation.
|
8
|
-
#
|
9
|
-
# <tt>name</tt> is the unique identifer of the navigation.
|
10
|
-
#
|
11
|
-
# <tt>current_controller</tt> the currently loaded controller
|
12
|
-
#
|
13
|
-
# The block given to the navigation item is used to define navigation
|
14
|
-
# items of this navigation object.
|
15
|
-
def initialize(name, current_controller, &block)
|
16
|
-
@items = []
|
17
|
-
@name = name
|
18
|
-
@current_controller = current_controller
|
19
|
-
|
20
|
-
self.instance_eval(&block) if block_given?
|
21
|
-
end
|
22
|
-
|
23
|
-
# Returns an array of selected navigation items. The array represents a
|
24
|
-
# bread-crumb list in that the head of the list represents a top-level
|
25
|
-
# navigation item, and the tail of the list represents selected sub-navigation
|
26
|
-
# items.
|
27
|
-
def selected(item=self)
|
28
|
-
items = []
|
29
|
-
item.items.each do |item|
|
30
|
-
items << item << selected(item) if item.selected?
|
31
|
-
end
|
32
|
-
items.flatten
|
33
|
-
end
|
34
|
-
|
35
|
-
def method_missing(method_name, *args) #:nodoc:
|
36
|
-
@current_controller.send method_name, *args
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def item(name, options={}, &block)
|
42
|
-
@items << Item.new(name, @current_controller, options, &block)
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
Binary file
|
Binary file
|
data/uninstall.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# Uninstall hook code here
|