bootstrap-navbar 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1a8ce95231b5f0e27729be22f6f1c510c7425e4
4
+ data.tar.gz: 5bff4661ff302e82b4e113daadb54e0b6f33b838
5
+ SHA512:
6
+ metadata.gz: 71f6ece8a5c288f346e1b195cefd700d4fddc62d9a4d8ded4c2eded71de02732d8c7fce1cfab7879f8df6cddae3d01e6eadab4fe133a00f4806f4a3a2b571423
7
+ data.tar.gz: 6e0a9f2d3805b95e08570f824efcc488581227084c73f07da188581b118fe7bfc18508bc7d494eef1e41c88291d337352d9e0d887880f6771ab9a5ddaa7644cb
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode
6
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gemspec
@@ -0,0 +1,9 @@
1
+ guard 'rspec', cli: '--drb --profile', all_after_pass: false do
2
+ # Specs
3
+ watch(%r(^spec/.+_spec\.rb$))
4
+ watch('spec/spec_helper.rb') { 'spec' }
5
+ watch(%r(^spec/support/(.+)\.rb$)) { 'spec' }
6
+
7
+ # Files
8
+ watch(%r(^lib/(.+)\.rb$)) { |m| "spec/#{m[1]}_spec.rb" }
9
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 kraut computing UG (haftungsbeschränkt)
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,513 @@
1
+ # BootstrapNavbar
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/bootstrap-navbar.png)](http://badge.fury.io/rb/bootstrap-navbar)
4
+ [![Build Status](https://secure.travis-ci.org/krautcomputing/bootstrap-navbar.png)](http://travis-ci.org/krautcomputing/bootstrap-navbar)
5
+ [![Dependency Status](https://gemnasium.com/krautcomputing/bootstrap-navbar.png)](https://gemnasium.com/krautcomputing/bootstrap-navbar)
6
+ [![Code Climate](https://codeclimate.com/github/krautcomputing/bootstrap-navbar.png)](https://codeclimate.com/github/krautcomputing/bootstrap-navbar)
7
+
8
+ Helpers to generate a Twitter Bootstrap style navbar
9
+
10
+ ## Installation
11
+
12
+ This gem only provides a helper module with methods to generate HTML. It can be used by other gems to make these helpers available to a framework's rendering engine, e.g.:
13
+
14
+ * For Rails: https://github.com/julescopeland/Rails-Bootstrap-Navbar
15
+ * For [Middleman](http://middlemanapp.com/): https://github.com/krautcomputing/middleman-bootstrap-navbar
16
+
17
+ In short: __Unless you know what you're doing, do not use this gem directly in your app!__
18
+
19
+ ## Setup
20
+
21
+ ### Set current_url_method (required)
22
+
23
+ BootstrapNavbar has to be able to query for the current URL when rendering the navbar, e.g. to determine if a menu item is active or not. Since the way the current URL is determined varies depending on whether you use Rails, Sinatra, etc., this has to be set beforehand in some kind of initializer:
24
+
25
+ ```ruby
26
+ # For Rails >= 3.2
27
+ BootstrapNavbar.current_url_method = 'request.original_url'
28
+ ```
29
+
30
+ `current_url_method` should be set to a string which can be `eval`ed later.
31
+
32
+ ### Set up HTML escaping (optional)
33
+
34
+ If the framework or rendering engine that you use BootstrapNavbar with escapes HTML by default, you can instruct BootstrapNavbar to mark the returned HTML as html_safe by default by overriding `BootstrapNavbar#prepare_html`:
35
+
36
+ ```ruby
37
+ # For Rails
38
+ module BootstrapNavbar::Helpers
39
+ def prepare_html(html)
40
+ html.html_safe
41
+ end
42
+ end
43
+ ```
44
+
45
+ ### Mix in the helpers into the rendering engine (required)
46
+
47
+ ```ruby
48
+ # For Rails
49
+ ActionView::Base.send :include, BootstrapNavbar::Helpers
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ Check out the [Twitter Bootstrap docs](http://twitter.github.io/bootstrap/components.html#navbar) for how a navbar can be constructed. All components and options mentioned there should be supported by this gem, so you don't need to write any HTML by hand. If there is something missing or wrong HTML is generated, please [open an issue](https://github.com/krautcomputing/bootstrap-navbar/issues).
55
+
56
+ Let's assume you have mixed in the helper in your rendering engine and use Haml.
57
+
58
+ ### Full example
59
+
60
+ ```ruby
61
+ = nav_bar fixed: :top, responsive: true do
62
+ = brand_link 'My great app'
63
+ = menu_group class: 'foo', id: 'menu' do
64
+ = menu_text 'Pick an option:'
65
+ = menu_item "Home", root_path
66
+ = menu_item "About Us", about_us_path
67
+ = menu_item contact_path do
68
+ = image_tag 'contact.jpg'
69
+ Contact Us!
70
+ = menu_divider
71
+ = drop_down "Stuff" do
72
+ = drop_down_header 'Great stuff!'
73
+ = menu_item "One", one_path
74
+ = menu_item "Two", two_path
75
+ = menu_item "Three", three_path
76
+ - if current_user.admin?
77
+ = drop_down_divider
78
+ = sub_drop_down 'Admin Stuff' do
79
+ = menu_item "Admin Dashboard", admin_path
80
+ = menu_item "Users", admin_users_path
81
+ = menu_group pull: 'right' do
82
+ - if current_user
83
+ = menu_item "Log Out", log_out_path
84
+ - else
85
+ = menu_item "Log In", log_in_path
86
+ ```
87
+
88
+ ### Methods
89
+
90
+ #### nav_bar
91
+
92
+ This method sets up the basic structure of a navbar.
93
+
94
+ ```haml
95
+ = nav_bar
96
+ ```
97
+
98
+ generates:
99
+
100
+ ```html
101
+ <div class="navbar">
102
+ <div class="navbar-inner">
103
+ <div class="container">
104
+ </div>
105
+ </div>
106
+ </div>
107
+ ```
108
+
109
+ The content of the navbar is supplied by the block and the available options:
110
+
111
+ ```haml
112
+ = nav_bar do
113
+ Yay!
114
+ ```
115
+
116
+ generates:
117
+
118
+ ```html
119
+ <div class="navbar">
120
+ <div class="navbar-inner">
121
+ <div class="container">
122
+ Yay!
123
+ </div>
124
+ </div>
125
+ </div>
126
+ ```
127
+
128
+ Options `brand` and `brand_link` autogenerate the brand link:
129
+
130
+ ```haml
131
+ = nav_bar brand: 'My great app', brand_link: '/start'
132
+ ```
133
+
134
+ generates:
135
+
136
+ ```html
137
+ <div class="navbar">
138
+ <div class="navbar-inner">
139
+ <div class="container">
140
+ <a href="/start" class="brand">My great app</a>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ ```
145
+
146
+ If only `brand` is defined, `brand_link` defaults to `/`.
147
+
148
+ Option `responsive` generates a responsive navbar:
149
+
150
+ ```haml
151
+ = nav_bar responsive: true
152
+ ```
153
+
154
+ generates:
155
+
156
+ ```html
157
+ <div class="navbar">
158
+ <div class="navbar-inner">
159
+ <div class="container">
160
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
161
+ <span class='icon-bar'></span>
162
+ <span class='icon-bar'></span>
163
+ <span class='icon-bar'></span>
164
+ </div>
165
+ </div>
166
+ </div>
167
+ ```
168
+
169
+ Option `fluid` changes the grid system to be [fluid](http://twitter.github.io/bootstrap/scaffolding.html#fluidGridSystem):
170
+
171
+ ```haml
172
+ = nav_bar fluid: true
173
+ ```
174
+
175
+ generates:
176
+
177
+ ```html
178
+ <div class="navbar">
179
+ <div class="navbar-inner">
180
+ <div class="container-fluid">
181
+ </div>
182
+ </div>
183
+ </div>
184
+ ```
185
+
186
+ #### brand_link
187
+
188
+ This method generates a menu divider, to be used in a `nav_bar`.
189
+
190
+ ```haml
191
+ = brand_link 'My App', '/home'
192
+ ```
193
+
194
+ generates:
195
+
196
+ ```html
197
+ <a href="/home" class="brand">My App</a>
198
+ ```
199
+
200
+ If the path (`/home` in this case) is not specified, it defaults to `/`.
201
+
202
+ #### menu_text
203
+
204
+ This method generates some menu text, to be used in a `nav_bar`.
205
+
206
+ ```haml
207
+ = menu_text 'Select a option:'
208
+ ```
209
+
210
+ generates:
211
+
212
+ ```html
213
+ <p class="navbar-text">
214
+ Select a option:
215
+ </p>
216
+ ```
217
+
218
+ A option can be supplied to make the text float to the right or left:
219
+
220
+ ```haml
221
+ = menu_text 'Select a option:', :right
222
+ ```
223
+
224
+ generates:
225
+
226
+ ```html
227
+ <p class="navbar-text pull-right">
228
+ Select a option:
229
+ </p>
230
+ ```
231
+
232
+ The content can alternatively be supplied in a block:
233
+
234
+ ```haml
235
+ = menu_text do
236
+ Current country:
237
+ = image_text 'flags/en.jpg'
238
+ ```
239
+
240
+ generates:
241
+
242
+ ```html
243
+ <p class="navbar-text">
244
+ Current country:
245
+ <img src="/images/flags/en.jpg">
246
+ </p>
247
+ ```
248
+
249
+ #### menu_group
250
+
251
+ This method generates a menu group, to be used in a `nav_bar`.
252
+
253
+ ```haml
254
+ = menu_group
255
+ ```
256
+
257
+ generates:
258
+
259
+ ```html
260
+ <ul class="nav">
261
+ </ul>
262
+ ```
263
+
264
+ The content of the menu group is supplied by the blocks:
265
+
266
+ ```haml
267
+ = menu_group do
268
+ Yay!
269
+ ```
270
+
271
+ generates:
272
+
273
+ ```html
274
+ <ul class="nav">
275
+ Yay!
276
+ </ul>
277
+ ```
278
+
279
+ You can add a `pull` option to make the group float to the right or left, and add more classes and other attributes:
280
+
281
+ ```haml
282
+ = menu_group pull: 'right', class: 'large', id: 'menu'
283
+ ```
284
+
285
+ generates:
286
+
287
+ ```html
288
+ <ul class="nav pull-right large" id="menu">
289
+ </ul>
290
+ ```
291
+
292
+ #### menu_item
293
+
294
+ This method generates a menu item, to be used in a `menu_group`.
295
+
296
+ ```haml
297
+ = menu_item 'Home', '/home'
298
+ ```
299
+
300
+ generates:
301
+
302
+ ```html
303
+ <li>
304
+ <a href="/home">
305
+ Home
306
+ </a>
307
+ </li>
308
+ ```
309
+
310
+ If the path (`/home` in this case) is not specified, it defaults to `#`.
311
+
312
+ You can also use a block (e.g., in case the link name is more than a single word):
313
+
314
+ ```haml
315
+ = menu_item /home' do
316
+ = image_tag 'home.png'
317
+ Home
318
+ ```
319
+
320
+ generates:
321
+
322
+ ```html
323
+ <li>
324
+ <a href="/home">
325
+ <img src="/images/home.png">
326
+ Home
327
+ </a>
328
+ </li>
329
+ ```
330
+
331
+ You can add options that will be passed on to the `li` and `a` elements:
332
+
333
+ ```haml
334
+ = menu_item 'Home', '/home', { class: 'list-item' }, { id: 'home' }
335
+ ```
336
+
337
+ generates:
338
+
339
+ ```html
340
+ <li class="list-item">
341
+ <a href="/home" id="home">
342
+ Home
343
+ </a>
344
+ </li>
345
+ ```
346
+
347
+ If the specified path/URL is the [current url](#set-current_url_method-required), it will be marked as `active`. Note that it doesn't matter if you link to a full URL or just the path, or if `BootstrapNavbar.current_url_method` returns a full URL or just the path, it will work regardless.
348
+
349
+ ```haml
350
+ = menu_item 'Home', '/home'
351
+ ```
352
+
353
+ generates:
354
+
355
+ ```html
356
+ <!-- If the current path is /home -->
357
+
358
+ <li class="active">
359
+ <a href="/home">
360
+ Home
361
+ </a>
362
+ </li>
363
+ ```
364
+
365
+ #### menu_divider
366
+
367
+ This method generates a menu divider, to be used in a `menu_group`.
368
+
369
+ ```haml
370
+ = menu_divider
371
+ ```
372
+
373
+ generates:
374
+
375
+ ```html
376
+ <li class="divider-vertical"></li>
377
+ ```
378
+
379
+ #### drop_down
380
+
381
+ This method generates a dropdown, to be used in a `menu_group`.
382
+
383
+ ```haml
384
+ = drop_down 'Settings'
385
+ ```
386
+
387
+ generates:
388
+
389
+ ```html
390
+ <li class="dropdown">
391
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
392
+ Settings <b class="caret"></b>
393
+ </a>
394
+ <ul class="dropdown-menu">
395
+ </ul>
396
+ </li>
397
+ ```
398
+
399
+ The content of the dropdown can be defined in the block using `menu_item`s:
400
+
401
+ ```haml
402
+ = drop_down 'Settings' do
403
+ = menu_item 'Basic', '/settings/basic'
404
+ = menu_item 'Advanced', '/settings/advanced'
405
+ ```
406
+
407
+ generates:
408
+
409
+ ```html
410
+ <li class="dropdown">
411
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
412
+ Settings <b class="caret"></b>
413
+ </a>
414
+ <ul class="dropdown-menu">
415
+ <li>
416
+ <a href="/settings/basic">
417
+ Basic
418
+ </a>
419
+ </li>
420
+ <li>
421
+ <a href="/settings/advanced">
422
+ Advanced
423
+ </a>
424
+ </li>
425
+ </ul>
426
+ </li>
427
+ ```
428
+
429
+ #### sub_drop_down
430
+
431
+ This method generates a sub dropdown, to be used in a `drop_down`.
432
+
433
+ ```haml
434
+ = sub_drop_down 'Admin Settings'
435
+ ```
436
+
437
+ generates:
438
+
439
+ ```html
440
+ <li class="dropdown-submenu">
441
+ <a href="#">
442
+ Admin Settings
443
+ </a>
444
+ <ul class="dropdown-menu">
445
+ </ul>
446
+ </li>
447
+ ```
448
+
449
+ Just like in the `drop_down`, the content of the sub dropdown is defined in the block:
450
+
451
+ ```haml
452
+ = sub_drop_down 'Admin Settings' do
453
+ = menu_item 'Users', '/settings/admin/users'
454
+ = menu_item 'Stats', '/settings/admin/stats'
455
+ ```
456
+
457
+ generates:
458
+
459
+ ```html
460
+ <li class="dropdown-submenu">
461
+ <a href="#">
462
+ Admin Settings
463
+ </a>
464
+ <ul class="dropdown-menu">
465
+ <li>
466
+ <a href="/settings/admin/users">
467
+ Users
468
+ </a>
469
+ </li>
470
+ <li>
471
+ <a href="/settings/admin/stats">
472
+ Stats
473
+ </a>
474
+ </li>
475
+ </ul>
476
+ </li>
477
+ ```
478
+
479
+ #### drop_down_divider
480
+
481
+ This method generates a dropdown divider, to be used in a `drop_down` or `sub_drop_down`.
482
+
483
+ ```haml
484
+ = drop_down_divider
485
+ ```
486
+
487
+ generates:
488
+
489
+ ```html
490
+ <li class="divider"></li>
491
+ ```
492
+
493
+ #### drop_down_header
494
+
495
+ This method generates a dropdown header, to be used in a `drop_down` or `sub_drop_down`.
496
+
497
+ ```haml
498
+ = drop_down_header 'Important!'
499
+ ```
500
+
501
+ generates:
502
+
503
+ ```html
504
+ <li class="nav-header">Important!</li>
505
+ ```
506
+
507
+ ## Contributing
508
+
509
+ 1. Fork it
510
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
511
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
512
+ 4. Push to the branch (`git push origin my-new-feature`)
513
+ 5. Create new Pull Request
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task default: :spec
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'bootstrap-navbar/version'
7
+
8
+ Gem::Specification.new do |gem|
9
+ gem.name = 'bootstrap-navbar'
10
+ gem.version = BootstrapNavbar::VERSION
11
+ gem.platform = Gem::Platform::RUBY
12
+ gem.authors = ['Manuel Meurer']
13
+ gem.email = 'manuel.meurer@gmail.com'
14
+ gem.summary = 'Helpers to generate a Twitter Bootstrap style navbar'
15
+ gem.description = 'Helpers to generate a Twitter Bootstrap style navbar'
16
+ gem.homepage = 'https://github.com/krautcomputing/bootstrap-navbar'
17
+ gem.license = 'MIT'
18
+
19
+ gem.files = `git ls-files`.split($/)
20
+ gem.executables = gem.files.grep(%r(^bin/)).map { |f| File.basename(f) }
21
+ gem.test_files = gem.files.grep(%r(^(test|spec|features)/))
22
+ gem.require_paths = ['lib']
23
+
24
+ gem.add_development_dependency 'rake', '>= 10.0.0'
25
+ gem.add_development_dependency 'rspec', '~> 2.13.0'
26
+ gem.add_development_dependency 'rspec-html-matchers', '~> 0.4.3'
27
+ gem.add_development_dependency 'guard-rspec', '~> 3.0'
28
+ gem.add_development_dependency 'padrino-helpers', '~> 0.11.2'
29
+ end
@@ -0,0 +1,13 @@
1
+ require 'bootstrap-navbar/version'
2
+
3
+ module BootstrapNavbar
4
+ def self.current_url_method=(value)
5
+ @current_url_method = value
6
+ end
7
+
8
+ def self.current_url_method
9
+ @current_url_method
10
+ end
11
+ end
12
+
13
+ require 'bootstrap-navbar/helpers'
@@ -0,0 +1,201 @@
1
+ require 'uri'
2
+
3
+ module BootstrapNavbar::Helpers
4
+ def nav_bar(options = {}, &block)
5
+ nav_bar_div options do
6
+ navbar_inner_div do
7
+ container_div options[:brand], options[:brand_link], options[:responsive], options[:fluid], &block
8
+ end
9
+ end
10
+ end
11
+
12
+ def menu_group(options = {}, &block)
13
+ css_classes = %w(nav).tap do |css_classes|
14
+ css_classes << "pull-#{options.delete(:pull)}" if options.has_key?(:pull)
15
+ css_classes << options.delete(:class) if options.has_key?(:class)
16
+ end
17
+ attributes = attribute_hash_to_string({ class: css_classes.join(' ') }.merge(options))
18
+ prepare_html <<-HTML.chomp!
19
+ <ul#{with_preceding_space attributes}>
20
+ #{capture(&block) if block_given?}
21
+ </ul>
22
+ HTML
23
+ end
24
+
25
+ def menu_item(name = nil, path = nil, list_item_options = nil, link_options = nil, &block)
26
+ name, path, list_item_options, link_options = capture(&block), name, path, list_item_options if block_given?
27
+ path ||= '#'
28
+ list_item_options ||= {}
29
+ link_options ||= {}
30
+
31
+ list_item_css_classes = [].tap do |css_classes|
32
+ css_classes << 'active' if current_url?(path)
33
+ css_classes << list_item_options.delete(:class) if list_item_options.has_key?(:class)
34
+ end
35
+ list_item_attributes = attribute_hash_to_string(
36
+ { class: list_item_css_classes.join(' ') }
37
+ .delete_if { |k, v| v.empty? }
38
+ .merge(list_item_options)
39
+ )
40
+ link_attributes = attribute_hash_to_string(link_options)
41
+ prepare_html <<-HTML.chomp!
42
+ <li#{with_preceding_space list_item_attributes}>
43
+ <a href="#{path}"#{with_preceding_space link_attributes}>
44
+ #{name}
45
+ </a>
46
+ </li>
47
+ HTML
48
+ end
49
+
50
+ def drop_down(name, &block)
51
+ prepare_html <<-HTML.chomp!
52
+ <li class="dropdown">
53
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
54
+ #{name} <b class="caret"></b>
55
+ </a>
56
+ #{drop_down_menu(&block)}
57
+ </li>
58
+ HTML
59
+ end
60
+
61
+ def sub_drop_down(name, list_item_options = {}, link_options = {}, &block)
62
+ list_item_css_classes = %w(dropdown-submenu).tap do |css_classes|
63
+ css_classes << list_item_options.delete(:class) if list_item_options.has_key?(:class)
64
+ end
65
+ list_item_attributes = attribute_hash_to_string({ class: list_item_css_classes.join(' ') }.merge(list_item_options))
66
+ link_attributes = attribute_hash_to_string(link_options)
67
+ prepare_html <<-HTML.chomp!
68
+ <li#{with_preceding_space list_item_attributes}>
69
+ <a href="#"#{with_preceding_space link_attributes}>
70
+ #{name}
71
+ </a>
72
+ #{drop_down_menu(&block)}
73
+ </li>
74
+ HTML
75
+ end
76
+
77
+ def drop_down_divider
78
+ prepare_html %(<li class="divider"></li>)
79
+ end
80
+
81
+ def drop_down_header(text)
82
+ prepare_html %(<li class="nav-header">#{text}</li>)
83
+ end
84
+
85
+ def menu_divider
86
+ prepare_html %(<li class="divider-vertical"></li>)
87
+ end
88
+
89
+ def menu_text(text = nil, pull = nil, &block)
90
+ css_classes = %w(navbar-text).tap do |css_classes|
91
+ css_classes << "pull-#{pull}" if pull
92
+ end
93
+ prepare_html <<-HTML.chomp!
94
+ <p class="#{css_classes.join(' ')}">
95
+ #{block_given? ? capture(&block) : text}
96
+ </p>
97
+ HTML
98
+ end
99
+
100
+ def brand_link(name, url = nil)
101
+ prepare_html %(<a href="#{url || '/'}" class="brand">#{name}</a>)
102
+ end
103
+
104
+ private
105
+
106
+ def nav_bar_div(options, &block)
107
+ position = case
108
+ when options.has_key?(:static)
109
+ "static-#{options[:static]}"
110
+ when options.has_key?(:fixed)
111
+ "fixed-#{options[:fixed]}"
112
+ end
113
+
114
+ css_classes = %w(navbar).tap do |css_classes|
115
+ css_classes << "navbar-#{position}" if position
116
+ css_classes << 'navbar-inverse' if options[:inverse]
117
+ end
118
+
119
+ prepare_html <<-HTML.chomp!
120
+ <div class="#{css_classes.join(' ')}">
121
+ #{capture(&block) if block_given?}
122
+ </div>
123
+ HTML
124
+ end
125
+
126
+ def navbar_inner_div(&block)
127
+ prepare_html <<-HTML.chomp!
128
+ <div class="navbar-inner">
129
+ #{capture(&block) if block_given?}
130
+ </div>
131
+ HTML
132
+ end
133
+
134
+ def container_div(brand, brand_link, responsive, fluid, &block)
135
+ css_class = fluid ? 'container-fluid' : 'container'
136
+ content = [].tap do |content|
137
+ content << responsive_button if responsive
138
+ content << brand_link(brand, brand_link) if brand || brand_link
139
+ content << if responsive
140
+ responsive_wrapper(&block)
141
+ else
142
+ capture(&block) if block_given?
143
+ end
144
+ end
145
+ prepare_html <<-HTML.chomp!
146
+ <div class="#{css_class}">
147
+ #{content.join("\n")}
148
+ </div>
149
+ HTML
150
+ end
151
+
152
+ def responsive_wrapper(&block)
153
+ prepare_html <<-HTML.chomp!
154
+ <div class="nav-collapse collapse">
155
+ #{capture(&block) if block_given?}
156
+ </div>
157
+ HTML
158
+ end
159
+
160
+ def responsive_button
161
+ prepare_html <<-HTML.chomp!
162
+ <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
163
+ <span class='icon-bar'></span>
164
+ <span class='icon-bar'></span>
165
+ <span class='icon-bar'></span>
166
+ </a>
167
+ HTML
168
+ end
169
+
170
+ def drop_down_menu(&block)
171
+ prepare_html <<-HTML.chomp!
172
+ <ul class="dropdown-menu">
173
+ #{capture(&block) if block_given?}
174
+ </ul>
175
+ HTML
176
+ end
177
+
178
+ def with_preceding_space(attributes)
179
+ ' ' << attributes unless [nil, ''].include?(attributes)
180
+ end
181
+
182
+ def attribute_hash_to_string(hash)
183
+ hash.map { |k, v| %(#{k}="#{v}") }.join(' ')
184
+ end
185
+
186
+ def current_url?(url)
187
+ normalized_path, normalized_current_path = [url, current_url].map do |url|
188
+ URI.parse(url).path.sub(%r(/\z), '') rescue nil
189
+ end
190
+ normalized_path == normalized_current_path
191
+ end
192
+
193
+ def current_url
194
+ raise StandardError, 'current_url_method is not defined.' if BootstrapNavbar.current_url_method.nil?
195
+ eval BootstrapNavbar.current_url_method
196
+ end
197
+
198
+ def prepare_html(html)
199
+ html
200
+ end
201
+ end
@@ -0,0 +1,3 @@
1
+ module BootstrapNavbar
2
+ VERSION = '0.0.13'
3
+ end
@@ -0,0 +1,353 @@
1
+ require 'spec_helper'
2
+ require 'padrino-helpers'
3
+
4
+ shared_examples 'active menu item' do
5
+ it 'generates the correct HTML' do
6
+ paths_and_urls.each do |current_path_or_url|
7
+ paths_and_urls.each do |menu_path_or_url|
8
+ BootstrapNavbar.current_url_method = "'#{current_path_or_url}'"
9
+ subject.menu_item('foo', menu_path_or_url).should have_tag(:li, with: { class: 'active' })
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ describe BootstrapNavbar::Helpers do
16
+ subject do
17
+ Class.new do
18
+ include Padrino::Helpers::OutputHelpers
19
+ include BootstrapNavbar::Helpers
20
+ end.new
21
+ end
22
+
23
+ before do
24
+ BootstrapNavbar.current_url_method = ''
25
+ end
26
+
27
+ describe '#nav_bar' do
28
+ context 'without parameters' do
29
+ it 'generates the correct HTML' do
30
+ subject.nav_bar.should have_tag(:div, with: { class: 'navbar' }) do
31
+ with_tag :div, with: { class: 'navbar-inner' } do
32
+ with_tag :div, with: { class: 'container' }
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'with a block' do
39
+ it 'generates the correct HTML' do
40
+ subject.nav_bar { 'foo' }.should have_tag(:div, with: { class: 'navbar' }, content: 'foo')
41
+ end
42
+ end
43
+
44
+ context 'with "static" parameter' do
45
+ it 'generates the correct HTML' do
46
+ subject.nav_bar(static: 'top').should have_tag(:div, with: { class: 'navbar navbar-static-top' })
47
+ subject.nav_bar(static: 'bottom').should have_tag(:div, with: { class: 'navbar navbar-static-bottom' })
48
+ end
49
+ end
50
+
51
+ context 'with "fixed" parameter' do
52
+ it 'generates the correct HTML' do
53
+ subject.nav_bar(fixed: 'top').should have_tag(:div, with: { class: 'navbar navbar-fixed-top' })
54
+ subject.nav_bar(fixed: 'bottom').should have_tag(:div, with: { class: 'navbar navbar-fixed-bottom' })
55
+ end
56
+ end
57
+
58
+ context 'with "inverse" parameter' do
59
+ it 'generates the correct HTML' do
60
+ subject.nav_bar(inverse: true).should have_tag(:div, with: { class: 'navbar navbar-inverse' })
61
+ end
62
+ end
63
+
64
+ context 'with "brand" and "brank_link" parameters' do
65
+ it 'generates the correct HTML' do
66
+ subject.nav_bar(brand: 'foo').should have_tag(:a, with: { href: '/', class: 'brand' }, content: 'foo')
67
+ subject.nav_bar(brand: 'foo', brand_link: 'http://google.com').should have_tag(:a, with: { href: 'http://google.com', class: 'brand' }, content: 'foo')
68
+ subject.nav_bar(brand_link: 'http://google.com').should have_tag(:a, with: { href: 'http://google.com', class: 'brand' })
69
+ end
70
+ end
71
+
72
+ context 'with "responsive" parameter' do
73
+ it 'generates the correct HTML' do
74
+ subject.nav_bar(responsive: true).should have_tag(:a, with: { class: 'btn btn-navbar', :'data-toggle' => 'collapse', :'data-target' => '.nav-collapse' }) do
75
+ 3.times do
76
+ with_tag :span, with: { class: 'icon-bar' }
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'with "fluid" parameter' do
83
+ it 'generates the correct HTML' do
84
+ subject.nav_bar(fluid: true).should have_tag(:div, with: { class: 'container-fluid' })
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '#menu_group' do
90
+ context 'without parameters' do
91
+ it 'generates the correct HTML' do
92
+ subject.menu_group.should have_tag(:ul, with: { class: 'nav' })
93
+ subject.menu_group { 'foo' }.should have_tag(:ul, with: { class: 'nav' }, content: 'foo')
94
+ end
95
+ end
96
+
97
+ context 'with "pull" parameter' do
98
+ it 'generates the correct HTML' do
99
+ subject.menu_group(pull: 'right').should have_tag(:ul, with: { class: 'nav pull-right' })
100
+ end
101
+ end
102
+
103
+ context 'with "class" parameter' do
104
+ it 'generates the correct HTML' do
105
+ subject.menu_group(class: 'foo').should have_tag(:ul, with: { class: 'nav foo' })
106
+ end
107
+ end
108
+
109
+ context 'with random parameters' do
110
+ it 'generates the correct HTML' do
111
+ subject.menu_group(:'data-foo' => 'bar').should have_tag(:ul, with: { class: 'nav', :'data-foo' => 'bar' })
112
+ end
113
+ end
114
+
115
+ context 'with many parameters' do
116
+ it 'generates the correct HTML' do
117
+ subject.menu_group(pull: 'right', class: 'foo', :'data-foo' => 'bar').should have_tag(:ul, with: { class: 'nav foo pull-right', :'data-foo' => 'bar' })
118
+ end
119
+ end
120
+ end
121
+
122
+ describe '#menu_item' do
123
+ context 'with current URL or path' do
124
+ # With root URL or path
125
+ it_behaves_like 'active menu item' do
126
+ let(:paths_and_urls) do
127
+ %w(
128
+ http://www.foobar.com/
129
+ http://www.foobar.com
130
+ /
131
+ http://www.foobar.com/?foo=bar
132
+ http://www.foobar.com?foo=bar
133
+ /?foo=bar
134
+ http://www.foobar.com/#foo
135
+ http://www.foobar.com#foo
136
+ /#foo
137
+ http://www.foobar.com/#foo?foo=bar
138
+ http://www.foobar.com#foo?foo=bar
139
+ /#foo?foo=bar
140
+ )
141
+ end
142
+ end
143
+
144
+ # With sub URL or path
145
+ it_behaves_like 'active menu item' do
146
+ let(:paths_and_urls) do
147
+ %w(
148
+ http://www.foobar.com/foo
149
+ http://www.foobar.com/foo/
150
+ /foo
151
+ /foo/
152
+ http://www.foobar.com/foo?foo=bar
153
+ http://www.foobar.com/foo/?foo=bar
154
+ /foo?foo=bar
155
+ /foo/?foo=bar
156
+ http://www.foobar.com/foo#foo
157
+ http://www.foobar.com/foo/#foo
158
+ /foo#foo
159
+ /foo/#foo
160
+ http://www.foobar.com/foo#foo?foo=bar
161
+ http://www.foobar.com/foo/#foo?foo=bar
162
+ /foo#foo?foo=bar
163
+ /foo/#foo?foo=bar
164
+ )
165
+ end
166
+ end
167
+
168
+ context 'with list item options' do
169
+ it 'generates the correct HTML' do
170
+ BootstrapNavbar.current_url_method = '"/"'
171
+ subject.menu_item('foo', '/', class: 'bar', id: 'baz').should have_tag(:li, with: { class: 'active bar', id: 'baz' })
172
+ end
173
+ end
174
+
175
+ context 'with link options' do
176
+ it 'generates the correct HTML' do
177
+ BootstrapNavbar.current_url_method = '"/"'
178
+ subject.menu_item('foo', '/', {}, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'active' }) do
179
+ with_tag :a, with: { href: '/', class: 'pelle', id: 'fant' }, content: 'foo'
180
+ end
181
+ end
182
+ end
183
+
184
+ context 'with list item options and link options' do
185
+ it 'generates the correct HTML' do
186
+ BootstrapNavbar.current_url_method = '"/"'
187
+ subject.menu_item('foo', '/', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'active bar', id: 'baz' }) do
188
+ with_tag :a, with: { href: '/', class: 'pelle', id: 'fant' }, content: 'foo'
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ context 'without current URL' do
195
+ it 'generates the correct HTML' do
196
+ BootstrapNavbar.current_url_method = '"/foo"'
197
+ subject.menu_item('foo').should have_tag(:li, without: { class: 'active' }) do
198
+ with_tag :a, with: { href: '#' }, content: 'foo'
199
+ end
200
+ subject.menu_item('foo', '/').should have_tag(:li, without: { class: 'active' }) do
201
+ with_tag :a, with: { href: '/' }, content: 'foo'
202
+ end
203
+ subject.menu_item('foo', '/bar').should have_tag(:li, without: { class: 'active' }) do
204
+ with_tag :a, with: { href: '/bar' }, content: 'foo'
205
+ end
206
+
207
+ BootstrapNavbar.current_url_method = '"/"'
208
+ subject.menu_item('foo', '/foo').should have_tag(:li, without: { class: 'active' }) do
209
+ with_tag :a, with: { href: '/foo' }, content: 'foo'
210
+ end
211
+ end
212
+
213
+ context 'with list item options' do
214
+ it 'generates the correct HTML' do
215
+ BootstrapNavbar.current_url_method = '"/foo"'
216
+ subject.menu_item('foo', '/', class: 'bar', id: 'baz').should have_tag(:li, without: { class: 'active' }, with: { class: 'bar', id: 'baz' })
217
+ end
218
+ end
219
+ end
220
+
221
+ context 'with a block' do
222
+ it 'generates the correct HTML' do
223
+ subject.menu_item { 'bar' }.should have_tag(:li) do
224
+ with_tag :a, with: { href: '#' }, content: 'bar'
225
+ end
226
+ end
227
+
228
+ context 'with list item options' do
229
+ it 'generates the correct HTML' do
230
+ subject.menu_item('/foo', class: 'pelle', id: 'fant') { 'bar' }.should have_tag(:li, with: { class: 'pelle', id: 'fant' }) do
231
+ with_tag :a, with: { href: '/foo' }, content: 'bar'
232
+ end
233
+ end
234
+ end
235
+
236
+ context 'with link options' do
237
+ it 'generates the correct HTML' do
238
+ subject.menu_item('/foo', {}, class: 'pelle', id: 'fant') { 'bar' }.should have_tag(:li) do
239
+ with_tag :a, with: { href: '/foo', class: 'pelle', id: 'fant' }, content: 'bar'
240
+ end
241
+ end
242
+ end
243
+
244
+ context 'with list item options and link options' do
245
+ it 'generates the correct HTML' do
246
+ subject.menu_item('/foo', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant') { 'shnoo' }.should have_tag(:li, with: { class: 'bar', id: 'baz' }) do
247
+ with_tag :a, with: { href: '/foo', class: 'pelle', id: 'fant' }, content: 'shnoo'
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ context 'drop downs' do
255
+ def with_drop_down_menu(content = nil)
256
+ options = { with: { class: 'dropdown-menu' } }
257
+ options[:content] = content unless content.nil?
258
+ with_tag :ul, options
259
+ end
260
+
261
+ describe '#drop_down' do
262
+ it 'generates the correct HTML' do
263
+ subject.drop_down('foo').should have_tag(:li, with: { class: 'dropdown' }) do
264
+ with_tag :a, with: { href: '#', class: 'dropdown-toggle', :'data-toggle' => 'dropdown' } do
265
+ with_text /foo/
266
+ with_tag :b, with: { class: 'caret' }
267
+ end
268
+ with_drop_down_menu
269
+ end
270
+
271
+ subject.drop_down('foo') { 'bar' }.should have_tag(:li, with: { class: 'dropdown' }) do
272
+ with_tag :a, with: { href: '#', class: 'dropdown-toggle', :'data-toggle' => 'dropdown' } do
273
+ with_text /foo/
274
+ with_tag :b, with: { class: 'caret' }
275
+ end
276
+ with_drop_down_menu('bar')
277
+ end
278
+ end
279
+ end
280
+
281
+ describe '#sub_drop_down' do
282
+ it 'generates the correct HTML' do
283
+ subject.sub_drop_down('foo').should have_tag(:li, with: { class: 'dropdown-submenu' }) do
284
+ with_tag :a, with: { href: '#' }, content: 'foo'
285
+ with_drop_down_menu
286
+ end
287
+
288
+ subject.sub_drop_down('foo') { 'bar' }.should have_tag(:li, with: { class: 'dropdown-submenu' }) do
289
+ with_tag :a, with: { href: '#' }, content: 'foo'
290
+ with_drop_down_menu('bar')
291
+ end
292
+ end
293
+
294
+ context 'with list item options' do
295
+ it 'generates the correct HTML' do
296
+ subject.sub_drop_down('foo', class: 'bar', id: 'baz').should have_tag(:li, with: { class: 'dropdown-submenu bar', id: 'baz' }) do
297
+ with_tag :a, with: { href: '#' }, content: 'foo'
298
+ end
299
+ end
300
+ end
301
+
302
+ context 'with link options' do
303
+ it 'generates the correct HTML' do
304
+ subject.sub_drop_down('foo', {}, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'dropdown-submenu' }) do
305
+ with_tag :a, with: { href: '#', class: 'pelle', id: 'fant' }, content: 'foo'
306
+ end
307
+ end
308
+ end
309
+
310
+ context 'with list item options and link options' do
311
+ it 'generates the correct HTML' do
312
+ subject.sub_drop_down('foo', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant').should have_tag(:li, with: { class: 'dropdown-submenu bar', id: 'baz' }) do
313
+ with_tag :a, with: { href: '#', class: 'pelle', id: 'fant' }, content: 'foo'
314
+ end
315
+ end
316
+ end
317
+ end
318
+ end
319
+
320
+ describe '#drop_down_divider' do
321
+ it 'generates the correct HTML' do
322
+ subject.drop_down_divider.should have_tag(:li, with: { class: 'divider' }, content: '')
323
+ end
324
+ end
325
+
326
+ describe '#drop_down_header' do
327
+ it 'generates the correct HTML' do
328
+ subject.drop_down_header('foo').should have_tag(:li, with: { class: 'nav-header' }, content: 'foo')
329
+ end
330
+ end
331
+
332
+ describe '#menu_divider' do
333
+ it 'generates the correct HTML' do
334
+ subject.menu_divider.should have_tag(:li, with: { class: 'divider-vertical' }, content: '')
335
+ end
336
+ end
337
+
338
+ describe '#menu_text' do
339
+ it 'generates the correct HTML' do
340
+ subject.menu_text('foo').should have_tag(:p, with: { class: 'navbar-text' }, content: 'foo')
341
+ subject.menu_text { 'foo' }.should have_tag(:p, with: { class: 'navbar-text' }, content: 'foo')
342
+ subject.menu_text('foo', 'right').should have_tag(:p, with: { class: 'navbar-text pull-right' }, content: 'foo')
343
+ subject.menu_text(nil, 'left') { 'foo' }.should have_tag(:p, with: { class: 'navbar-text pull-left' }, content: 'foo')
344
+ end
345
+ end
346
+
347
+ describe '#brand_link' do
348
+ it 'generates the correct HTML' do
349
+ subject.brand_link('foo').should have_tag(:a, with: { class: 'brand', href: '/' }, content: 'foo')
350
+ subject.brand_link('foo', '/foo').should have_tag(:a, with: { class: 'brand', href: '/foo' }, content: 'foo')
351
+ end
352
+ end
353
+ end
@@ -0,0 +1,10 @@
1
+ require 'bootstrap-navbar'
2
+ require 'rspec-html-matchers'
3
+
4
+ RSpec.configure do |config|
5
+ config.treat_symbols_as_metadata_keys_with_true_values = true
6
+ config.run_all_when_everything_filtered = true
7
+ config.filter_run :focus
8
+
9
+ config.order = 'random'
10
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bootstrap-navbar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.13
5
+ platform: ruby
6
+ authors:
7
+ - Manuel Meurer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 10.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 10.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.13.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 2.13.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-html-matchers
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.4.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: padrino-helpers
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 0.11.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 0.11.2
83
+ description: Helpers to generate a Twitter Bootstrap style navbar
84
+ email: manuel.meurer@gmail.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - .travis.yml
90
+ - Gemfile
91
+ - Guardfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - bootstrap-navbar.gemspec
96
+ - lib/bootstrap-navbar.rb
97
+ - lib/bootstrap-navbar/helpers.rb
98
+ - lib/bootstrap-navbar/version.rb
99
+ - spec/bootstrap_navbar/helpers_spec.rb
100
+ - spec/spec_helper.rb
101
+ homepage: https://github.com/krautcomputing/bootstrap-navbar
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.0.2
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Helpers to generate a Twitter Bootstrap style navbar
125
+ test_files:
126
+ - spec/bootstrap_navbar/helpers_spec.rb
127
+ - spec/spec_helper.rb
128
+ has_rdoc: