navigatrix 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 28321e32d4430f1d16823c1a3d23121d25a1d2a3
4
- data.tar.gz: 8c466c5479a7330322bb2989a49d11621e13f81a
5
- SHA512:
6
- metadata.gz: d7c652b8c6d1e5ddbda0e997b1829307828d2951ae775a680c3407d1c2ff040e2fa444375a0e2facfddfa43d83a6092aa5d993b77a01af0007f758559accbebf
7
- data.tar.gz: 0eeb7a60fc49e5f7ce8a2e8c683bda0d10716694cb09f65a10d0dcf006310fd9f9245cddd599c87ecc9577fb994489f2c38dccb72ce705501ba979dd13c20568
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTU0ZDk1YzY1NjgxODkwODM0YmE1NjcyYmRmMWQwNWRjYmYwNTUxZQ==
5
+ data.tar.gz: !binary |-
6
+ NWRlOTg0NDVmYWZkNTg1MGEwYmRhMTU2Y2EwNGM4Yjc2MjFkMjk3MA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MTI3M2I0MTIyYTE0ZjI0N2U4ZDA1NjhlNTJjMWU4MjBjYzg4YjU5NGU4NGM4
10
+ NWVmZmViNDY4NjgyMzRjZTk3NmU2NTAzZjk4MjkwZTE0N2FlMjU1YmI2ZDEw
11
+ NTQzMDU4YjQyZTJiMzM2YzNmMmIxYTVlMWE5ZThmZTM3ODM0ZWQ=
12
+ data.tar.gz: !binary |-
13
+ NWU0YzVjMGY3OTYxYWJkNTEyZTQ0ZDBiMWVkMzI1NmU2NmZiNWI1NmU2YWNl
14
+ MjdmMDVhMDhkNWE1NzNmOTk3ZjBhNGFhODVjZmNjOTk5MmZiMTcwNzdiOGZh
15
+ MmM2NDhmNTk4ZmEzNmM3NzhkZGRkNjYzOGMwYTc4ZThjMTg2ZmY=
data/README.md CHANGED
@@ -46,9 +46,13 @@ Assuming we're on the "/about-us" path, the resulting HTML will look like this:
46
46
  :render? => user_signed_in?
47
47
  }
48
48
  }, {
49
- :active_class => "active-nav-item",
50
- :html_attributes => {
51
- :class => "nav"
49
+ :item => {
50
+ :active_class => "active-nav-item"
51
+ },
52
+ :list => {
53
+ :html_attributes => {
54
+ :class => "nav"
55
+ }
52
56
  }
53
57
  }) %>
54
58
  ```
@@ -57,14 +61,45 @@ Assuming we're on the "/users/1" path, and a User is signed in, the resulting HT
57
61
  ```HTML
58
62
  <ul class="nav">
59
63
  <li><a href="/">Home</a></li>
60
- <li class="active-nav-item">Users</li>
64
+ <li class="active-nav-item"><a href="/users">Users</a></li>
61
65
  <li><a href="/sign_out">Sign Out</a></li>
62
66
  </ul>
