semantic_navigation 0.0.13 → 0.0.14

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.
Files changed (32) hide show
  1. data/.travis.yml +7 -0
  2. data/Changelog.md +7 -0
  3. data/README.md +25 -8
  4. data/Rakefile +2 -0
  5. data/gemfiles/rails3 +7 -0
  6. data/lib/generators/semantic_navigation/install/templates/semantic_navigation.rb +6 -2
  7. data/lib/semantic_navigation/configuration.rb +5 -0
  8. data/lib/semantic_navigation/core/base.rb +2 -2
  9. data/lib/semantic_navigation/core/leaf.rb +28 -10
  10. data/lib/semantic_navigation/core/navigation.rb +11 -4
  11. data/lib/semantic_navigation/core/node.rb +24 -12
  12. data/lib/semantic_navigation/helper_methods.rb +3 -1
  13. data/lib/semantic_navigation/renderers/bread_crumb.rb +3 -3
  14. data/lib/semantic_navigation/renderers/list.rb +2 -2
  15. data/lib/semantic_navigation/renderers/render_helpers.rb +6 -2
  16. data/lib/semantic_navigation/twitter_bootstrap/breadcrumb.rb +4 -4
  17. data/lib/semantic_navigation/twitter_bootstrap/list.rb +6 -6
  18. data/lib/semantic_navigation/twitter_bootstrap/tabs.rb +3 -3
  19. data/lib/semantic_navigation/version.rb +1 -1
  20. data/spec/lib/semantic_navigation/configuration_spec.rb +153 -0
  21. data/spec/lib/semantic_navigation/core/leaf_spec.rb +50 -0
  22. data/spec/lib/semantic_navigation/core/navigation_spec.rb +35 -0
  23. data/spec/lib/semantic_navigation/core/node_spec.rb +25 -0
  24. data/spec/lib/semantic_navigation/helper_methods_spec.rb +82 -0
  25. data/spec/lib/semantic_navigation/renderers/bread_crumb_spec.rb +203 -0
  26. data/spec/lib/semantic_navigation/renderers/list_spec.rb +241 -0
  27. data/spec/lib/semantic_navigation/twitter_bootstrap/breadcrumb_spec.rb +202 -0
  28. data/spec/lib/semantic_navigation/twitter_bootstrap/list_spec.rb +316 -0
  29. data/spec/lib/semantic_navigation/twitter_bootstrap/tabs_spec.rb +310 -0
  30. data/spec/spec_helper.rb +1 -0
  31. metadata +15 -9
  32. data/spec/lib/semantic_navigation/core/base_spec.rb +0 -1
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - ruby-head
6
+ gemfile:
7
+ - gemfiles/rails3
data/Changelog.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### 0.0.14
2
+ * Now in render_if proc there is possibility to catch self(rendering element)
3
+ * Items accept procs for links definitions
4
+ * Fixed bug in active_item_for method
5
+ * active_item_for now returns empty string instead of nil then no active items
6
+ * added multiname support for items
7
+
1
8
  ### 0.0.13 / August 14, 2012
2
9
 
3
10
  * Bugfixes for support array of route like links
data/README.md CHANGED
@@ -1,13 +1,20 @@
1
1
  This is semantic_navigation gem
2
2
 
3
3
  ###Purpose
4
- This gem generates the navigation for your Rails app.
5
- Really customizable and simple to use.
6
- Using this gem you have 4 types of renderers: menu, breadcrumb, tabs, and, pills
4
+ Forget fat layouts, views and controllers. This gem will do all the menu staff for you.
5
+ You simply just have to generate configuration file, fill it with your menu hierarchy and renderer it wherever you want.
7
6
 
8
- You can define different menus and render them separate.
7
+ Symply and customizable it will make for you all the routings you were spending a lot of time before.
9
8
 
10
- Now with simple integration with a twitter-bootstrap CSS framework.
9
+ * semantic_navigation supports defining as many separate menus as you want and they can be as deep as you need.
10
+ * supports different styles of url definitions ('route#like', :symbols, 'strings', {hash: 'like'})
11
+ * supports and array of urls for one item
12
+ * supports procs for item name definitions - so you can have dynamic names
13
+ * supports render conditions defined as proc where you have access to controller class variables, request params and even to the rendering item
14
+ * supports multiname definitions where you can set the custom name for each renderer.
15
+ * has renderers compatible with bootstrap - so if you using bootstrap it will be simplier
16
+ * supports controller default styles overriding both - from configuration and view file
17
+ * supports custom renderers
11
18
 
