navtastic 0.0.1 → 0.1.0
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/.rubocop.yml +11 -1
- data/.yardopts +1 -0
- data/CHANGELOG.md +11 -1
- data/README.md +146 -6
- data/docs/bulma_headers_preview.png +0 -0
- data/docs/foundation_styles_preview.png +0 -0
- data/lib/navtastic.rb +17 -1
- data/lib/navtastic/configuration.rb +84 -0
- data/lib/navtastic/item.rb +44 -3
- data/lib/navtastic/menu.rb +52 -9
- data/lib/navtastic/renderer.rb +61 -38
- data/lib/navtastic/renderer/bootstrap4.rb +35 -0
- data/lib/navtastic/renderer/bulma.rb +44 -0
- data/lib/navtastic/renderer/foundation6.rb +58 -0
- data/lib/navtastic/renderer/simple.rb +18 -0
- data/lib/navtastic/version.rb +1 -1
- data/spec/demo/index.rhtml +7 -20
- data/spec/demo/renderer/bootstrap4.rhtml +55 -0
- data/spec/demo/renderer/bulma.rhtml +70 -0
- data/spec/demo/renderer/foundation6.rhtml +81 -0
- data/spec/demo/renderer/simple.rhtml +41 -0
- data/spec/demo/server.rb +21 -10
- data/spec/navtastic/configuration_spec.rb +71 -0
- data/spec/navtastic/item_spec.rb +82 -0
- data/spec/navtastic/menu_spec.rb +107 -3
- data/spec/navtastic/renderer/simple_spec.rb +19 -0
- data/spec/navtastic/renderer_spec.rb +49 -7
- data/spec/navtastic_spec.rb +41 -4
- data/spec/spec_helper.rb +2 -1
- data/spec/support/navtastic_helpers.rb +17 -0
- data/spec/support/{navtastic_store.rb → navtastic_reset.rb} +2 -1
- metadata +25 -4
@@ -0,0 +1,55 @@
|
|
1
|
+
<%
|
2
|
+
Navtastic.configure do |config|
|
3
|
+
config.renderer = Navtastic::Renderer::Bootstrap4
|
4
|
+
end
|
5
|
+
|
6
|
+
Navtastic.define :main_menu do |menu|
|
7
|
+
menu.item "General" do |generalmenu|
|
8
|
+
generalmenu.item "Dashboard", '/'
|
9
|
+
generalmenu.item "Customers", '/customers'
|
10
|
+
end
|
11
|
+
|
12
|
+
menu.item "Administration" do |adminmenu|
|
13
|
+
adminmenu.item "Team Settings", '/team'
|
14
|
+
adminmenu.item "Manage Your Team", '/manage' do |teammenu|
|
15
|
+
teammenu.item "Members", '/manage/members/'
|
16
|
+
teammenu.item "Plugins", '/manage/plugins'
|
17
|
+
teammenu.item "Add a member", '/manage/members/new'
|
18
|
+
end
|
19
|
+
adminmenu.item "Invitations", '/invitations'
|
20
|
+
adminmenu.item "Cloud Storage Environment Settings", '/cloud'
|
21
|
+
adminmenu.item "Authentication", '/authentication'
|
22
|
+
end
|
23
|
+
|
24
|
+
menu.item "Other renderers" do |rendermenu|
|
25
|
+
rendermenu.item "Overview", '/', root: true
|
26
|
+
rendermenu.item "Simple", '/simple', root: true
|
27
|
+
rendermenu.item "Bulma", '/bulma', root: true
|
28
|
+
rendermenu.item "Foundation6", '/foundation6', root: true
|
29
|
+
end
|
30
|
+
|
31
|
+
menu.config.base_url = '/bootstrap4'
|
32
|
+
end
|
33
|
+
%>
|
34
|
+
|
35
|
+
<html>
|
36
|
+
<head>
|
37
|
+
<title>Navtastic Bootstrap4 Renderer</title>
|
38
|
+
|
39
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap.min.css">
|
40
|
+
|
41
|
+
<style>
|
42
|
+
a.active {
|
43
|
+
font-weight: bold;
|
44
|
+
}
|
45
|
+
|
46
|
+
ul.nav ul {
|
47
|
+
margin-left: 2rem;
|
48
|
+
}
|
49
|
+
</style>
|
50
|
+
</head>
|
51
|
+
|
52
|
+
<body>
|
53
|
+
<%= Navtastic.render :main_menu, current_url %>
|
54
|
+
</body>
|
55
|
+
</html>
|
@@ -0,0 +1,70 @@
|
|
1
|
+
<%
|
2
|
+
Navtastic.configure do |config|
|
3
|
+
config.renderer = Navtastic::Renderer::Bulma
|
4
|
+
end
|
5
|
+
|
6
|
+
Navtastic.define :main_menu do |menu|
|
7
|
+
menu.item "General" do |generalmenu|
|
8
|
+
generalmenu.item "Dashboard", '/'
|
9
|
+
generalmenu.item "Customers", '/customers'
|
10
|
+
end
|
11
|
+
|
12
|
+
menu.item "Administration" do |adminmenu|
|
13
|
+
adminmenu.item "Team Settings", '/team'
|
14
|
+
adminmenu.item "Manage Your Team", '/manage' do |teammenu|
|
15
|
+
teammenu.item "Members", '/manage/members'
|
16
|
+
teammenu.item "Plugins", '/manage/plugins'
|
17
|
+
teammenu.item "Add a member", '/manage/members/new'
|
18
|
+
end
|
19
|
+
adminmenu.item "Invitations", '/invitations'
|
20
|
+
adminmenu.item "Cloud Storage Environment Settings", '/cloud'
|
21
|
+
adminmenu.item "Authentication", '/authentication'
|
22
|
+
end
|
23
|
+
|
24
|
+
menu.item "Other renderers" do |rendermenu|
|
25
|
+
rendermenu.item "Overview", '/', root: true
|
26
|
+
rendermenu.item "Simple", '/simple', root: true
|
27
|
+
rendermenu.item "Bootstrap4", '/bootstrap4', root: true
|
28
|
+
rendermenu.item "Foundation6", '/foundation6', root: true
|
29
|
+
end
|
30
|
+
|
31
|
+
menu.config.base_url = '/bulma'
|
32
|
+
end
|
33
|
+
%>
|
34
|
+
|
35
|
+
<html>
|
36
|
+
<head>
|
37
|
+
<title>Navtastic Bulma Renderer</title>
|
38
|
+
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.5.1/css/bulma.css">
|
39
|
+
</head>
|
40
|
+
|
41
|
+
<body>
|
42
|
+
<div class="container">
|
43
|
+
<div class="content">
|
44
|
+
Menu example is taken directly from <a href="http://bulma.io/documentation/components/menu/">the Bulma documentation</a>.
|
45
|
+
</div>
|
46
|
+
<div class="columns">
|
47
|
+
<div class="column">
|
48
|
+
<div class="content">
|
49
|
+
<h1 class="title">Without headers option</h1>
|
50
|
+
<code>Navtastic.render :main_menu, current_url</code>
|
51
|
+
</div>
|
52
|
+
<div style="max-width: 300px">
|
53
|
+
<%= Navtastic.render :main_menu, current_url %>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<div class="column">
|
58
|
+
<div class="content">
|
59
|
+
<h1 class="title">With headers option</h1>
|
60
|
+
<code>Navtastic.render :main_menu, current_url, renderer: { headers: true }</code>
|
61
|
+
</div>
|
62
|
+
<div style="max-width: 300px">
|
63
|
+
<%= Navtastic.render :main_menu, current_url, renderer: { headers: true } %>
|
64
|
+
</div>
|
65
|
+
</div>
|
66
|
+
</div>
|
67
|
+
|
68
|
+
<pre>current_url: <%= current_url %></pre>
|
69
|
+
</body>
|
70
|
+
</html>
|
@@ -0,0 +1,81 @@
|
|
1
|
+
<%
|
2
|
+
Navtastic.configure do |config|
|
3
|
+
config.renderer = Navtastic::Renderer::Foundation6
|
4
|
+
end
|
5
|
+
|
6
|
+
Navtastic.define :main_menu do |menu|
|
7
|
+
menu.item "General" do |generalmenu|
|
8
|
+
generalmenu.item "Dashboard", ''
|
9
|
+
generalmenu.item "Customers", '/customers'
|
10
|
+
end
|
11
|
+
|
12
|
+
menu.item "Administration" do |adminmenu|
|
13
|
+
adminmenu.item "Team Settings", '/team'
|
14
|
+
adminmenu.item "Manage Your Team", '/manage' do |teammenu|
|
15
|
+
teammenu.item "Members", '/manage/members'
|
16
|
+
teammenu.item "Plugins", '/manage/plugins'
|
17
|
+
teammenu.item "Add a member", '/manage/members/new'
|
18
|
+
end
|
19
|
+
adminmenu.item "Invitations", '/invitations'
|
20
|
+
adminmenu.item "Cloud Storage Environment Settings", '/cloud'
|
21
|
+
adminmenu.item "Authentication", '/authentication'
|
22
|
+
end
|
23
|
+
|
24
|
+
menu.item "Other renderers" do |rendermenu|
|
25
|
+
rendermenu.item "Overview", '/', root: true
|
26
|
+
rendermenu.item "Simple", '/simple', root: true
|
27
|
+
rendermenu.item "Bootstrap4", '/bootstrap4', root: true
|
28
|
+
rendermenu.item "Bulma", '/bulma', root: true
|
29
|
+
end
|
30
|
+
|
31
|
+
menu.config.base_url = '/foundation6'
|
32
|
+
end
|
33
|
+
%>
|
34
|
+
|
35
|
+
<html>
|
36
|
+
<head>
|
37
|
+
<title>Navtastic Foundation6 Renderer</title>
|
38
|
+
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.0/css/foundation.min.css">
|
39
|
+
|
40
|
+
<style>
|
41
|
+
.is-selected {
|
42
|
+
font-weight: bold;
|
43
|
+
}
|
44
|
+
</style>
|
45
|
+
</head>
|
46
|
+
|
47
|
+
<body>
|
48
|
+
<div class="grid-container">
|
49
|
+
<p>Menu example is taken directly from <a href="http://bulma.io/documentation/components/menu/">the Bulma documentation</a>.</p>
|
50
|
+
|
51
|
+
<div class="grid-x">
|
52
|
+
<div class="auto cell">
|
53
|
+
<h1>Default style</h1>
|
54
|
+
<code>{}</code>
|
55
|
+
|
56
|
+
<div style="width: 300px">
|
57
|
+
<%= Navtastic.render :main_menu, current_url %>
|
58
|
+
</div>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<div class="auto cell">
|
62
|
+
<h1>Drilldown style</h1>
|
63
|
+
<code>{ style: :drilldown, active_class: 'is-selected' }</code>
|
64
|
+
|
65
|
+
<div style="width: 300px">
|
66
|
+
<%= Navtastic.render :main_menu, current_url, renderer: { style: :drilldown, active_class: 'is-selected' } %>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
|
72
|
+
<pre>current_url: <%= current_url %></pre>
|
73
|
+
|
74
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
75
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.4.3/js/foundation.min.js"></script>
|
76
|
+
|
77
|
+
<script>
|
78
|
+
$(document).foundation();
|
79
|
+
</script>
|
80
|
+
</body>
|
81
|
+
</html>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<%
|
2
|
+
Navtastic.configure do |config|
|
3
|
+
config.renderer = Navtastic::Renderer::Simple
|
4
|
+
end
|
5
|
+
|
6
|
+
Navtastic.define :main_menu do |menu|
|
7
|
+
menu.item "Home", '/' do |submenu|
|
8
|
+
submenu.item "Posts", '/posts'
|
9
|
+
submenu.item "About", '/about'
|
10
|
+
end
|
11
|
+
|
12
|
+
menu.item "Settings" do |submenu|
|
13
|
+
submenu.item "General", '/settings'
|
14
|
+
submenu.item "Profile", '/settings/profile'
|
15
|
+
end
|
16
|
+
|
17
|
+
menu.item "Other Renderers", '/' do |submenu|
|
18
|
+
submenu.item "Bootstrap4", '/bootstrap4', root: true
|
19
|
+
submenu.item "Bulma", '/bulma', root: true
|
20
|
+
submenu.item "Foundation6", '/foundation6', root: true
|
21
|
+
end
|
22
|
+
|
23
|
+
menu.config.base_url = '/simple'
|
24
|
+
end
|
25
|
+
%>
|
26
|
+
|
27
|
+
<html>
|
28
|
+
<head>
|
29
|
+
<title>Navtastic Simple Renderer</title>
|
30
|
+
<style type="text/css">
|
31
|
+
.current { font-weight: bold }
|
32
|
+
.current ul { font-weight: normal }
|
33
|
+
</style>
|
34
|
+
</head>
|
35
|
+
|
36
|
+
<body>
|
37
|
+
<%= Navtastic.render :main_menu, current_url %>
|
38
|
+
|
39
|
+
<pre>current_url: <%= current_url %></pre>
|
40
|
+
</body>
|
41
|
+
</html>
|
data/spec/demo/server.rb
CHANGED
@@ -14,7 +14,7 @@ class DemoServer
|
|
14
14
|
# A poor man's hot reload. Just reload everything on every request.
|
15
15
|
Object.send(:remove_const, :Navtastic) if Object.constants.include?(:Navtastic)
|
16
16
|
|
17
|
-
Dir.glob('lib/**/*.rb').each do |file|
|
17
|
+
Dir.glob('lib/**/*.rb').sort_by(&:length).each do |file|
|
18
18
|
load file
|
19
19
|
end
|
20
20
|
end
|
@@ -23,12 +23,15 @@ class DemoServer
|
|
23
23
|
WEBrick::HTTPUtils::DefaultMimeTypes.store('rhtml', 'text/html')
|
24
24
|
|
25
25
|
# Mount servlets
|
26
|
-
|
27
|
-
s.mount '/',
|
26
|
+
s.mount '/', WEBrick::HTTPServlet::ERBHandler, File.expand_path('../index.rhtml', __FILE__)
|
27
|
+
s.mount '/simple', RendererServlet, :simple
|
28
|
+
s.mount '/bootstrap4', RendererServlet, :bootstrap4
|
29
|
+
s.mount '/bulma', RendererServlet, :bulma
|
30
|
+
s.mount '/foundation6', RendererServlet, :foundation6
|
28
31
|
|
29
32
|
# Trap signals so as to shutdown cleanly.
|
30
33
|
['TERM', 'INT'].each do |signal|
|
31
|
-
trap(signal){ s.shutdown }
|
34
|
+
trap(signal) { s.shutdown }
|
32
35
|
end
|
33
36
|
|
34
37
|
# Start the server and block on input.
|
@@ -36,19 +39,27 @@ class DemoServer
|
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
39
|
-
class
|
42
|
+
class RendererServlet < WEBrick::HTTPServlet::AbstractServlet
|
43
|
+
def initialize(server, renderer)
|
44
|
+
@renderer = renderer
|
45
|
+
end
|
46
|
+
|
40
47
|
def do_GET(request, response)
|
48
|
+
@request = request
|
49
|
+
|
41
50
|
response.status = 200
|
42
51
|
response['Content-Type'] = 'text/html'
|
43
|
-
response.body = render_page
|
52
|
+
response.body = render_page
|
44
53
|
end
|
45
54
|
|
46
|
-
def render_page
|
47
|
-
template_file = File.expand_path(
|
55
|
+
def render_page
|
56
|
+
template_file = File.expand_path("../renderer/#{@renderer}.rhtml", __FILE__)
|
48
57
|
template_string = File.read template_file
|
49
58
|
|
50
|
-
current_url = request.path
|
51
|
-
|
52
59
|
ERB.new(template_string).result(binding)
|
53
60
|
end
|
61
|
+
|
62
|
+
def current_url
|
63
|
+
@request.path
|
64
|
+
end
|
54
65
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Navtastic::Configuration do
|
4
|
+
describe '.new' do
|
5
|
+
subject(:configuration) { described_class.new }
|
6
|
+
|
7
|
+
expected_defaults = {
|
8
|
+
base_url: nil,
|
9
|
+
renderer: Navtastic::Renderer::Simple,
|
10
|
+
renderer_options: {},
|
11
|
+
}
|
12
|
+
|
13
|
+
expected_defaults.each do |key, value|
|
14
|
+
context "##{key}" do
|
15
|
+
it "defaults to #{value}" do
|
16
|
+
expect(configuration.send(key)).to eq value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.reset_configuration' do
|
23
|
+
before { set_configuration renderer: :bulma }
|
24
|
+
|
25
|
+
it "sets the configuration values back to default" do
|
26
|
+
expect { Navtastic.reset_configuration }
|
27
|
+
.to change { Navtastic.configuration.renderer }
|
28
|
+
.from(Navtastic::Renderer::Bulma)
|
29
|
+
.to(Navtastic::Renderer::Simple)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.configure' do
|
34
|
+
specify do
|
35
|
+
expect { |b| Navtastic.configure(&b) }.to yield_with_args(described_class)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#renderer=' do
|
40
|
+
subject(:renderer_config) do
|
41
|
+
configuration.renderer = renderer
|
42
|
+
configuration.renderer
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:configuration) { described_class.new }
|
46
|
+
|
47
|
+
context "when the renderer parameter is a class" do
|
48
|
+
let(:renderer) { Navtastic::Renderer::Simple }
|
49
|
+
|
50
|
+
it "sets the renderer to that class" do
|
51
|
+
expect(renderer_config).to eq renderer
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when the renderer is a known symbol" do
|
56
|
+
let(:renderer) { :bulma }
|
57
|
+
|
58
|
+
it "sets the renderer to the class for that symbol" do
|
59
|
+
expect(renderer_config).to eq Navtastic::Renderer::Bulma
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when the renderer is not a known symbol" do
|
64
|
+
let(:renderer) { :foo }
|
65
|
+
|
66
|
+
it "raises an argument error" do
|
67
|
+
expect { renderer_config }.to raise_error ArgumentError
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/navtastic/item_spec.rb
CHANGED
@@ -11,4 +11,86 @@ RSpec.describe Navtastic::Item do
|
|
11
11
|
expect(menu).to have_received :current_item
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
describe '#active?' do
|
16
|
+
subject { item.active? }
|
17
|
+
|
18
|
+
let(:menu) do
|
19
|
+
menu = Navtastic::Menu.new
|
20
|
+
menu.item "Root", '/' do |submenu|
|
21
|
+
submenu.item "Sub", '/sub'
|
22
|
+
end
|
23
|
+
menu.item "Foo", '/foo'
|
24
|
+
menu.current_url = current_url
|
25
|
+
menu
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when the item has an active child" do
|
29
|
+
let(:item) { menu['/'] }
|
30
|
+
let(:current_url) { '/sub' }
|
31
|
+
|
32
|
+
it { is_expected.to eq true }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when the item does not have an active child" do
|
36
|
+
let(:item) { menu['/'] }
|
37
|
+
let(:current_url) { '/foo' }
|
38
|
+
|
39
|
+
it { is_expected.to eq false }
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the item has no submenu" do
|
43
|
+
let(:item) { menu['/sub'] }
|
44
|
+
let(:current_url) { '/' }
|
45
|
+
|
46
|
+
it { is_expected.to eq false }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when the item is the current item" do
|
50
|
+
let(:item) { menu[current_url] }
|
51
|
+
let(:current_url) { '/' }
|
52
|
+
|
53
|
+
it { is_expected.to eq true }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#url' do
|
58
|
+
subject(:url) { item.url }
|
59
|
+
|
60
|
+
let(:menu) { Navtastic::Menu.new }
|
61
|
+
|
62
|
+
context "when the item has a url" do
|
63
|
+
let(:item) { menu.item "A", '/a' }
|
64
|
+
|
65
|
+
it "returns that url" do
|
66
|
+
expect(url).to eq '/a'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when the item doesn't have a url" do
|
71
|
+
let(:item) { menu.item "A" }
|
72
|
+
|
73
|
+
it { is_expected.to eq nil }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when the the menu has a base_url" do
|
77
|
+
before { menu.config.base_url = '/admin' }
|
78
|
+
|
79
|
+
let(:item) { menu.item "Settings", '/settings' }
|
80
|
+
|
81
|
+
it "prepends the base url to the item" do
|
82
|
+
expect(url).to eq '/admin/settings'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when the item is set to be as root" do
|
87
|
+
before { menu.config.base_url = '/admin' }
|
88
|
+
|
89
|
+
let(:item) { menu.item "Home", '/home', root: true }
|
90
|
+
|
91
|
+
it "doesn't prepend the base url to the item" do
|
92
|
+
expect(url).to eq '/home'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
14
96
|
end
|