simple-navigation 3.12.0 → 3.12.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/generators/navigation_config/navigation_config_generator.rb +3 -3
- data/generators/navigation_config/templates/config/navigation.rb +9 -10
- data/init.rb +1 -1
- data/lib/generators/navigation_config/navigation_config_generator.rb +11 -6
- data/lib/simple-navigation.rb +1 -1
- data/lib/simple_navigation.rb +93 -65
- data/lib/simple_navigation/adapters/base.rb +16 -16
- data/lib/simple_navigation/adapters/nanoc.rb +7 -6
- data/lib/simple_navigation/adapters/padrino.rb +5 -7
- data/lib/simple_navigation/adapters/rails.rb +52 -39
- data/lib/simple_navigation/adapters/sinatra.rb +14 -17
- data/lib/simple_navigation/core/configuration.rb +73 -34
- data/lib/simple_navigation/core/item.rb +110 -54
- data/lib/simple_navigation/core/item_adapter.rb +18 -13
- data/lib/simple_navigation/core/item_container.rb +93 -66
- data/lib/simple_navigation/core/items_provider.rb +12 -10
- data/lib/simple_navigation/rails_controller_methods.rb +98 -78
- data/lib/simple_navigation/rendering/helpers.rb +130 -68
- data/lib/simple_navigation/rendering/renderer/base.rb +30 -25
- data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +26 -19
- data/lib/simple_navigation/rendering/renderer/json.rb +11 -13
- data/lib/simple_navigation/rendering/renderer/links.rb +18 -13
- data/lib/simple_navigation/rendering/renderer/list.rb +28 -15
- data/lib/simple_navigation/rendering/renderer/text.rb +7 -12
- data/lib/simple_navigation/version.rb +1 -1
- data/spec/lib/simple_navigation/core/item_adapter_spec.rb +1 -1
- data/spec/lib/simple_navigation/core/item_container_spec.rb +118 -68
- data/spec/lib/simple_navigation_spec.rb +16 -5
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
class NavigationConfigGenerator < Rails::Generator::Base
|
2
2
|
def manifest
|
3
3
|
record do |m|
|
4
|
-
m.file
|
5
|
-
m.readme
|
4
|
+
m.file 'config/navigation.rb', 'config/navigation.rb'
|
5
|
+
m.readme '../../../README.md'
|
6
6
|
end
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
@@ -6,8 +6,8 @@ SimpleNavigation::Configuration.run do |navigation|
|
|
6
6
|
# The renderer can also be specified as option in the render_navigation call.
|
7
7
|
# navigation.renderer = Your::Custom::Renderer
|
8
8
|
|
9
|
-
# Specify the class that will be applied to active navigation items.
|
10
|
-
# navigation.selected_class = 'your_selected_class'
|
9
|
+
# Specify the class that will be applied to active navigation items.
|
10
|
+
# Defaults to 'selected' navigation.selected_class = 'your_selected_class'
|
11
11
|
|
12
12
|
# Specify the class that will be applied to the current leaf of
|
13
13
|
# active navigation items. Defaults to 'simple-navigation-active-leaf'
|
@@ -22,7 +22,8 @@ SimpleNavigation::Configuration.run do |navigation|
|
|
22
22
|
# The example below would add a prefix to each key.
|
23
23
|
# navigation.id_generator = Proc.new {|key| "my-prefix-#{key}"}
|
24
24
|
|
25
|
-
# If you need to add custom html around item names, you can define a proc that
|
25
|
+
# If you need to add custom html around item names, you can define a proc that
|
26
|
+
# will be called with the name you pass in to the navigation.
|
26
27
|
# The example below shows how to wrap items spans.
|
27
28
|
# navigation.name_generator = Proc.new {|name, item| "<span>#{name}</span>"}
|
28
29
|
|
@@ -42,15 +43,15 @@ SimpleNavigation::Configuration.run do |navigation|
|
|
42
43
|
# options - can be used to specify attributes that will be included in the rendered navigation item (e.g. id, class etc.)
|
43
44
|
# some special options that can be set:
|
44
45
|
# :if - Specifies a proc to call to determine if the item should
|
45
|
-
# be rendered (e.g. <tt
|
46
|
+
# be rendered (e.g. <tt>if: -> { current_user.admin? }</tt>). The
|
46
47
|
# proc should evaluate to a true or false value and is evaluated in the context of the view.
|
47
48
|
# :unless - Specifies a proc to call to determine if the item should not
|
48
|
-
# be rendered (e.g. <tt
|
49
|
+
# be rendered (e.g. <tt>unless: -> { current_user.admin? }</tt>). The
|
49
50
|
# proc should evaluate to a true or false value and is evaluated in the context of the view.
|
50
51
|
# :method - Specifies the http-method for the generated link - default is :get.
|
51
52
|
# :highlights_on - if autohighlighting is turned off and/or you want to explicitly specify
|
52
53
|
# when the item should be highlighted, you can set a regexp which is matched
|
53
|
-
# against the current URI. You may also use a proc, or the symbol <tt>:subpath</tt>.
|
54
|
+
# against the current URI. You may also use a proc, or the symbol <tt>:subpath</tt>.
|
54
55
|
#
|
55
56
|
primary.item :key_1, 'name', url, options
|
56
57
|
|
@@ -63,8 +64,8 @@ SimpleNavigation::Configuration.run do |navigation|
|
|
63
64
|
# You can also specify a condition-proc that needs to be fullfilled to display an item.
|
64
65
|
# Conditions are part of the options. They are evaluated in the context of the views,
|
65
66
|
# thus you can use all the methods and vars you have available in the views.
|
66
|
-
primary.item :key_3, 'Admin', url, :
|
67
|
-
primary.item :key_4, 'Account', url, :
|
67
|
+
primary.item :key_3, 'Admin', url, class: 'special', if: -> { current_user.admin? }
|
68
|
+
primary.item :key_4, 'Account', url, unless: -> { logged_in? }
|
68
69
|
|
69
70
|
# you can also specify html attributes to attach to this particular level
|
70
71
|
# works for all levels of the menu
|
@@ -72,7 +73,5 @@ SimpleNavigation::Configuration.run do |navigation|
|
|
72
73
|
|
73
74
|
# You can turn off auto highlighting for a specific level
|
74
75
|
# primary.auto_highlight = false
|
75
|
-
|
76
76
|
end
|
77
|
-
|
78
77
|
end
|
data/init.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require File.dirname(__FILE__) +
|
1
|
+
require File.dirname(__FILE__) + '/rails/init'
|
@@ -1,12 +1,17 @@
|
|
1
1
|
class NavigationConfigGenerator < Rails::Generators::Base
|
2
2
|
def self.source_root
|
3
|
-
@source_root ||=
|
3
|
+
@source_root ||= begin
|
4
|
+
tpl_dir = %w[.. .. .. .. generators navigation_config templates]
|
5
|
+
tpl_dir_path = File.join(tpl_dir)
|
6
|
+
File.expand_path(tpl_dir_path, __FILE__)
|
7
|
+
end
|
4
8
|
end
|
5
9
|
|
6
|
-
desc 'Creates a template config file for the simple-navigation plugin.
|
10
|
+
desc 'Creates a template config file for the simple-navigation plugin. ' \
|
11
|
+
'You will find the generated file in config/navigation.rb.'
|
7
12
|
def navigation_config
|
8
|
-
copy_file('config/navigation.rb', 'config/navigation.rb')
|
9
|
-
|
13
|
+
copy_file('config/navigation.rb', 'config/navigation.rb')
|
14
|
+
readme_path = File.join(%w[.. .. .. .. README.md])
|
15
|
+
say File.read(File.expand_path(readme_path, __FILE__))
|
10
16
|
end
|
11
|
-
|
12
|
-
end
|
17
|
+
end
|
data/lib/simple-navigation.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'simple_navigation'
|
1
|
+
require 'simple_navigation'
|
data/lib/simple_navigation.rb
CHANGED
@@ -10,37 +10,52 @@ require 'simple_navigation/adapters'
|
|
10
10
|
|
11
11
|
require 'forwardable'
|
12
12
|
|
13
|
-
# A plugin for generating a simple navigation. See README for resources on
|
13
|
+
# A plugin for generating a simple navigation. See README for resources on
|
14
|
+
# usage instructions.
|
14
15
|
module SimpleNavigation
|
15
|
-
|
16
|
-
|
16
|
+
mattr_accessor :adapter,
|
17
|
+
:adapter_class,
|
18
|
+
:config_files,
|
19
|
+
:config_file_paths,
|
20
|
+
:default_renderer,
|
21
|
+
:environment,
|
22
|
+
:registered_renderers,
|
23
|
+
:root
|
17
24
|
|
18
25
|
# Cache for loaded config files
|
19
26
|
self.config_files = {}
|
20
27
|
|
21
|
-
# Allows for multiple config_file_paths. Needed if a plugin itself uses
|
28
|
+
# Allows for multiple config_file_paths. Needed if a plugin itself uses
|
29
|
+
# simple-navigation and therefore has its own config file
|
22
30
|
self.config_file_paths = []
|
23
|
-
|
24
|
-
# Maps renderer keys to classes. The keys serve as shortcut in the
|
31
|
+
|
32
|
+
# Maps renderer keys to classes. The keys serve as shortcut in the
|
33
|
+
# render_navigation calls (renderer: :list)
|
25
34
|
self.registered_renderers = {
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
35
|
+
list: SimpleNavigation::Renderer::List,
|
36
|
+
links: SimpleNavigation::Renderer::Links,
|
37
|
+
breadcrumbs: SimpleNavigation::Renderer::Breadcrumbs,
|
38
|
+
text: SimpleNavigation::Renderer::Text,
|
39
|
+
json: SimpleNavigation::Renderer::Json
|
31
40
|
}
|
32
|
-
|
41
|
+
|
33
42
|
class << self
|
34
43
|
extend Forwardable
|
35
|
-
|
36
|
-
def_delegators :adapter, :
|
44
|
+
|
45
|
+
def_delegators :adapter, :context_for_eval,
|
46
|
+
:current_page?,
|
47
|
+
:request,
|
48
|
+
:request_path,
|
49
|
+
:request_uri
|
50
|
+
|
37
51
|
def_delegators :adapter_class, :register
|
38
52
|
|
39
|
-
# Sets the root path and current environment as specified. Also sets the
|
53
|
+
# Sets the root path and current environment as specified. Also sets the
|
54
|
+
# default config_file_path.
|
40
55
|
def set_env(root, environment)
|
41
56
|
self.root = root
|
42
57
|
self.environment = environment
|
43
|
-
|
58
|
+
config_file_paths << SimpleNavigation.default_config_file_path
|
44
59
|
end
|
45
60
|
|
46
61
|
# Returns the current framework in which the plugin is running.
|
@@ -49,30 +64,29 @@ module SimpleNavigation
|
|
49
64
|
return :padrino if defined?(Padrino)
|
50
65
|
return :sinatra if defined?(Sinatra)
|
51
66
|
return :nanoc if defined?(Nanoc3)
|
52
|
-
|
67
|
+
fail 'simple_navigation currently only works for Rails, Sinatra and ' \
|
68
|
+
'Padrino apps'
|
53
69
|
end
|
54
|
-
|
70
|
+
|
55
71
|
# Loads the adapter for the current framework
|
56
72
|
def load_adapter
|
57
|
-
self.adapter_class =
|
58
|
-
|
59
|
-
SimpleNavigation::Adapters::Rails
|
60
|
-
|
61
|
-
SimpleNavigation::Adapters::
|
62
|
-
|
63
|
-
|
64
|
-
when :nanoc
|
65
|
-
SimpleNavigation::Adapters::Nanoc
|
66
|
-
end
|
73
|
+
self.adapter_class =
|
74
|
+
case framework
|
75
|
+
when :rails then SimpleNavigation::Adapters::Rails
|
76
|
+
when :sinatra then SimpleNavigation::Adapters::Sinatra
|
77
|
+
when :padrino then SimpleNavigation::Adapters::Padrino
|
78
|
+
when :nanoc then SimpleNavigation::Adapters::Nanoc
|
79
|
+
end
|
67
80
|
end
|
68
81
|
|
69
|
-
# Creates a new adapter instance based on the context in which
|
82
|
+
# Creates a new adapter instance based on the context in which
|
83
|
+
# render_navigation has been called.
|
70
84
|
def init_adapter_from(context)
|
71
|
-
self.adapter =
|
85
|
+
self.adapter = adapter_class.new(context)
|
72
86
|
end
|
73
|
-
|
87
|
+
|
74
88
|
def default_config_file_path
|
75
|
-
File.join(
|
89
|
+
File.join(root, 'config')
|
76
90
|
end
|
77
91
|
|
78
92
|
# Returns true if the config_file for specified context does exist.
|
@@ -80,30 +94,47 @@ module SimpleNavigation
|
|
80
94
|
!!config_file(navigation_context)
|
81
95
|
end
|
82
96
|
|
83
|
-
# Returns the path to the config file for the given navigation context or
|
97
|
+
# Returns the path to the config file for the given navigation context or
|
98
|
+
# nil if no matching config file can be found.
|
84
99
|
# If multiple config_paths are set, it returns the first matching path.
|
85
100
|
def config_file(navigation_context = :default)
|
86
|
-
config_file_paths
|
101
|
+
config_file_paths
|
102
|
+
.map { |path| File.join(path, config_file_name(navigation_context)) }
|
103
|
+
.find { |full_path| File.exist?(full_path) }
|
87
104
|
end
|
88
105
|
|
89
106
|
# Returns the name of the config file for the given navigation_context
|
90
107
|
def config_file_name(navigation_context = :default)
|
91
|
-
prefix = navigation_context == :default
|
92
|
-
|
108
|
+
prefix = if navigation_context == :default
|
109
|
+
''
|
110
|
+
else
|
111
|
+
"#{navigation_context.to_s.underscore}_"
|
112
|
+
end
|
113
|
+
"#{prefix}navigation.rb"
|
93
114
|
end
|
94
|
-
|
115
|
+
|
95
116
|
# Resets the list of config_file_paths to the specified path
|
96
117
|
def config_file_path=(path)
|
97
118
|
self.config_file_paths = [path]
|
98
119
|
end
|
99
120
|
|
100
|
-
# Reads the config_file for the specified navigation_context and stores it
|
121
|
+
# Reads the config_file for the specified navigation_context and stores it
|
122
|
+
# for later evaluation.
|
101
123
|
def load_config(navigation_context = :default)
|
102
|
-
|
103
|
-
|
104
|
-
|
124
|
+
unless config_file?(navigation_context)
|
125
|
+
fail "Config file '#{config_file_name(navigation_context)}' not " \
|
126
|
+
"found in path(s) #{config_file_paths.join(', ')}!"
|
127
|
+
end
|
128
|
+
|
129
|
+
# FIXME: what about update_config and update_config! methods ?
|
130
|
+
if environment == 'production'
|
131
|
+
config_files[navigation_context] ||= begin
|
132
|
+
IO.read(config_file(navigation_context))
|
133
|
+
end
|
105
134
|
else
|
106
|
-
|
135
|
+
config_files[navigation_context] = begin
|
136
|
+
IO.read(config_file(navigation_context))
|
137
|
+
end
|
107
138
|
end
|
108
139
|
end
|
109
140
|
|
@@ -112,57 +143,54 @@ module SimpleNavigation
|
|
112
143
|
SimpleNavigation::Configuration.instance
|
113
144
|
end
|
114
145
|
|
115
|
-
# Returns the ItemContainer that contains the items for the
|
146
|
+
# Returns the ItemContainer that contains the items for the
|
147
|
+
# primary navigation
|
116
148
|
def primary_navigation
|
117
149
|
config.primary_navigation
|
118
150
|
end
|
119
151
|
|
120
|
-
# Returns the active item container for the specified level.
|
152
|
+
# Returns the active item container for the specified level.
|
153
|
+
# Valid levels are
|
121
154
|
# * :all - in this case the primary_navigation is returned.
|
122
155
|
# * :leaves - the 'deepest' active item_container will be returned
|
123
|
-
# * a specific level - the active item_container for the specified level
|
124
|
-
#
|
156
|
+
# * a specific level - the active item_container for the specified level
|
157
|
+
# will be returned
|
158
|
+
# * a range of levels - the active item_container for the range's minimum
|
159
|
+
# will be returned
|
125
160
|
#
|
126
161
|
# Returns nil if there is no active item_container for the specified level.
|
127
162
|
def active_item_container_for(level)
|
128
163
|
case level
|
129
|
-
when :all
|
130
|
-
|
131
|
-
when
|
132
|
-
|
133
|
-
when Integer
|
134
|
-
self.primary_navigation.active_item_container_for(level)
|
135
|
-
when Range
|
136
|
-
self.primary_navigation.active_item_container_for(level.min)
|
164
|
+
when :all then primary_navigation
|
165
|
+
when :leaves then primary_navigation.active_leaf_container
|
166
|
+
when Integer then primary_navigation.active_item_container_for(level)
|
167
|
+
when Range then primary_navigation.active_item_container_for(level.min)
|
137
168
|
else
|
138
|
-
|
169
|
+
fail ArgumentError, "Invalid navigation level: #{level}"
|
139
170
|
end
|
140
171
|
end
|
141
|
-
|
172
|
+
|
142
173
|
# Registers a renderer.
|
143
174
|
#
|
144
175
|
# === Example
|
145
176
|
# To register your own renderer:
|
146
177
|
#
|
147
|
-
# SimpleNavigation.register_renderer :
|
178
|
+
# SimpleNavigation.register_renderer my_renderer: My::RendererClass
|
148
179
|
#
|
149
180
|
# Then in the view you can call:
|
150
181
|
#
|
151
|
-
# render_navigation(:
|
182
|
+
# render_navigation(renderer: :my_renderer)
|
152
183
|
def register_renderer(renderer_hash)
|
153
|
-
|
184
|
+
registered_renderers.merge!(renderer_hash)
|
154
185
|
end
|
155
|
-
|
186
|
+
|
156
187
|
private
|
157
|
-
|
188
|
+
|
158
189
|
def apply_defaults(options)
|
159
190
|
options[:level] = options.delete(:levels) if options[:levels]
|
160
|
-
{:
|
191
|
+
{ context: :default, level: :all }.merge(options)
|
161
192
|
end
|
162
|
-
|
163
|
-
|
164
193
|
end
|
165
|
-
|
166
194
|
end
|
167
195
|
|
168
196
|
SimpleNavigation.load_adapter
|
@@ -1,37 +1,37 @@
|
|
1
1
|
module SimpleNavigation
|
2
2
|
module Adapters
|
3
|
-
|
4
|
-
# This
|
3
|
+
# This is the base class for all adapters.
|
4
|
+
# This class mainly exists for documenting reasons.
|
5
5
|
# It lists all the methods that an adapter should implement.
|
6
6
|
#
|
7
7
|
class Base
|
8
8
|
attr_reader :context, :request
|
9
|
-
|
10
|
-
# This method is usually called when the framework is initialized.
|
11
|
-
# It should call SimpleNavigation.set_env and install
|
9
|
+
|
10
|
+
# This method is usually called when the framework is initialized.
|
11
|
+
# It should call SimpleNavigation.set_env and install
|
12
|
+
# SimpleNavigation::Helpers where appropriate.
|
12
13
|
def self.register; end
|
13
|
-
|
14
|
+
|
14
15
|
# Returns the full path incl. query params
|
15
16
|
def request_uri; end
|
16
|
-
|
17
|
+
|
17
18
|
# Returns the path without query params
|
18
19
|
def request_path; end
|
19
|
-
|
20
|
+
|
20
21
|
# Returns the context in which the config files will be evaluated
|
21
22
|
def context_for_eval; end
|
22
|
-
|
23
|
-
# Returns true if the current request's url matches the specified url.
|
23
|
+
|
24
|
+
# Returns true if the current request's url matches the specified url.
|
24
25
|
# Used to determine if an item should be autohighlighted.
|
25
26
|
def current_page?(url); end
|
26
|
-
|
27
|
+
|
27
28
|
# Returns a link with the specified name, url and options.
|
28
29
|
# Used for rendering.
|
29
|
-
def link_to(name, url, options={}); end
|
30
|
-
|
30
|
+
def link_to(name, url, options = {}); end
|
31
|
+
|
31
32
|
# Returns a tag of the specified type, content and options.
|
32
33
|
# Used for rendering.
|
33
|
-
def content_tag(type, content, options={}); end
|
34
|
-
|
34
|
+
def content_tag(type, content, options = {}); end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
@@ -16,29 +16,30 @@ module SimpleNavigation
|
|
16
16
|
def context_for_eval
|
17
17
|
context
|
18
18
|
end
|
19
|
-
|
20
|
-
# Returns true if the current request's url matches the specified url.
|
19
|
+
|
20
|
+
# Returns true if the current request's url matches the specified url.
|
21
21
|
# Used to determine if an item should be autohighlighted.
|
22
22
|
def current_page?(url)
|
23
23
|
path = context.item.path
|
24
24
|
path && path.chop == url
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Returns a link with the specified name, url and options.
|
28
28
|
# Used for rendering.
|
29
|
-
def link_to(name, url, options={})
|
29
|
+
def link_to(name, url, options = {})
|
30
30
|
"<a href='#{url}' #{to_attributes(options)}>#{name}</a>"
|
31
31
|
end
|
32
32
|
|
33
33
|
# Returns a tag of the specified type, content and options.
|
34
34
|
# Used for rendering.
|
35
|
-
def content_tag(type, content, options={})
|
35
|
+
def content_tag(type, content, options = {})
|
36
36
|
"<#{type} #{to_attributes(options)}>#{content}</#{type}>"
|
37
37
|
end
|
38
38
|
|
39
39
|
private
|
40
|
+
|
40
41
|
def to_attributes(options)
|
41
|
-
options.map {|k, v| v.nil? ? nil : "#{k}='#{v}'"}.compact.join(' ')
|
42
|
+
options.map { |k, v| v.nil? ? nil : "#{k}='#{v}'" }.compact.join(' ')
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|