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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f71489809ad37489fff943b48ecc3c00224a7d5d
4
- data.tar.gz: 8d52c7216084c2e84d620ae1f94b7464fc4c68ad
3
+ metadata.gz: f1310ede0cecc3da85ea235b10c6bd7b6413d823
4
+ data.tar.gz: 7507adc0d81b1e381463fabc7f0a912b24e8b586
5
5
  SHA512:
6
- metadata.gz: c9a022d6a93b60adbc98dfed4d8fe26b9a9b4d35c6ac1e37a83e9a6c511cd4c021ed15e5fd4cc6871d40c585b032b13e6062c503550d11892fdccf7802d69015
7
- data.tar.gz: 6b3678f6e320f10eab9f158845ec34cdb634f0b3babe35fa9c7649dfd907148a348438b6a7febb60bfef866fe185e76fe8225ff3b0b1cf0dc1b251750a9c7b85
6
+ metadata.gz: fab8bbf0725908f60ecdd76c50709ea4cff88ccbf43ba30f4cd1d6085b03b4e3baeae5bd18ebec37ba19f8dec5e77a5e4a77c78395ec0a44621c0c049ce1749b
7
+ data.tar.gz: d315fb9dc68df9e0d827b231421684d9b211611b249a69163fa65b95055c797062286a6935144af2246c33e011ff1d9aef3d75e67c6961c48063c312149eb297
data/.rubocop.yml CHANGED
@@ -6,16 +6,26 @@ AllCops:
6
6
  - '**/Rakefile'
7
7
  Exclude:
8
8
  - 'spec/demo/**/*'
9
+ - 'spec/support/**/*'
9
10
  - 'vendor/**/*'
10
11
  TargetRubyVersion: 2.4
11
12
 
13
+ Metrics/AbcSize:
14
+ Max: 20
15
+
12
16
  Metrics/BlockLength:
13
17
  Exclude:
14
18
  - 'spec/**/*_spec.rb'
15
- - 'spec/support/matchers/**/*'
19
+
20
+ Metrics/MethodLength:
21
+ Max: 15
16
22
 
17
23
  Style/FrozenStringLiteralComment:
18
24
  Enabled: false
19
25
 
20
26
  Style/StringLiterals:
21
27
  Enabled: false
28
+
29
+ Style/TrailingCommaInLiteral:
30
+ EnforcedStyleForMultiline: consistent_comma
31
+
data/.yardopts CHANGED
@@ -2,3 +2,4 @@
2
2
  --no-private
3
3
  -
4
4
  LICENSE
5
+ CHANGELOG.md
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.1.0] - 2017-09-05
6
+
7
+ ### Added
8
+
9
+ - Configuration options
10
+ - Base urls
11
+ - New Renderers: Bootstrap4, Bulma, Foundation 6
12
+ - Only vertical menus are supported for now
13
+
5
14
  ## 0.0.1 - 2017-08-21
6
15
 
7
16
  ### Added
@@ -11,4 +20,5 @@
11
20
  - Highlighting current menu item
12
21
  - Runtime parameters
13
22
 
