simple-navigation 3.12.0 → 3.12.1
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/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
|