smart_navigation 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +65 -2
- data/lib/smart_navigation/renderer.rb +134 -82
- data/lib/smart_navigation/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 032655f9ab35419c26f5b36b2ebb58bc044cee25
|
4
|
+
data.tar.gz: 54e5513ff6c6954ce05e6e25bdd205279b421a40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2413436e93175f1ca0eb2771740962d755a5f50d6775db282176b01fa6eced57d5a1aa8e6eee7504ba9b562f0847e852c0cc2b964d13463b9610e627b5c920b9
|
7
|
+
data.tar.gz: b23f3b1a58cd012667d80f1835fba875fd06f6e4bc43680c0a2c532989d1b3fd7cfdf2cd003fc91856481fec869698a6c10e53532748f981df84989c0d73c5bd
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SmartNavigation
|
2
2
|
|
3
|
-
View helpers for navigation menus. Build navigation menus from hash
|
3
|
+
View helpers for navigation menus. Build navigation menus from hash objects.
|
4
4
|
|
5
5
|
[](https://badge.fury.io/rb/smart_navigation)
|
6
6
|
[](https://travis-ci.org/hardpixel/smart-navigation)
|
@@ -24,7 +24,70 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
-
|
27
|
+
Define the menu items in a hash:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
@items = {
|
31
|
+
dashboard: {
|
32
|
+
label: 'Dashboard',
|
33
|
+
url: :root_path,
|
34
|
+
icon: 'dashboard'
|
35
|
+
},
|
36
|
+
pages: {
|
37
|
+
label: 'Pages',
|
38
|
+
url: :admin_pages_path,
|
39
|
+
icon: 'pages',
|
40
|
+
children: {
|
41
|
+
index: {
|
42
|
+
label: 'All Pages',
|
43
|
+
url: :pages_path
|
44
|
+
},
|
45
|
+
new: {
|
46
|
+
label: 'New Page',
|
47
|
+
url: :new_page_path
|
48
|
+
}
|
49
|
+
}
|
50
|
+
},
|
51
|
+
system: {
|
52
|
+
label: 'System',
|
53
|
+
separator: true
|
54
|
+
},
|
55
|
+
profile: {
|
56
|
+
label: 'Profile',
|
57
|
+
url: -> { edit_user_path(current_user) },
|
58
|
+
icon: 'user',
|
59
|
+
if: :user_signed_in?
|
60
|
+
}
|
61
|
+
}
|
62
|
+
```
|
63
|
+
|
64
|
+
The `url` key can be a String, a Symbol or a Proc. Keys `if` and `unless` can be a Symbol or a Proc. Symbols and Procs are executed in the view context.
|
65
|
+
|
66
|
+
To render a menu you can use the `navigation_for` or `smart_navigation_for` helper in your views:
|
67
|
+
|
68
|
+
```erb
|
69
|
+
<%= smart_navigation_for(@items) %>
|
70
|
+
```
|
71
|
+
|
72
|
+
There are a number of options you can use to customize the navigation. The default options are:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
options = {
|
76
|
+
menu_class: 'menu',
|
77
|
+
menu_html: {},
|
78
|
+
separator_class: 'separator',
|
79
|
+
submenu_parent_class: 'has-submenu',
|
80
|
+
submenu_class: 'submenu',
|
81
|
+
active_class: 'active',
|
82
|
+
active_submenu_class: 'open',
|
83
|
+
submenu_icons: false,
|
84
|
+
submenu_toggle: nil,
|
85
|
+
icon_prefix: 'icon icon-',
|
86
|
+
icon_position: 'left'
|
87
|
+
}
|
88
|
+
|
89
|
+
smart_navigation_for(@items, options)
|
90
|
+
```
|
28
91
|
|
29
92
|
## Development
|
30
93
|
|
@@ -2,107 +2,159 @@ module SmartNavigation
|
|
2
2
|
class Renderer
|
3
3
|
# Initialize builder
|
4
4
|
def initialize(view_context, items, options={})
|
5
|
-
@context
|
6
|
-
@items
|
7
|
-
@
|
8
|
-
@sep_class = options.fetch :separator_class, 'separator'
|
9
|
-
@group_class = options.fetch :group_class, 'menu-group'
|
10
|
-
@submenu_class = options.fetch :submenu_class, 'submenu'
|
11
|
-
@active_class = options.fetch :active_class, 'active'
|
12
|
-
@active_submenu_class = options.fetch :active_submenu_class, 'open'
|
13
|
-
@submenu_icons = options.fetch :submenu_icons, false
|
5
|
+
@context = view_context
|
6
|
+
@items = sort_items items
|
7
|
+
@options = default_options.merge(options)
|
14
8
|
end
|
15
9
|
|
16
|
-
#
|
17
|
-
def
|
18
|
-
items.
|
10
|
+
# Render menu
|
11
|
+
def render
|
12
|
+
menu_tag @items.map { |k, v| item_tag(v, true) }.join
|
19
13
|
end
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
15
|
+
private
|
16
|
+
|
17
|
+
# Default options
|
18
|
+
def default_options
|
19
|
+
{
|
20
|
+
menu_class: 'menu',
|
21
|
+
menu_html: {},
|
22
|
+
separator_class: 'separator',
|
23
|
+
submenu_parent_class: 'has-submenu',
|
24
|
+
submenu_class: 'submenu',
|
25
|
+
active_class: 'active',
|
26
|
+
active_submenu_class: 'open',
|
27
|
+
submenu_icons: false,
|
28
|
+
submenu_toggle: nil,
|
29
|
+
icon_prefix: 'icon icon-',
|
30
|
+
icon_position: 'left'
|
31
|
+
}
|
32
|
+
end
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
34
|
+
# Sort items by order
|
35
|
+
def sort_items(items)
|
36
|
+
items.sort_by { |_k, v| v[:order] }.to_h
|
37
|
+
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
current
|
38
|
-
end
|
39
|
+
# Get menu item url
|
40
|
+
def item_url(item)
|
41
|
+
item[:url].present? ? mixed_value(item[:url]) : "##{item[:id]}"
|
42
|
+
end
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
# Check if should render item
|
45
|
+
def render_item?(item)
|
46
|
+
if item[:if]
|
47
|
+
mixed_value(item[:if]).present?
|
48
|
+
elsif item[:unless]
|
49
|
+
mixed_value(item[:unless]).blank?
|
50
|
+
else
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
44
54
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
label = label + arrow if item[:children].present?
|
55
|
+
# Check if current page
|
56
|
+
def current_page?(item)
|
57
|
+
url = item_url(item)
|
58
|
+
@context.current_page?(url)
|
59
|
+
end
|
51
60
|
|
52
|
-
|
53
|
-
|
61
|
+
# Check if current group
|
62
|
+
def current_group?(item)
|
63
|
+
current = true if current_page?(item)
|
64
|
+
current = Hash(item[:children]).any? { |_k, v| current_page?(v) } if current.blank?
|
65
|
+
current = Hash(item[:children]).any? { |_k, v| current_group?(v) } if current.blank?
|
66
|
+
current
|
67
|
+
end
|
68
|
+
|
69
|
+
# Create html tag
|
70
|
+
def tag(*args, &block)
|
71
|
+
@context.content_tag(*args, &block)
|
72
|
+
end
|
54
73
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
items = items.map { |_k, v| item_tag(v, @submenu_icons) }.join
|
59
|
-
active = @active_submenu_class if active.present?
|
74
|
+
# Create menu icon
|
75
|
+
def icon_tag(name, label=nil)
|
76
|
+
icon = tag :i, nil, class: "#{@options[:icon_prefix]}#{name}"
|
60
77
|
|
61
|
-
|
62
|
-
|
78
|
+
if @options[:icon_position] == 'left'
|
79
|
+
"#{icon}#{label}".html_safe
|
80
|
+
else
|
81
|
+
"#{label}#{icon}".html_safe
|
82
|
+
end
|
83
|
+
end
|
63
84
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
submenu = submenu_item_tag item, active
|
69
|
-
content = link + submenu
|
85
|
+
# Create submenu toggle tag
|
86
|
+
def toggle_tag
|
87
|
+
"#{@options[:submenu_toggle]}".html_safe
|
88
|
+
end
|
70
89
|
|
71
|
-
|
72
|
-
|
90
|
+
# Create menu separator
|
91
|
+
def separator_tag(item)
|
92
|
+
tag :li, item[:label], class: @options[:separator_class]
|
93
|
+
end
|
73
94
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
95
|
+
# Create item link
|
96
|
+
def item_link_tag(item, icons=false)
|
97
|
+
label = tag :span, item[:label]
|
98
|
+
label = icon_tag("#{item[:icon]}", label) if icons.present?
|
99
|
+
label = label + toggle_tag if item[:children].present?
|
78
100
|
|
79
|
-
|
80
|
-
|
101
|
+
@context.link_to label.html_safe, item_url(item)
|
102
|
+
end
|
81
103
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
single_item_tag(item, icons)
|
104
|
+
# Create submenu item
|
105
|
+
def submenu_item_tag(item, active=false)
|
106
|
+
items = sort_items item[:children]
|
107
|
+
items = items.map { |_k, v| item_tag(v, @options[:submenu_icons]) }.join
|
108
|
+
active = @options[:active_submenu_class] if active.present?
|
109
|
+
|
110
|
+
tag(:ul, items.html_safe, class: "#{active} #{@options[:submenu_class]}".strip)
|
90
111
|
end
|
91
|
-
end
|
92
112
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
113
|
+
# Create group menu item
|
114
|
+
def group_item_tag(item, icons=false)
|
115
|
+
active = @options[:active_class] if current_group?(item)
|
116
|
+
link = item_link_tag item, icons
|
117
|
+
submenu = submenu_item_tag item, active
|
118
|
+
content = link + submenu
|
97
119
|
|
98
|
-
|
99
|
-
|
100
|
-
menu_tag @items.map { |k, v| item_tag(v, true) }.join
|
101
|
-
end
|
120
|
+
tag :li, content.html_safe, class: "#{active} #{@options[:submenu_parent_class]}".strip
|
121
|
+
end
|
102
122
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
123
|
+
# Create single menu item
|
124
|
+
def single_item_tag(item, icons=false)
|
125
|
+
active = @options[:active_class] if current_page?(item)
|
126
|
+
link = item_link_tag(item, icons)
|
127
|
+
|
128
|
+
tag :li, link.html_safe, class: "#{active}"
|
129
|
+
end
|
130
|
+
|
131
|
+
# Create menu list item
|
132
|
+
def item_tag(item, icons=false)
|
133
|
+
if render_item?(item)
|
134
|
+
if item[:separator].present?
|
135
|
+
separator_tag(item)
|
136
|
+
elsif item[:children].present?
|
137
|
+
group_item_tag(item, icons)
|
138
|
+
else
|
139
|
+
single_item_tag(item, icons)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Create menu list
|
145
|
+
def menu_tag(items)
|
146
|
+
tag :ul, items.html_safe, Hash(@options[:menu_html]).merge(class: @options[:menu_class])
|
147
|
+
end
|
148
|
+
|
149
|
+
# Parse mixed value
|
150
|
+
def mixed_value(value)
|
151
|
+
if value.is_a?(Proc)
|
152
|
+
@context.instance_exec(&value)
|
153
|
+
elsif value.is_a?(Symbol)
|
154
|
+
@context.send(value)
|
155
|
+
else
|
156
|
+
value
|
157
|
+
end
|
158
|
+
end
|
107
159
|
end
|
108
160
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_navigation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonian Guveli
|
@@ -72,7 +72,7 @@ dependencies:
|
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '5.0'
|
75
|
-
description: View helpers for navigation menus. Build navigation menus from hash
|
75
|
+
description: View helpers for navigation menus. Build navigation menus from hash objects.
|
76
76
|
email:
|
77
77
|
- jonian@hardpixel.eu
|
78
78
|
executables: []
|