14
- [Unreleased]: https://github.com/aramvisser/navtastic/compare/v0.0.1...HEAD
23
+ [Unreleased]: https://github.com/aramvisser/navtastic/compare/v0.1.0...HEAD
24
+ [0.1.0]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.0.1...v0.1.0
data/README.md CHANGED
@@ -3,13 +3,19 @@
3
3
  [![Build Status](https://img.shields.io/circleci/project/github/aramvisser/navtastic.svg)](https://circleci.com/gh/aramvisser/navtastic)
4
4
  [![Code Coverage](https://img.shields.io/codeclimate/coverage/github/aramvisser/navtastic.svg)](https://codeclimate.com/github/aramvisser/navtastic)
5
5
  [![Inline docs](https://inch-ci.org/github/aramvisser/navtastic.svg?branch=master)](https://inch-ci.org/github/aramvisser/navtastic)
6
+ [![Gem](https://img.shields.io/gem/v/navtastic.svg)](https://rubygems.org/gems/navtastic)
6
7
  [![MIT License](https://img.shields.io/github/license/aramvisser/navtastic.svg)](https://github.com/aramvisser/navtastic/blob/master/LICENSE)
7
8
 
8
- Navtastic is way to create and render complex navigation menus. It allows for runtime configurations
9
- of menus.
9
+ Navtastic is way to create and display complex navigation menus for websites. It allows for runtime
10
+ configurations of menus, depending on context.
10
11
 
11
12
  - Keep menu content and rendering logic separate
12
13
  - Automatically highlight the current page
14
+ - Different output structures supported (Simple, Bootstrap4, Bulma, Foundation6)
15
+ - HTML structure only, bring your own CSS.
16
+ - Easily create your own renderer to fit your style.
17
+
18
+ _The current renderers only support vertical menus. Horizontal (navbar) menus are planned._
13
19
 
14
20
  ## Table of Contents
15
21
 
@@ -18,7 +24,13 @@ of menus.
18
24
  - [Documentation](#documentation)
19
25
  - [Submenus](#submenus)
20
26
  - [Current item](#current-item)
27
+ - [Custom classes](#custom-classes)
21
28
  - [Runtime parameters](#runtime-parameters)
29
+ - [Global Configuration](#global-configuration)
30
+ - [Menu Configuration](#menu-configuration)
31
+ - [Item Configuration](#item-configuration)
32
+ - [Renderers](#renderers)
33
+ - [Development](#development)
22
34
 
23
35
  ## Installation
24
36
 
@@ -36,7 +48,7 @@ bundle install
36
48
 
37
49
  ## Example
38
50
 
39
- Define a menu somwhere:
51
+ Define a menu somewhere:
40
52
 
41
53
  ```ruby
42
54
  Navtastic.define :main_menu do |menu|
@@ -70,9 +82,9 @@ Using the default renderer, assuming that the current url starts with `/posts`,
70
82
 
71
83
  ## Documentation
72
84
 
73
- ## Submenus
85
+ ### Submenus
74
86
 
75
- Every item can have a submenu. They can be nested as deeply as you want (or at least until Ruby starts complaining).
87
+ Every item can have a submenu. They can be nested as deeply as you want.
76
88
 
77
89
  ```ruby
78
90
  Navtastic.define :main_menu do |menu|
@@ -117,7 +129,7 @@ For example, if there is a menu containing these urls:
117
129
  If the current_url is `/posts/featured/2017`, the `/posts/featured` item will be highlighted. If the
118
130
  current_url is `/posts/123`, then `/posts` is highlighted.
119
131
 
120
- The root url `/` will always match, if no other items match the current _url. If there is no item
132
+ The root url `/` will always match, if no other items match the current url. If there is no item
121
133
  with `/` as url in the menu and no other urls match, nothing will be highlighted.
122
134
 
123
135
  ### Runtime parameters
@@ -141,3 +153,131 @@ end
141
153
  # Render it with the current user as a parameter
142
154
  Navtastic.render :main_menu, current_url, current_user: User.current
143
155
  ```
156
+
157
+ ### Global Configuration
158
+
159
+ Some global settings that Navtastic uses can be configured. Make sure the configuration happens
160
+ before defining any menu (e.g. when using rails, add it to `config/initializers/navtastic.rb`).
161
+
162
+ These are the defaults values:
163
+
164
+ ```ruby
165
+ Navtastic.configure do |config|
166
+ # This url to prepend before every item url
167
+ config.base_url = nil
168
+
169
+ # Set the renderer to use, can be one of :simple, :bootstrap4, :bulma, :foundation6
170
+ # Can also be a class if you want to use a custom renderer
171
+ config.renderer = :simple
172
+
173
+ # Options that are passed to the renderer
174
+ config.renderer_options = {}
175
+ end
176
+ ```
177
+
178
+ ### Menu Configuration
179
+
180
+ Each individual menu can also be configured in some way:
181
+
182
+ ```ruby
183
+ Navtastic.define :user_menu do |menu, params|
184
+ # The url to put before every item
185
+ menu.config.base_url = '/users/' + params[:user_id]
186
+
187
+ menu.item "Profile", '/profile' # will link to: /users/123/profile
188
+ end
189
+ ```
190
+
191
+ ### Item Configuration
192
+
193
+ Every item can have options passed to it:
194
+
195
+ ```ruby
196
+ Navtastic.define :menu do |menu|
197
+ # Add a css class to the container (e.g. <li> tag)
198
+ menu.item "Home", "/", class: 'highlight'
199
+
200
+ # Add a css class the content inside the container (e.g. <a> tag)
201
+ menu.item "Posts", "/posts", content_class: 'important'
202
+
203
+ # If `root` is true, this item will ignore any base urls
204
+ menu.item "Somewhere", '/', root: true
205
+
206
+ # Use the item url as the base_url for the submenu
207
+ menu.item "Settings", '/settings', base_url: true do |submenu|
208
+ # submenu.config.base_url is now set to '/settings'
209
+ end
210
+ end
211
+ ```
212
+
213
+ ### Renderers
214
+
215
+ The following renders are currently available:
216
+
217
+ - **Simple** adds a `current` class to the basic list structure
218
+ - **Bootstrap4** is used with the [Bootstrap 4](https://getbootstrap.com) framework.
219
+ - **Bulma** is used with the [Bulma.io](http://bulma.io) framework.
220
+ - **Foundation6** is used with the [Foundation 6](http://foundation.zurb.com/sites.html) framework.
221
+
222
+ Some renderers also support extra options. You can set them globally in the configuration or pass
223
+ them at runtime when rendering a menu:
224
+
225
+ ```ruby
226
+ # Global options
227
+ Navtastic.configure do |config|
228
+ config.renderer_options = { option: value }
229
+ end
230
+ ```
231
+
232
+ ```erb
233
+ # Runtime options
234
+ <%= Navtastic.render :menu, current_url, renderer: { option: value } %>
235
+ ```
236
+
237
+ Globally defined options and options given at runtime are merged together, with those at runtime
238
+ taking precedence.
239
+
240
+ #### Bulma Configuration
241
+
242
+ - **headers** (default: `false`)
243
+
244
+ Top level items are styled differently. Works best if they are only text, not
245
+ links.
246
+
247
+ <div align="center">
248
+ <figure>
249
+ <img src="docs/bulma_headers_preview.png"><br>
250
+ <figcaption>left: <code>headers: false</code>, right: <code>headers: true</code></legend>
251
+ </figure>
252
+ </div>
253
+
254
+ #### Foundation Configuration
255
+
256
+ - **active_class** (default: `nil`)
257
+
258
+ CSS class to use for active items. Active items are items that have a child that is the current
259
+ item. Useful to highlight the current item in a drilldown menu.
260
+
261
+ - **style** (default: `nil`)
262
+
263
+ Set to `:drilldown` to generate [a drilldown
264
+ menu](http://foundation.zurb.com/sites/docs/drilldown-menu.html). Make sure you include the
265
+ required javascript files.
266
+
267
+ <div align="center">
268
+ <figure>
269
+ <img src="docs/foundation_styles_preview.png"><br>
270
+ <figcaption>left: default style, right: drilldown style</figcaption>
271
+ </figure>
272
+ </div>
273
+
274
+ ## Development
275
+
276
+ 1. Checkout Repository: `git clone https://github.com/aramvisser/navtastic.git`
277
+ 2. Install Bundler: `gem install bundler`
278
+ 3. Run `bundle install` inside the project root to install the gem dependencies
279
+ 4. Run test cases: `bundle exec rake`
280
+
281
+ For testing visual changes, a test server is provided by running `bundle exec rake demo`. It's
282
+ accessibly on http://localhost:9090.
283
+
Binary file
Binary file
data/lib/navtastic.rb CHANGED
@@ -1,6 +1,11 @@
1
+ require 'navtastic/configuration'
1
2
  require 'navtastic/item'
2
3
  require 'navtastic/menu'
3
4
  require 'navtastic/renderer'
5
+ require 'navtastic/renderer/bootstrap4'
6
+ require 'navtastic/renderer/bulma'
7
+ require 'navtastic/renderer/foundation6'
8
+ require 'navtastic/renderer/simple'
4
9
  require 'navtastic/version'
5
10
 
6
11
  # Main module containing some convenience methods
@@ -33,9 +38,16 @@ module Navtastic
33
38
 
34
39
  # Render a stored menu
35
40
  #
41
+ # The `params` parameter is passed along to the block in {Navtastic.define}.
42
+ #
43
+ # If `params` contains a `:renderer` key, it's removed from the hash and
44
+ # passed to the renderer instead. Look at the renderer documentation to see
45
+ # which options are supported.
46
+ #
36
47
  # @param name the name of the defined menu
37
48
  # @param current_url [String] the url of the current page
38
49
  # @param params [Hash] runtime parameters
50
+ # @option params [Hash] :renderer Options passed to the renderer
39
51
  #
40
52
  # @raise [KeyError] if the menu was not defined
41
53
  #
@@ -46,10 +58,14 @@ module Navtastic
46
58
 
47
59
  raise KeyError, "menu not defined: #{name.inspect}" if block.nil?
48
60
 
61
+ # Merge renderer options globally with those passed at runtime
62
+ renderer_options = configuration.renderer_options
63
+ renderer_options.merge!(params.delete(:renderer) || {})
64
+
49
65
  menu = Menu.new
50
66
  block.call(menu, params)
51
67
  menu.current_url = current_url
52
- Renderer.render(menu)
68
+ Navtastic.configuration.renderer.render(menu, renderer_options)
53
69
  end
54
70
 
55
71
  # A list of all defined menus
@@ -0,0 +1,84 @@
1
+ module Navtastic # :nodoc:
2
+ # Configuration settings
3
+ class Configuration
4
+ # The base url will be prepended to every item url
5
+ #
6
+ # Defaults to nil.
7
+ #
8
+ # @return [String,nil]
9
+
10
+ attr_accessor :base_url
11
+ # The default renderer to use when displaying a menu
12
+ #
13
+ # Defaults to {Navtastic::Renderer::Simple}.
14
+ #
15
+ # @return any class that responds to the `.render` method
16
+ attr_reader :renderer
17
+
18
+ # Default options passed to the current renderer
19
+ #
20
+ # Defaults to empty Hash.
21
+ #
22
+ # @return [Hash]
23
+ attr_accessor :renderer_options
24
+
25
+ def initialize
26
+ @renderer = Navtastic::Renderer::Simple
27
+ @renderer_options = {}
28
+ @base_url = nil
29
+ end
30
+
31
+ # Set the renderer to use for displaying a menu
32
+ #
33
+ # @param value [Symbol,Class]
34
+ def renderer=(value)
35
+ if value.is_a? Symbol
36
+ renderers = available_renderers
37
+
38
+ unless renderers.key? value
39
+ raise ArgumentError, "Unknown renderer: #{value}"
40
+ end
41
+
42
+ @renderer = renderers[value]
43
+ else
44
+ @renderer = value
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # Built in renderers
51
+ #
52
+ # @return Hash
53
+ def available_renderers
54
+ {
55
+ bootstrap4: Renderer::Bootstrap4,
56
+ bulma: Renderer::Bulma,
57
+ foundation6: Renderer::Foundation6,
58
+ simple: Renderer::Simple,
59
+ }
60
+ end
61
+ end
62
+
63
+ # @return [Navtastic::Configuration] current configuration
64
+ def self.configuration
65
+ @configuration ||= Configuration.new
66
+ end
67
+
68
+ # This will reset the configuration back to defaults
69
+ def self.reset_configuration
70
+ @configuration = nil
71
+ end
72
+
73
+ # Modify Navtastic's current configuration
74
+ #
75
+ # @example Modify the current configuration
76
+ # Navtastic.configure do |config|
77
+ # config.setting = :updated
78
+ # end
79
+ #
80
+ # @yieldparam [Navtastic::Configuration] current Navtastic configuration
81
+ def self.configure
82
+ yield configuration
83
+ end
84
+ end
@@ -1,11 +1,14 @@
1
1
  module Navtastic
2
2
  # A single menu item
3
3
  class Item
4
+ # @return [Menu] the containing menu
5
+ attr_reader :menu
6
+
4
7
  # @return [String] the name to be displayed in the menu
5
8
  attr_reader :name
6
9
 
7
- # @return [String,nil] the url to link to if item is a link, nil otherwise
8
- attr_reader :url
10
+ # @return [Hash] extra options to configure individual items
11
+ attr_reader :options
9
12
 
10
13
  # @return [Menu,nil] the submenu of this item, if defined
11
14
  attr_accessor :submenu
@@ -19,10 +22,12 @@ module Navtastic
19
22
  # @param menu [Menu] the menu this items belongs to
20
23
  # @param name [String] the name to display when rendering
21
24
  # @param url [String] the url to link to, if the item is a link
22
- def initialize(menu, name, url = nil)
25
+ # @param options [Hash] extra configuration options
26
+ def initialize(menu, name, url = nil, options = {})
23
27
  @menu = menu
24
28
  @name = name
25
29
  @url = url
30
+ @options = options
26
31
 
27
32
  @submenu = nil
28
33
  end
@@ -37,6 +42,21 @@ module Navtastic
37
42
  @menu.current_item == self
38
43
  end
39
44
 
45
+ # Check if the item has a current child in its submenu (or deeper)
46
+ #
47
+ # Also returns true if this is the current item.
48
+ #
49
+ # @see file:README.md#Current_item documentation on how the current item is
50
+ # selected
51
+ #
52
+ # @return [Bool] if the item is the current item
53
+ def active?
54
+ return true if current?
55
+ return false unless submenu
56
+
57
+ submenu.items.any?(&:active?)
58
+ end
59
+
40
60
  # @return [Bool] true if the item has a submenu, false other
41
61
  def submenu?
42
62
  !@submenu.nil?
@@ -45,5 +65,26 @@ module Navtastic
45
65
  def inspect
46
66
  "#<Item \"#{name}\" [#{url}] current?:#{current?}>"
47
67
  end
68
+
69
+ # Check if item has a link or not
70
+ #
71
+ # @return [Bool]
72
+ def url?
73
+ !@url.nil?
74
+ end
75
+
76
+ # The url for this item, if the item has a url
77
+ #
78
+ # Will prepend the `base_url` for the menu if it is present
79
+ #
80
+ # @return [String,nil]
81
+ def url
82
+ return nil unless url?
83
+ return @url if options[:root]
84
+
85
+ url = "#{@menu.base_url}#{@url}"
86
+ url.chomp!('/') unless url == '/'
87
+ url
88
+ end
48
89
  end
49
90
  end