12
19
  ###How to install
13
20
 
@@ -33,9 +40,9 @@ Configure your navigation in config/semantic_navigation.rb
33
40
  <pre><code>
34
41
  SemanticNavigation::Configuration.run do
35
42
  navigate :root_menu do
36
- item :header_item, nil, :name => 'Header'
43
+ header :header_item, :name => 'Header'
37
44
  item :first_item, '#', :name => 'First Item', :ico => :tag
38
- item :divide
45
+ divider
39
46
  item :second_item, '#', :name => 'Second Item', :ico => :user
40
47
  end
41
48
  end
@@ -46,7 +53,17 @@ And try to render it in your layout(code in haml):
46
53
  .well
47
54
  = navigation_for :root_menu, :as => :bootstrap_list
48
55
  </code></pre>
56
+ or
57
+ <pre><code>
58
+ .well
59
+ = bootstrap_list_for :root_menu
60
+ </code></pre>
49
61
 
50
62
  Render the navigation using the semantic_navigation helper methods and options for them.
51
63
 
52
- For the information of how to configure and render your navigation read the <a href='https://github.com/fr33z3/semantic_navigation/wiki'>Wiki</a>
64
+ For the information of how to configure and render your navigation read the <a href='https://github.com/fr33z3/semantic_navigation/wiki'>Wiki</a>
65
+
66
+ Dependence:
67
+
68
+ * Ruby >= 1.9.2
69
+ * Rails >= 3.0.0
data/Rakefile CHANGED
@@ -2,3 +2,5 @@ require 'rspec/core/rake_task'
2
2
  require "bundler/gem_tasks"
3
3
 
4
4
  RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
data/gemfiles/rails3 ADDED
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+
3
+ gem 'semantic_navigation', :path => '..'
4
+ gem 'rails', '>=3.1.0'
5
+ gem 'rspec'
6
+ gem 'rake'
7
+ gem 'simplecov'
@@ -1,23 +1,27 @@
1
+ #encoding: utf-8
1
2
  SemanticNavigation::Configuration.run do
2
3
  # Read wiki https://github.com/fr33z3/semantic_navigation/wiki to lear about
3
4
  # semantic_navigation configuration
4
5
 
6
+ #Override renderer default styles:
5
7
  #styles_for :list do
6
8
  # show_navigation_active_class true
7
9
  # navigation_active_class [:some_active_class]
8
10
  #end
9
11
 
12
+ # You can register your custom renderer:
10
13
  #register_renderer :some_renderer, SomeRendererClass
11
14
 
15
+ # The example of the navigation:
12
16
  #navigate :navigation do
13
- # item :header_item, :name => 'Header Item'
17
+ # header :header_item, :name => 'Header Item'
14
18
  # item :first_item, :first_item_route, :ico => 'user' do
15
19
  # item :sub_item, :sub_item_route do
16
20
  # item :sub_sub_item, :sub_sub_item_route
17
21
  # end
18
22
  # item :second_sub, :second_sub_route, :ico => 'user'
19
23
  # end
20
- # item :divide
24
+ # divider
21
25
  # item :second_item, :second_item_route
22
26
  #end
23
27
 
@@ -25,6 +25,7 @@ module SemanticNavigation
25
25
  renderer.instance_eval &@@render_styles[renderer_name]
26
26
  end
27
27
  options.keys.each{|key| renderer.send "#{key}=", options[key]}
28
+ renderer.name = renderer_name
28
29
  navigation = @@navigations[menu_id]
29
30
  navigation.mark_active
30
31
  navigation.render(renderer)
@@ -54,6 +55,10 @@ module SemanticNavigation
54
55
  def self.view_object
55
56
  @@view_object
56
57
  end
58
+
59
+ def self.view_object=(view_object)
60
+ @@view_object = view_object
61
+ end
57
62
 
58
63
  def self.navigation(name)
59
64
  @@navigations[name]
@@ -2,11 +2,11 @@ module SemanticNavigation
2
2
  module Core
3
3
  class Base
4
4
 
5
- attr :id, :level, :classes, :active
5
+ attr_accessor :id, :level, :classes, :active
6
6
  attr_writer :render_if
7
7
 
8
8
  def render_if
9
- !@render_if.nil? ? view_object.instance_eval(&@render_if) : true
9
+ !@render_if.nil? ? view_object.instance_exec(self, &@render_if) : true
10
10
  end
11
11
 
12
12
  def initialize(options, level)
@@ -1,32 +1,50 @@
1
1
  module SemanticNavigation
2
2
  module Core
3
3
  class Leaf < Base
4
- attr :link_classes
4
+ attr_accessor :link_classes
5
5
 
6
6
  def url
7
- @url.is_a?(Array) ? @url.first : @url
7
+ urls.first
8
8
  end
9
9
 
10
10
  def initialize(options, level)
11
11
  super options, level
12
12
  end
13
13
 
14
- def name
15
- rendering_name = @name || I18n.t("#{@i18n_name}.#{@id}", :default => '')
16
- if rendering_name.is_a?(Proc)
17
- view_object.instance_eval(&rendering_name).to_s
18
- else
19
- rendering_name
20
- end
14
+ def name(renderer_name = nil)
15
+ rendering_name = @name
16
+ rendering_name = rendering_name[renderer_name.to_sym] || rendering_name[:default] if rendering_name.is_a?(Hash)
17
+ rendering_name = view_object.instance_eval(&rendering_name).to_s if rendering_name.is_a?(Proc)
18
+ rendering_name || i18n_name(renderer_name)
21
19
  end
22
20
 
23
21
  def mark_active
24
22
  if @url
25
- @active = [@url].flatten(1).map{|u| current_page?(u) rescue false}.reduce(:"|")
23
+ @active = urls.map{|u| current_page?(u) rescue false}.reduce(:"|")
26
24
  else
27
25
  @active = false
28
26
  end
29
27
  end
28
+
29
+ private
30
+
31
+ def i18n_name(renderer_name = nil)
32
+ name = I18n.t("#{@i18n_name}.#{@id}", :default => '')
33
+ if name.is_a? Hash
34
+ name = name[renderer_name.to_sym] || name[:default]
35
+ end
36
+ name || ''
37
+ end
38
+
39
+ def urls
40
+ [@url].flatten(1).map do |url|
41
+ if url.is_a?(Proc)
42
+ view_object.instance_eval(&url) rescue ''
43
+ else
44
+ url
45
+ end
46
+ end
47
+ end
30
48
 
31
49
  end
32
50
  end
@@ -1,7 +1,7 @@
1
1
  module SemanticNavigation
2
2
  module Core
3
3
  class Navigation < Base
4
- attr :sub_elements
4
+ attr_accessor :sub_elements
5
5
 
6
6
  def initialize(options, level = 0)
7
7
  @sub_elements = []
@@ -24,6 +24,13 @@ module SemanticNavigation
24
24
  element.instance_eval &block
25
25
  else
26
26
  element = Leaf.new(options, @level+1)
27
+ #Deprecation warning message
28
+ #TODO:Should be deleted after moving the header and divider definition via item
29
+ if element.url.nil? && !element.name.empty?
30
+ puts 'Warning: do not define `headers` using `item` method. Use `header` instead. This logic will be deprecated soon.'
31
+ elsif element.url.nil? && element.name.empty?
32
+ puts 'Warning: do not define `dividers` using `item` method. Use `divider` instead. This logic will be deprecated soon.'
33
+ end
27
34
  end
28
35
 
29
36
  @sub_elements.push element
@@ -64,10 +71,10 @@ module SemanticNavigation
64
71
  if url.is_a? String
65
72
  controller_name, action_name = url.split('#')
66
73
  if controller_name && action_name
67
- url = {:controller => controller_name, :action => action_name}
68
- end
74
+ decoded_url = {:controller => controller_name, :action => action_name}
75
+ end
69
76
  end
70
- url
77
+ decoded_url || url
71
78
  end
72
79
 
73
80
  end
@@ -1,10 +1,10 @@
1
1
  module SemanticNavigation
2
2
  module Core
3
3
  class Node < Navigation
4
- attr :link_classes, :node_classes
4
+ attr_accessor :link_classes, :node_classes
5
5
 
6
6
  def url
7
- @url.is_a?(Array) ? @url.first : @url
7
+ urls.first
8
8
  end
9
9
 
10
10
  def initialize(options, level)
@@ -12,25 +12,37 @@ module SemanticNavigation
12
12
  super options, level