63
67
  ```
64
68
  The "Users" item is active and not linked because the path "/users/1" matches the pattern `/\/users\/\d*/`. The "Home" item is linked because we are not on the path "/".
65
69
 
70
+ ## List Configuration Options
71
+ List configuration options are supplied via the `:list` option when rendering a navigation. For example,
72
+
73
+ ```Ruby
74
+ render_navigation(config, {
75
+ list: {
76
+ html_attributes: {
77
+ class: "nav"
78
+ }
79
+ }
80
+ })
81
+ ```
82
+
83
+ A list accepts the following configuration options:
84
+
85
+ ##### `:html_attributes`
86
+ HTML attributes added to an the list.
66
87
 
67
88
  ## List Item Configuration Options
89
+
90
+ List item configuration options can be supplied to all list items or a single list item. Supply options to a single list item via the navigation configuration.
91
+
92
+ ```Ruby
93
+ render_navigation({
94
+ "Home" => {
95
+ path: "/",
96
+ active_class: "home-active"
97
+ }
98
+ })
99
+ ```
100
+
101
+ The following options are supported.
102
+
68
103
  ##### `:path`
69
104
  Specifies where the navigation item should link to.
70
105
 
@@ -133,12 +168,78 @@ Results in the following HTML.
133
168
  ##### `:render?`
134
169
  Determines if the navigation item is rendered.
135
170
 
136
- ## List Configuration Options
137
- ##### `:html_attributes`
138
- HTML attributes added to an the list.
171
+ ### Supplying options to all list items
172
+ List configuration options are supplied via the `:item` option when rendering a navigation. For example,
173
+ ```Ruby
174
+ render_navigation(config, {
175
+ item: {
176
+ active_class: "active-item"
177
+ }
178
+ })
179
+ ```
180
+
181
+ Supported options are:
139
182
 
140
183
  ##### `:active_class`
141
184
  Determines which HTML class is applied to list items when the item is active.
142
185
 
143
186
  ##### `:inactive_class`
144
187
  Determines which HTML class is applied to list items when the item is *not* active.
188
+
189
+ `active_class`, `inactive_class`, `html_attributes`.
190
+
191
+ ## Building Custom List Renderers
192
+
193
+ To change the default list rendering from \<ul> tags to \<section> tags with an id of "nav", create a custom list renderer:
194
+
195
+ ```Ruby
196
+ Navigatrix.register_list_renderer(:my_custom_list) do |renderer|
197
+ renderer.wrapper do |items, html_attributes|
198
+ content_tag(:section, items, html_attributes.merge_attribute(:id, "nav"))
199
+ end
200
+ end
201
+ ```
202
+
203
+ ```ERB
204
+ <%= render_navigation({
205
+ "Home" => "/",
206
+ "About Us" => "/about-us",
207
+ }, {
208
+ list: {renderer: :my_custom_list}
209
+ }) %>
210
+ ```
211
+
212
+ ## Building Custom Item Renderers
213
+
214
+ If the basic list and and item configuration, custom renders can be registered.
215
+
216
+ For example, to add change the default item rendering from \<li> tags to \<p> tags, create a custom item renderer:
217
+
218
+ ```Ruby
219
+ Navigatrix.register_item_renderer(:my_custom_item) do |renderer|
220
+ renderer.wrapper do |content, children, html_attributes|
221
+ content(:p, content + children, html_attributes)
222
+ end
223
+ end
224
+ ```
225
+
226
+ ```ERB
227
+ <%= render_navigation({
228
+ "Home" => "/",
229
+ "About Us" => "/about-us",
230
+ }, {
231
+ item: {renderer: :my_custom_item}
232
+ }) %>
233
+ ```
234
+
235
+ #### All item rendering options
236
+
237
+ `wrapper` - wraps item content - accepts `content, children, html_attributes`
238
+
239
+ `linked` - content when the item is linked - accepts `name, path`
240
+
241
+ `unlinked` - content when the item is not linked - accepts `name, path`
242
+
243
+ `html_attributes` - HTML attributes for the item
244
+
245
+ `children_options` - attributes passed to the child list
@@ -2,8 +2,31 @@ require "navigatrix/version"
2
2
  require "navigatrix/item"
3
3
  require "navigatrix/item_collection"
4
4
  require "navigatrix/renderer"
5
+ require "navigatrix/builder"
5
6
  require 'navigatrix/integration/rails' if defined?(Rails)
6
7
  require 'navigatrix/integration/sinatra' if defined?(Sinatra)
7
8
 
8
9
  module Navigatrix
10
+ extend self
11
+
12
+ mattr_accessor :list_renderers
13
+
14
+ self.list_renderers = {
15
+ :unordered_list => Rendering::Strategies::List,
16
+ :bootstrap_navbar => Rendering::Strategies::Bootstrap::Navbar,
17
+ :bootstrap_tabs => Rendering::Strategies::Bootstrap::Tabs
18
+ }
19
+
20
+ mattr_accessor :item_renderers
21
+ self.item_renderers = {
22
+ :item => Rendering::Strategies::Item
23
+ }
24
+
25
+ def register_list_renderer(name, &block)
26
+ list_renderers[name] = ListBuilder.build(&block)
27
+ end
28
+
29
+ def register_item_renderer(name, &block)
30
+ item_renderers[name] = ItemBuilder.build(&block)
31
+ end
9
32
  end
@@ -0,0 +1,69 @@
1
+ module Navigatrix
2
+ class Builder
3
+ attr_reader :klass
4
+
5
+ def self.build(&block)
6
+ instance = new(klass)
7
+ block.call(instance)
8
+ instance.klass
9
+ end
10
+
11
+ def initialize(klass)
12
+ @klass = Class.new(klass)
13
+ end
14
+
15
+ def define_method(method_name, &block)
16
+ @klass.send(:define_method, method_name, &block)
17
+ end
18
+ end
19
+
20
+ class ListBuilder < Builder
21
+ def self.klass
22
+ Navigatrix::Rendering::Strategies::List
23
+ end
24
+
25
+ def wrapper(&block)
26
+ define_method(:render) do
27
+ instance_exec(render_items, html_attributes, &block)
28
+ end
29
+ end
30
+ end
31
+
32
+ class ItemBuilder < Builder
33
+ def self.klass
34
+ Navigatrix::Rendering::Strategies::Item
35
+ end
36
+
37
+ def wrapper(&block)
38
+ define_method(:render) do
39
+ instance_exec(name_or_link, render_children, html_attributes, &block) if render?
40
+ end
41
+ end
42
+
43
+ def linked(&block)
44
+ define_method(:linked_content) do
45
+ instance_exec(name, path, &block)
46
+ end
47
+ end
48
+
49
+ def unlinked(&block)
50
+ define_method(:unlinked_content) do
51
+ instance_exec(name, path, &block)
52
+ end
53
+ end
54
+
55
+ def children_options(&block)
56
+ define_method(:children_options) do
57
+ instance_exec(super(), &block)
58
+ end
59
+ end
60
+
61
+ def html_attributes(&block)
62
+ define_method(:html_attributes) do
63
+ instance_exec(&block).inject(super()) do |acc, (key, val)|
64
+ acc.merge_attribute(key, val)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -23,6 +23,14 @@ module Navigatrix
23
23
  {}
24
24
  end
25
25
 
26
+ def active_class
27
+ nil
28
+ end
29
+
30
+ def inactive_class
31
+ nil
32
+ end
33
+
26
34
  def render?
27
35
  true
28
36
  end
@@ -30,6 +38,8 @@ module Navigatrix
30
38
 
31
39
  class AdvancedConfig < OpenStruct
32
40
  DEFAULTS = {
41
+ :active_class => nil,
42
+ :inactive_class => nil,
33
43
  :html_attributes => {},
34
44
  :render? => true,
35
45
  :children => {}
@@ -6,7 +6,7 @@ module Navigatrix
6
6
  class Item < Struct.new(:name, :config, :context)
7
7
  extend Forwardable
8
8
  delegate :current_path => :context
9
- delegate [:render?, :html_attributes] => :config
9
+ delegate [:render?, :html_attributes, :active_class, :inactive_class] => :config
10
10
 
11
11
  def active?
12
12
  applicable_active_state? ||
@@ -1,4 +1,5 @@
1
1
  require "navigatrix/rendering/context"
2
+ require "navigatrix/rendering/strategy_factory"
2
3
  require "navigatrix/rendering/strategies/list"
3
4
  require "navigatrix/rendering/strategies/bootstrap/navbar"
4
5
  require "navigatrix/rendering/strategies/bootstrap/tabs"
@@ -7,23 +8,14 @@ module Navigatrix
7
8
  class Renderer
8
9
  attr_reader :configuration, :strategy, :render_context, :render_options
9
10
 
10
- REGISTERED_STRATEGIES = {
11
- :unordered_list => Rendering::Strategies::List,
12
- :bootstrap_navbar => Rendering::Strategies::Bootstrap::Navbar,
13
- :bootstrap_tabs => Rendering::Strategies::Bootstrap::Tabs
14
- }
15
-
16
- class MissingStrategy < NameError ; end
17
-
18
11
  def initialize(configuration, options)
19
12
  @configuration = configuration
20
- @strategy = find_strategy(options.delete(:strategy))
21
13
  @render_context = Rendering::Context.new(options.delete(:render_context))
22
14
  @render_options = options
23
15
  end
24
16
 
25
17
  def render
26
- strategy.new(item_collection.items, render_options).render
18
+ strategy.new(item_collection.items, list_options, item_options).render
27
19
  end
28
20
 
29
21
  private
@@ -32,10 +24,24 @@ module Navigatrix
32
24
  ItemCollection.new(configuration, render_context)
33
25
  end
34
26
 
35
- def find_strategy(strategy_or_name)
36
- return strategy_or_name if strategy_or_name.is_a?(Class)
37
- strategy_or_name ||= :unordered_list
38
- REGISTERED_STRATEGIES[strategy_or_name] || raise(MissingStrategy, "can't find strategy #{strategy_name}")
27
+ def strategy
28
+ Rendering::StrategyFactory.find_list_strategy(strategy_name)
29
+ end
30
+
31
+ def strategy_name
32
+ render_options.fetch(:list, {})[:renderer]
33
+ end
34
+
35
+ def list_options
36
+ base = render_options[:html_attributes]
37
+ (base ? {html_attributes: base} : {})
38
+ .merge(render_options.fetch(:list, {}))
39
+ end
40
+
41
+ def item_options
42
+ render_options
43
+ .slice(:active_class, :inactive_class)
44
+ .merge(render_options.fetch(:item, {}))
39
45
  end
40
46
  end
41
47
  end
@@ -1,36 +1,40 @@
1
1
  require "navigatrix/rendering/strategies/list"
2
2
 
3
- module Navigatrix::Rendering::Strategies
4
- module Bootstrap
5
- class Navbar < List
3
+ module Navigatrix
4
+ module Rendering
5
+ module Strategies
6
+ module Bootstrap
7
+ class Navbar < List
6
8
 
7
- private
9
+ private
8
10
 
9
- def html_attributes
10
- super.merge_attribute(:class, "nav")
11
- end
11
+ def html_attributes
12
+ super.merge_attribute(:class, "nav")
13
+ end
12
14
 
13
- def items
14
- super.map { |item| (item.has_children? ? Item : List::Item).new(item, options) }
15
- end
15
+ def items
16
+ super.map { |item| (item.has_children? ? Item : Strategies::Item).new(item, options) }
17
+ end
16
18
 
17
- class Item < List::Item
18
- private
19
+ class Item < Strategies::Item
20
+ private
19
21
 
20
- def html_attributes
21
- super.merge_attribute(:class, "dropdown")
22
- end
22
+ def html_attributes
23
+ super.merge_attribute(:class, "dropdown")
24
+ end
23
25
 
24
- def name
25
- (super + dropdown_icon).html_safe
26
- end
26
+ def name
27
+ (super + dropdown_icon).html_safe
28
+ end
27
29
 
28
- def nested_list
29
- List.new(children, options).render if has_children?
30
- end
30
+ def nested_list
31
+ List.new(children, options).render if has_children?
32
+ end
31
33
 
32
- def dropdown_icon
33
- options[:dropdown_icon] || content_tag(:i, nil, :class => "icon-chevron-down icon-white")
34
+ def dropdown_icon
35
+ options[:dropdown_icon] || content_tag(:i, nil, :class => "icon-chevron-down icon-white")
36
+ end
37
+ end
34
38
  end
35
39
  end
36
40
  end
@@ -1,11 +1,15 @@
1
- module Navigatrix::Rendering::Strategies
2
- module Bootstrap
3
- class Tabs < List
1
+ module Navigatrix
2
+ module Rendering
3
+ module Strategies
4
+ module Bootstrap
5
+ class Tabs < List
4
6
 
5
- private
7
+ private
6
8
 
7
- def html_attributes
8
- super.merge_attribute(:class, "nav nav-tabs")
9
+ def html_attributes
10
+ super.merge_attribute(:class, "nav nav-tabs")
11
+ end
12
+ end
9
13
  end
10
14
  end
11
15
  end