semantic_navigation 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/Changelog.md +7 -0
- data/README.md +25 -8
- data/Rakefile +2 -0
- data/gemfiles/rails3 +7 -0
- data/lib/generators/semantic_navigation/install/templates/semantic_navigation.rb +6 -2
- data/lib/semantic_navigation/configuration.rb +5 -0
- data/lib/semantic_navigation/core/base.rb +2 -2
- data/lib/semantic_navigation/core/leaf.rb +28 -10
- data/lib/semantic_navigation/core/navigation.rb +11 -4
- data/lib/semantic_navigation/core/node.rb +24 -12
- data/lib/semantic_navigation/helper_methods.rb +3 -1
- data/lib/semantic_navigation/renderers/bread_crumb.rb +3 -3
- data/lib/semantic_navigation/renderers/list.rb +2 -2
- data/lib/semantic_navigation/renderers/render_helpers.rb +6 -2
- data/lib/semantic_navigation/twitter_bootstrap/breadcrumb.rb +4 -4
- data/lib/semantic_navigation/twitter_bootstrap/list.rb +6 -6
- data/lib/semantic_navigation/twitter_bootstrap/tabs.rb +3 -3
- data/lib/semantic_navigation/version.rb +1 -1
- data/spec/lib/semantic_navigation/configuration_spec.rb +153 -0
- data/spec/lib/semantic_navigation/core/leaf_spec.rb +50 -0
- data/spec/lib/semantic_navigation/core/navigation_spec.rb +35 -0
- data/spec/lib/semantic_navigation/core/node_spec.rb +25 -0
- data/spec/lib/semantic_navigation/helper_methods_spec.rb +82 -0
- data/spec/lib/semantic_navigation/renderers/bread_crumb_spec.rb +203 -0
- data/spec/lib/semantic_navigation/renderers/list_spec.rb +241 -0
- data/spec/lib/semantic_navigation/twitter_bootstrap/breadcrumb_spec.rb +202 -0
- data/spec/lib/semantic_navigation/twitter_bootstrap/list_spec.rb +316 -0
- data/spec/lib/semantic_navigation/twitter_bootstrap/tabs_spec.rb +310 -0
- data/spec/spec_helper.rb +1 -0
- metadata +15 -9
- data/spec/lib/semantic_navigation/core/base_spec.rb +0 -1
data/.travis.yml
ADDED
data/Changelog.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
### 0.0.14
|
2
|
+
* Now in render_if proc there is possibility to catch self(rendering element)
|
3
|
+
* Items accept procs for links definitions
|
4
|
+
* Fixed bug in active_item_for method
|
5
|
+
* active_item_for now returns empty string instead of nil then no active items
|
6
|
+
* added multiname support for items
|
7
|
+
|
1
8
|
### 0.0.13 / August 14, 2012
|
2
9
|
|
3
10
|
* Bugfixes for support array of route like links
|
data/README.md
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
This is semantic_navigation gem
|
2
2
|
|
3
3
|
###Purpose
|
4
|
-
This gem
|
5
|
-
|
6
|
-
Using this gem you have 4 types of renderers: menu, breadcrumb, tabs, and, pills
|
4
|
+
Forget fat layouts, views and controllers. This gem will do all the menu staff for you.
|
5
|
+
You simply just have to generate configuration file, fill it with your menu hierarchy and renderer it wherever you want.
|
7
6
|
|
8
|
-
|
7
|
+
Symply and customizable it will make for you all the routings you were spending a lot of time before.
|
9
8
|
|
10
|
-
|
9
|
+
* semantic_navigation supports defining as many separate menus as you want and they can be as deep as you need.
|
10
|
+
* supports different styles of url definitions ('route#like', :symbols, 'strings', {hash: 'like'})
|
11
|
+
* supports and array of urls for one item
|
12
|
+
* supports procs for item name definitions - so you can have dynamic names
|
13
|
+
* supports render conditions defined as proc where you have access to controller class variables, request params and even to the rendering item
|
14
|
+
* supports multiname definitions where you can set the custom name for each renderer.
|
15
|
+
* has renderers compatible with bootstrap - so if you using bootstrap it will be simplier
|
16
|
+
* supports controller default styles overriding both - from configuration and view file
|
17
|
+
* supports custom renderers
|
11
18
|
|
12
19
|
###How to install
|
13
20
|
|
@@ -33,9 +40,9 @@ Configure your navigation in config/semantic_navigation.rb
|
|
33
40
|
<pre><code>
|
34
41
|
SemanticNavigation::Configuration.run do
|
35
42
|
navigate :root_menu do
|
36
|
-
|
43
|
+
header :header_item, :name => 'Header'
|
37
44
|
item :first_item, '#', :name => 'First Item', :ico => :tag
|
38
|
-
|
45
|
+
divider
|
39
46
|
item :second_item, '#', :name => 'Second Item', :ico => :user
|
40
47
|
end
|
41
48
|
end
|
@@ -46,7 +53,17 @@ And try to render it in your layout(code in haml):
|
|
46
53
|
.well
|
47
54
|
= navigation_for :root_menu, :as => :bootstrap_list
|
48
55
|
</code></pre>
|
56
|
+
or
|
57
|
+
<pre><code>
|
58
|
+
.well
|
59
|
+
= bootstrap_list_for :root_menu
|
60
|
+
</code></pre>
|
49
61
|
|
50
62
|
Render the navigation using the semantic_navigation helper methods and options for them.
|
51
63
|
|
52
|
-
For the information of how to configure and render your navigation read the <a href='https://github.com/fr33z3/semantic_navigation/wiki'>Wiki</a>
|
64
|
+
For the information of how to configure and render your navigation read the <a href='https://github.com/fr33z3/semantic_navigation/wiki'>Wiki</a>
|
65
|
+
|
66
|
+
Dependence:
|
67
|
+
|
68
|
+
* Ruby >= 1.9.2
|
69
|
+
* Rails >= 3.0.0
|
data/Rakefile
CHANGED
data/gemfiles/rails3
ADDED
@@ -1,23 +1,27 @@
|
|
1
|
+
#encoding: utf-8
|
1
2
|
SemanticNavigation::Configuration.run do
|
2
3
|
# Read wiki https://github.com/fr33z3/semantic_navigation/wiki to lear about
|
3
4
|
# semantic_navigation configuration
|
4
5
|
|
6
|
+
#Override renderer default styles:
|
5
7
|
#styles_for :list do
|
6
8
|
# show_navigation_active_class true
|
7
9
|
# navigation_active_class [:some_active_class]
|
8
10
|
#end
|
9
11
|
|
12
|
+
# You can register your custom renderer:
|
10
13
|
#register_renderer :some_renderer, SomeRendererClass
|
11
14
|
|
15
|
+
# The example of the navigation:
|
12
16
|
#navigate :navigation do
|
13
|
-
#
|
17
|
+
# header :header_item, :name => 'Header Item'
|
14
18
|
# item :first_item, :first_item_route, :ico => 'user' do
|
15
19
|
# item :sub_item, :sub_item_route do
|
16
20
|
# item :sub_sub_item, :sub_sub_item_route
|
17
21
|
# end
|
18
22
|
# item :second_sub, :second_sub_route, :ico => 'user'
|
19
23
|
# end
|
20
|
-
#
|
24
|
+
# divider
|
21
25
|
# item :second_item, :second_item_route
|
22
26
|
#end
|
23
27
|
|
@@ -25,6 +25,7 @@ module SemanticNavigation
|
|
25
25
|
renderer.instance_eval &@@render_styles[renderer_name]
|
26
26
|
end
|
27
27
|
options.keys.each{|key| renderer.send "#{key}=", options[key]}
|
28
|
+
renderer.name = renderer_name
|
28
29
|
navigation = @@navigations[menu_id]
|
29
30
|
navigation.mark_active
|
30
31
|
navigation.render(renderer)
|
@@ -54,6 +55,10 @@ module SemanticNavigation
|
|
54
55
|
def self.view_object
|
55
56
|
@@view_object
|
56
57
|
end
|
58
|
+
|
59
|
+
def self.view_object=(view_object)
|
60
|
+
@@view_object = view_object
|
61
|
+
end
|
57
62
|
|
58
63
|
def self.navigation(name)
|
59
64
|
@@navigations[name]
|
@@ -2,11 +2,11 @@ module SemanticNavigation
|
|
2
2
|
module Core
|
3
3
|
class Base
|
4
4
|
|
5
|
-
|
5
|
+
attr_accessor :id, :level, :classes, :active
|
6
6
|
attr_writer :render_if
|
7
7
|
|
8
8
|
def render_if
|
9
|
-
!@render_if.nil? ? view_object.
|
9
|
+
!@render_if.nil? ? view_object.instance_exec(self, &@render_if) : true
|
10
10
|
end
|
11
11
|
|
12
12
|
def initialize(options, level)
|
@@ -1,32 +1,50 @@
|
|
1
1
|
module SemanticNavigation
|
2
2
|
module Core
|
3
3
|
class Leaf < Base
|
4
|
-
|
4
|
+
attr_accessor :link_classes
|
5
5
|
|
6
6
|
def url
|
7
|
-
|
7
|
+
urls.first
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(options, level)
|
11
11
|
super options, level
|
12
12
|
end
|
13
13
|
|
14
|
-
def name
|
15
|
-
rendering_name = @name
|
16
|
-
if rendering_name.is_a?(
|
17
|
-
|
18
|
-
|
19
|
-
rendering_name
|
20
|
-
end
|
14
|
+
def name(renderer_name = nil)
|
15
|
+
rendering_name = @name
|
16
|
+
rendering_name = rendering_name[renderer_name.to_sym] || rendering_name[:default] if rendering_name.is_a?(Hash)
|
17
|
+
rendering_name = view_object.instance_eval(&rendering_name).to_s if rendering_name.is_a?(Proc)
|
18
|
+
rendering_name || i18n_name(renderer_name)
|
21
19
|
end
|
22
20
|
|
23
21
|
def mark_active
|
24
22
|
if @url
|
25
|
-
@active =
|
23
|
+
@active = urls.map{|u| current_page?(u) rescue false}.reduce(:"|")
|
26
24
|
else
|
27
25
|
@active = false
|
28
26
|
end
|
29
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def i18n_name(renderer_name = nil)
|
32
|
+
name = I18n.t("#{@i18n_name}.#{@id}", :default => '')
|
33
|
+
if name.is_a? Hash
|
34
|
+
name = name[renderer_name.to_sym] || name[:default]
|
35
|
+
end
|
36
|
+
name || ''
|
37
|
+
end
|
38
|
+
|
39
|
+
def urls
|
40
|
+
[@url].flatten(1).map do |url|
|
41
|
+
if url.is_a?(Proc)
|
42
|
+
view_object.instance_eval(&url) rescue ''
|
43
|
+
else
|
44
|
+
url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
30
48
|
|
31
49
|
end
|
32
50
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module SemanticNavigation
|
2
2
|
module Core
|
3
3
|
class Navigation < Base
|
4
|
-
|
4
|
+
attr_accessor :sub_elements
|
5
5
|
|
6
6
|
def initialize(options, level = 0)
|
7
7
|
@sub_elements = []
|
@@ -24,6 +24,13 @@ module SemanticNavigation
|
|
24
24
|
element.instance_eval &block
|
25
25
|
else
|
26
26
|
element = Leaf.new(options, @level+1)
|
27
|
+
#Deprecation warning message
|
28
|
+
#TODO:Should be deleted after moving the header and divider definition via item
|
29
|
+
if element.url.nil? && !element.name.empty?
|
30
|
+
puts 'Warning: do not define `headers` using `item` method. Use `header` instead. This logic will be deprecated soon.'
|
31
|
+
elsif element.url.nil? && element.name.empty?
|
32
|
+
puts 'Warning: do not define `dividers` using `item` method. Use `divider` instead. This logic will be deprecated soon.'
|
33
|
+
end
|
27
34
|
end
|
28
35
|
|
29
36
|
@sub_elements.push element
|
@@ -64,10 +71,10 @@ module SemanticNavigation
|
|
64
71
|
if url.is_a? String
|
65
72
|
controller_name, action_name = url.split('#')
|
66
73
|
if controller_name && action_name
|
67
|
-
|
68
|
-
end
|
74
|
+
decoded_url = {:controller => controller_name, :action => action_name}
|
75
|
+
end
|
69
76
|
end
|
70
|
-
url
|
77
|
+
decoded_url || url
|
71
78
|
end
|
72
79
|
|
73
80
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module SemanticNavigation
|
2
2
|
module Core
|
3
3
|
class Node < Navigation
|
4
|
-
|
4
|
+
attr_accessor :link_classes, :node_classes
|
5
5
|
|
6
6
|
def url
|
7
|
-
|
7
|
+
urls.first
|
8
8
|
end
|
9
9
|
|
10
10
|
def initialize(options, level)
|
@@ -12,25 +12,37 @@ module SemanticNavigation
|
|
12
12
|
super options, level
|
13
13
|
end
|
14
14
|
|
15
|
-
def name
|
16
|
-
rendering_name = @name
|
17
|
-
if rendering_name.is_a?(
|
18
|
-
|
19
|
-
|
20
|
-
rendering_name
|
21
|
-
end
|
15
|
+
def name(renderer_name = nil)
|
16
|
+
rendering_name = @name
|
17
|
+
rendering_name = rendering_name[renderer_name.to_sym] || rendering_name[:default] if rendering_name.is_a?(Hash)
|
18
|
+
rendering_name = view_object.instance_eval(&rendering_name).to_s if rendering_name.is_a?(Proc)
|
19
|
+
rendering_name || i18n_name(renderer_name)
|
22
20
|
end
|
23
21
|
|
24
22
|
def mark_active
|
25
23
|
@sub_elements.each{|element| element.mark_active}
|
26
|
-
@active =
|
24
|
+
@active = urls.map{|u| current_page?(u) rescue false}.reduce(:"|")
|
27
25
|
@active |= !@sub_elements.find{|element| element.active}.nil?
|
28
26
|
end
|
29
27
|
|
30
28
|
private
|
31
29
|
|
32
|
-
def i18n_name
|
33
|
-
I18n.t("#{@i18n_name}.#{@id}", :default => '')
|
30
|
+
def i18n_name(renderer_name = nil)
|
31
|
+
name = I18n.t("#{@i18n_name}.#{@id}", :default => '')
|
32
|
+
if name.is_a? Hash
|
33
|
+
name = name[renderer_name.to_sym] || name[:default]
|
34
|
+
end
|
35
|
+
name || ''
|
36
|
+
end
|
37
|
+
|
38
|
+
def urls
|
39
|
+
[@url].flatten(1).map do |url|
|
40
|
+
if url.is_a?(Proc)
|
41
|
+
view_object.instance_eval(&url) rescue ''
|
42
|
+
else
|
43
|
+
url
|
44
|
+
end
|
45
|
+
end
|
34
46
|
end
|
35
47
|
|
36
48
|
end
|
@@ -7,13 +7,15 @@ module SemanticNavigation::HelperMethods
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def active_item_for(name, level = nil)
|
10
|
+
SemanticNavigation::Configuration.view_object = self
|
10
11
|
navigation = SemanticNavigation::Configuration.navigation(name)
|
12
|
+
navigation.mark_active
|
11
13
|
item = navigation
|
12
14
|
while !item.is_a?(SemanticNavigation::Core::Leaf) &&
|
13
15
|
!item.sub_elements.find{|e| e.active}.nil? &&
|
14
16
|
(!level.nil? ? item.level < level : true)
|
15
17
|
item = item.sub_elements.find{|e| e.active}
|
16
18
|
end
|
17
|
-
item
|
19
|
+
item != navigation ? item.name(:active_item_for) : ''
|
18
20
|
end
|
19
21
|
end
|
@@ -25,7 +25,7 @@ module SemanticNavigation
|
|
25
25
|
def node(object)
|
26
26
|
content_tag(:li, nil, :id => show_id(:leaf, object.id),
|
27
27
|
:class => merge_classes(:leaf, object.active, object.classes)) do
|
28
|
-
link_to(object
|
28
|
+
link_to(object_name(object), object.url, :id => show_id(:link, object.id),
|
29
29
|
:class => merge_classes(:link, object.active, object.link_classes))
|
30
30
|
end +
|
31
31
|
content_tag(:li) do
|
@@ -38,10 +38,10 @@ module SemanticNavigation
|
|
38
38
|
content_tag :li, nil, :id => show_id(:leaf, object.id),
|
39
39
|
:class => merge_classes(:leaf, object.active, object.classes) do
|
40
40
|
if last_as_link
|
41
|
-
link_to object
|
41
|
+
link_to object_name(object), object.url, :id => show_id(:link, object.id),
|
42
42
|
:class => merge_classes(:link, object.active, object.link_classes)
|
43
43
|
else
|
44
|
-
object
|
44
|
+
object_name(object)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -18,7 +18,7 @@ module SemanticNavigation
|
|
18
18
|
def node(object)
|
19
19
|
content_tag :li, nil, :id => show_id(:leaf, object.id),
|
20
20
|
:class => merge_classes(:leaf, object.active, object.classes) do
|
21
|
-
link_to(object
|
21
|
+
link_to(object_name(object), object.url, :id => show_id(:link, object.id),
|
22
22
|
:class => merge_classes(:link, object.active, object.link_classes))+
|
23
23
|
yield
|
24
24
|
end
|
@@ -34,7 +34,7 @@ module SemanticNavigation
|
|
34
34
|
def leaf(object)
|
35
35
|
content_tag :li, nil, :id => show_id(:leaf, object.id),
|
36
36
|
:class => merge_classes(:leaf, object.active, object.classes) do
|
37
|
-
link_to object
|
37
|
+
link_to object_name(object), object.url, :id => show_id(:link, object.id),
|
38
38
|
:class => merge_classes(:link, object.active, object.link_classes)
|
39
39
|
end
|
40
40
|
end
|
@@ -29,7 +29,7 @@ module SemanticNavigation
|
|
29
29
|
end
|
30
30
|
|
31
31
|
module ClassMethods
|
32
|
-
|
32
|
+
|
33
33
|
def style_accessor(hash)
|
34
34
|
hash.keys.each do |key|
|
35
35
|
class_eval "
|
@@ -66,7 +66,7 @@ module SemanticNavigation
|
|
66
66
|
end
|
67
67
|
|
68
68
|
module InstanceMethods
|
69
|
-
attr_accessor :from_level, :until_level, :except_for
|
69
|
+
attr_accessor :from_level, :until_level, :except_for, :name
|
70
70
|
|
71
71
|
def level=(level)
|
72
72
|
@from_level = level
|
@@ -103,6 +103,10 @@ module SemanticNavigation
|
|
103
103
|
def show_id(name, id)
|
104
104
|
id if send("show_#{name}_id")
|
105
105
|
end
|
106
|
+
|
107
|
+
def object_name(object)
|
108
|
+
object.name(self.name)
|
109
|
+
end
|
106
110
|
|
107
111
|
end
|
108
112
|
|
@@ -33,7 +33,7 @@ module SemanticNavigation
|
|
33
33
|
content_tag(:li, nil, :id => show_id(:leaf, object.id),
|
34
34
|
:class => merge_classes(:leaf, object.active, object.classes)) do
|
35
35
|
[object.ico ? content_tag(:i,nil,:class => "icon-#{object.ico}") : ''.html_safe,
|
36
|
-
link_to(object
|
36
|
+
link_to(object_name(object), object.url, :id => show_id(:link, object.id),
|
37
37
|
:class => merge_classes(:link, object.active, object.link_classes)),
|
38
38
|
content_tag(:span, nil, :class=> [:divider]) {breadcrumb_separator}].sum
|
39
39
|
end +
|
@@ -45,10 +45,10 @@ module SemanticNavigation
|
|
45
45
|
:class => merge_classes(:leaf, object.active, object.classes) do
|
46
46
|
[object.ico ? content_tag(:i,nil,:class => "icon-#{object.ico}") : ''.html_safe,
|
47
47
|
if last_as_link
|
48
|
-
link_to(object
|
49
|
-
|
48
|
+
link_to(object_name(object), object.url, :id => show_id(:link, object.id),
|
49
|
+
:class => merge_classes(:link, object.active, object.link_classes))
|
50
50
|
else
|
51
|
-
object
|
51
|
+
object_name(object)
|
52
52
|
end].sum
|
53
53
|
end
|
54
54
|
end
|
@@ -24,9 +24,9 @@ module SemanticNavigation
|
|
24
24
|
def node(object)
|
25
25
|
if object.ico
|
26
26
|
name = [content_tag(:i,nil,:class => "icon-#{object.ico}"),
|
27
|
-
object
|
27
|
+
object_name(object)].sum
|
28
28
|
else
|
29
|
-
name = object
|
29
|
+
name = object_name(object)
|
30
30
|
end
|
31
31
|
|
32
32
|
content_tag :li, nil, :id => show_id(:leaf, object.id),
|
@@ -45,7 +45,7 @@ module SemanticNavigation
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def leaf(object)
|
48
|
-
if object.
|
48
|
+
if object_name(object).empty? && object.url.nil?
|
49
49
|
classes = 'divider'
|
50
50
|
elsif object.url.nil?
|
51
51
|
classes = 'nav-header'
|
@@ -55,9 +55,9 @@ module SemanticNavigation
|
|
55
55
|
|
56
56
|
if object.ico
|
57
57
|
name = [content_tag(:i,nil,:class => "icon-#{object.ico}"),
|
58
|
-
object
|
58
|
+
object_name(object)].sum
|
59
59
|
else
|
60
|
-
name = object
|
60
|
+
name = object_name(object)
|
61
61
|
end
|
62
62
|
|
63
63
|
content_tag :li, nil, :id => show_id(:leaf, object.id),
|
@@ -66,7 +66,7 @@ module SemanticNavigation
|
|
66
66
|
name
|
67
67
|
else
|
68
68
|
link_to name, object.url, :id => show_id(:link, object.id),
|
69
|
-
|
69
|
+
:class => merge_classes(:link, object.active, object.link_classes)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|