13
13
  end
14
14
 
15
- def name
16
- rendering_name = @name || i18n_name
17
- if rendering_name.is_a?(Proc)
18
- view_object.instance_eval(&rendering_name).to_s
19
- else
20
- rendering_name
21
- end
15
+ def name(renderer_name = nil)
16
+ rendering_name = @name
17
+ rendering_name = rendering_name[renderer_name.to_sym] || rendering_name[:default] if rendering_name.is_a?(Hash)
18
+ rendering_name = view_object.instance_eval(&rendering_name).to_s if rendering_name.is_a?(Proc)
19
+ rendering_name || i18n_name(renderer_name)
22
20
  end
23
21
 
24
22
  def mark_active
25
23
  @sub_elements.each{|element| element.mark_active}
26
- @active = [@url].flatten(1).map{|u| current_page?(u) rescue false}.reduce(:"|")
24
+ @active = urls.map{|u| current_page?(u) rescue false}.reduce(:"|")
27
25
  @active |= !@sub_elements.find{|element| element.active}.nil?
28
26
  end
29
27
 
30
28
  private
31
29
 
32
- def i18n_name
33
- I18n.t("#{@i18n_name}.#{@id}", :default => '')
30
+ def i18n_name(renderer_name = nil)
31
+ name = I18n.t("#{@i18n_name}.#{@id}", :default => '')
32
+ if name.is_a? Hash
33
+ name = name[renderer_name.to_sym] || name[:default]
34
+ end
35
+ name || ''
36
+ end
37
+
38
+ def urls
39
+ [@url].flatten(1).map do |url|
40
+ if url.is_a?(Proc)
41
+ view_object.instance_eval(&url) rescue ''
42
+ else
43
+ url
44
+ end
45
+ end
34
46
  end
35
47
 
36
48
  end
@@ -7,13 +7,15 @@ module SemanticNavigation::HelperMethods
7
7
  end
8
8
 
9
9
  def active_item_for(name, level = nil)
10
+ SemanticNavigation::Configuration.view_object = self
10
11
  navigation = SemanticNavigation::Configuration.navigation(name)
12
+ navigation.mark_active
11
13
  item = navigation
12
14
  while !item.is_a?(SemanticNavigation::Core::Leaf) &&
13
15
  !item.sub_elements.find{|e| e.active}.nil? &&
14
16
  (!level.nil? ? item.level < level : true)
15
17
  item = item.sub_elements.find{|e| e.active}
16
18
  end
17
- item.name if item != navigation
19
+ item != navigation ? item.name(:active_item_for) : ''
18
20
  end
19
21
  end
@@ -25,7 +25,7 @@ module SemanticNavigation
25
25
  def node(object)
26
26
  content_tag(:li, nil, :id => show_id(:leaf, object.id),
27
27
  :class => merge_classes(:leaf, object.active, object.classes)) do
28
- link_to(object.name, object.url, :id => show_id(:link, object.id),
28
+ link_to(object_name(object), object.url, :id => show_id(:link, object.id),
29
29
  :class => merge_classes(:link, object.active, object.link_classes))
30
30
  end +
31
31
  content_tag(:li) do
@@ -38,10 +38,10 @@ module SemanticNavigation
38
38
  content_tag :li, nil, :id => show_id(:leaf, object.id),
39
39
  :class => merge_classes(:leaf, object.active, object.classes) do
40
40
  if last_as_link
41
- link_to object.name, object.url, :id => show_id(:link, object.id),
41
+ link_to object_name(object), object.url, :id => show_id(:link, object.id),
42
42
  :class => merge_classes(:link, object.active, object.link_classes)
43
43
  else
44
- object.name
44
+ object_name(object)
45
45
  end
46
46
  end
47
47
  end
@@ -18,7 +18,7 @@ module SemanticNavigation
18
18
  def node(object)
19
19
  content_tag :li, nil, :id => show_id(:leaf, object.id),
20
20
  :class => merge_classes(:leaf, object.active, object.classes) do
21
- link_to(object.name, object.url, :id => show_id(:link, object.id),
21
+ link_to(object_name(object), object.url, :id => show_id(:link, object.id),
22
22
  :class => merge_classes(:link, object.active, object.link_classes))+
23
23
  yield
24
24
  end
@@ -34,7 +34,7 @@ module SemanticNavigation
34
34
  def leaf(object)
35
35
  content_tag :li, nil, :id => show_id(:leaf, object.id),
36
36
  :class => merge_classes(:leaf, object.active, object.classes) do
37
- link_to object.name, object.url, :id => show_id(:link, object.id),
37
+ link_to object_name(object), object.url, :id => show_id(:link, object.id),
38
38
  :class => merge_classes(:link, object.active, object.link_classes)
39
39
  end
40
40
  end
@@ -29,7 +29,7 @@ module SemanticNavigation
29
29
  end
30
30
 
31
31
  module ClassMethods
32
-
32
+
33
33
  def style_accessor(hash)
34
34
  hash.keys.each do |key|
35
35
  class_eval "
@@ -66,7 +66,7 @@ module SemanticNavigation
66
66
  end
67
67
 
68
68
  module InstanceMethods
69
- attr_accessor :from_level, :until_level, :except_for
69
+ attr_accessor :from_level, :until_level, :except_for, :name
70
70
 
71
71
  def level=(level)
72
72
  @from_level = level
@@ -103,6 +103,10 @@ module SemanticNavigation
103
103
  def show_id(name, id)
104
104
  id if send("show_#{name}_id")
105
105
  end
106
+
107
+ def object_name(object)
108
+ object.name(self.name)
109
+ end
106
110
 
107
111
  end
108
112
 
@@ -33,7 +33,7 @@ module SemanticNavigation
33
33
  content_tag(:li, nil, :id => show_id(:leaf, object.id),
34
34
  :class => merge_classes(:leaf, object.active, object.classes)) do
35
35
  [object.ico ? content_tag(:i,nil,:class => "icon-#{object.ico}") : ''.html_safe,
36
- link_to(object.name, object.url, :id => show_id(:link, object.id),
36
+ link_to(object_name(object), object.url, :id => show_id(:link, object.id),
37
37
  :class => merge_classes(:link, object.active, object.link_classes)),
38
38
  content_tag(:span, nil, :class=> [:divider]) {breadcrumb_separator}].sum
39
39
  end +
@@ -45,10 +45,10 @@ module SemanticNavigation
45
45
  :class => merge_classes(:leaf, object.active, object.classes) do
46
46
  [object.ico ? content_tag(:i,nil,:class => "icon-#{object.ico}") : ''.html_safe,
47
47
  if last_as_link
48
- link_to(object.name, object.url, :id => show_id(:link, object.id),
49
- :class => merge_classes(:link, object.active, object.link_classes))
48
+ link_to(object_name(object), object.url, :id => show_id(:link, object.id),
49
+ :class => merge_classes(:link, object.active, object.link_classes))
50
50
  else
51
- object.name
51
+ object_name(object)
52
52
  end].sum
53
53
  end
54
54
  end
@@ -24,9 +24,9 @@ module SemanticNavigation
24
24
  def node(object)
25
25
  if object.ico
26
26
  name = [content_tag(:i,nil,:class => "icon-#{object.ico}"),
27
- object.name].sum
27
+ object_name(object)].sum
28
28
  else
29
- name = object.name
29
+ name = object_name(object)
30
30
  end
31
31
 
32
32
  content_tag :li, nil, :id => show_id(:leaf, object.id),
@@ -45,7 +45,7 @@ module SemanticNavigation
45
45
  end
46
46
 
47
47
  def leaf(object)
48
- if object.name.empty? && object.url.nil?
48
+ if object_name(object).empty? && object.url.nil?
49
49
  classes = 'divider'
50
50
  elsif object.url.nil?
51
51
  classes = 'nav-header'
@@ -55,9 +55,9 @@ module SemanticNavigation
55
55
 
56
56
  if object.ico
57
57
  name = [content_tag(:i,nil,:class => "icon-#{object.ico}"),
58
- object.name].sum
58
+ object_name(object)].sum
59
59
  else
60
- name = object.name
60
+ name = object_name(object)
61
61
  end
62
62
 
63
63
  content_tag :li, nil, :id => show_id(:leaf, object.id),
@@ -66,7 +66,7 @@ module SemanticNavigation
66
66
  name
67
67
  else
68
68
  link_to name, object.url, :id => show_id(:link, object.id),
69
- :class => merge_classes(:link, object.active, object.link_classes)
69
+ :class => merge_classes(:link, object.active, object.link_classes)
70
70
  end
71
71
  end
72
72
  end