simple-navigation 2.7.3 → 3.0.0.beta1

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 (46) hide show
  1. data/CHANGELOG +14 -4
  2. data/README +1 -2
  3. data/Rakefile +1 -0
  4. data/VERSION.yml +4 -4
  5. data/generators/navigation_config/templates/config/navigation.rb +14 -14
  6. data/lib/simple_navigation.rb +69 -151
  7. data/lib/simple_navigation/adapters.rb +9 -0
  8. data/lib/simple_navigation/adapters/base.rb +37 -0
  9. data/lib/simple_navigation/adapters/padrino.rb +20 -0
  10. data/lib/simple_navigation/adapters/rails.rb +93 -0
  11. data/lib/simple_navigation/adapters/sinatra.rb +76 -0
  12. data/lib/simple_navigation/core.rb +5 -0
  13. data/lib/simple_navigation/{configuration.rb → core/configuration.rb} +14 -19
  14. data/lib/simple_navigation/{item.rb → core/item.rb} +10 -11
  15. data/lib/simple_navigation/{item_adapter.rb → core/item_adapter.rb} +11 -7
  16. data/lib/simple_navigation/{item_container.rb → core/item_container.rb} +14 -21
  17. data/lib/simple_navigation/{items_provider.rb → core/items_provider.rb} +7 -7
  18. data/lib/simple_navigation/{controller_methods.rb → rails_controller_methods.rb} +67 -5
  19. data/lib/simple_navigation/rendering.rb +10 -0
  20. data/lib/simple_navigation/{helpers.rb → rendering/helpers.rb} +16 -18
  21. data/lib/simple_navigation/{renderer → rendering/renderer}/base.rb +20 -37
  22. data/lib/simple_navigation/{renderer → rendering/renderer}/breadcrumbs.rb +7 -7
  23. data/lib/simple_navigation/{renderer → rendering/renderer}/links.rb +7 -7
  24. data/lib/simple_navigation/{renderer → rendering/renderer}/list.rb +6 -6
  25. data/rails/init.rb +1 -5
  26. data/spec/lib/simple_navigation/adapters/padrino_spec.rb +29 -0
  27. data/spec/lib/simple_navigation/adapters/rails_spec.rb +269 -0
  28. data/spec/lib/simple_navigation/adapters/sinatra_spec.rb +60 -0
  29. data/spec/lib/simple_navigation/{configuration_spec.rb → core/configuration_spec.rb} +7 -18
  30. data/spec/lib/simple_navigation/{item_adapter_spec.rb → core/item_adapter_spec.rb} +11 -11
  31. data/spec/lib/simple_navigation/{item_container_spec.rb → core/item_container_spec.rb} +29 -46
  32. data/spec/lib/simple_navigation/{item_spec.rb → core/item_spec.rb} +30 -64
  33. data/spec/lib/simple_navigation/{items_provider_spec.rb → core/items_provider_spec.rb} +7 -7
  34. data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +251 -0
  35. data/spec/lib/simple_navigation/{helpers_spec.rb → rendering/helpers_spec.rb} +34 -53
  36. data/spec/lib/simple_navigation/{renderer → rendering/renderer}/base_spec.rb +11 -62
  37. data/spec/lib/simple_navigation/{renderer → rendering/renderer}/breadcrumbs_spec.rb +9 -51
  38. data/spec/lib/simple_navigation/rendering/renderer/links_spec.rb +59 -0
  39. data/spec/lib/simple_navigation/{renderer → rendering/renderer}/list_spec.rb +17 -58
  40. data/spec/lib/simple_navigation_spec.rb +51 -298
  41. data/spec/spec_helper.rb +16 -5
  42. metadata +67 -48
  43. data/lib/simple_navigation/initializer.rb +0 -21
  44. data/lib/simple_navigation/railtie.rb +0 -7
  45. data/spec/lib/simple_navigation/controller_methods_spec.rb +0 -90
  46. data/spec/lib/simple_navigation/renderer/links_spec.rb +0 -121
@@ -0,0 +1,20 @@
1
+ module SimpleNavigation
2
+ module Adapters
3
+ class Padrino < Sinatra
4
+
5
+ def self.register
6
+ SimpleNavigation.set_env(PADRINO_ROOT, PADRINO_ENV)
7
+ ::Padrino::Application.send(:helpers, SimpleNavigation::Helpers)
8
+ end
9
+
10
+ def link_to(name, url, options={})
11
+ context.link_to name, url, options
12
+ end
13
+
14
+ def content_tag(type, content, options={})
15
+ context.content_tag type, content, options
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,93 @@
1
+ module SimpleNavigation
2
+ module Adapters
3
+ class Rails < Base
4
+
5
+ attr_reader :controller, :template
6
+
7
+ def self.register
8
+ SimpleNavigation.set_env(rails_root, rails_env)
9
+ ActionController::Base.send(:include, SimpleNavigation::Helpers)
10
+ ActionController::Base.send(:helper_method, :render_navigation)
11
+ end
12
+
13
+ def initialize(context)
14
+ @controller = extract_controller_from context
15
+ @template = template_from @controller
16
+ @request = @template.request if @template
17
+ end
18
+
19
+ def request_uri
20
+ return '' unless request
21
+ return request.fullpath if request.respond_to?(:fullpath)
22
+ request.request_uri
23
+ end
24
+
25
+ def request_path
26
+ return '' unless request
27
+ request.path
28
+ end
29
+
30
+ def context_for_eval
31
+ raise 'no context set for evaluation the config file' unless template || controller
32
+ template || controller
33
+ end
34
+
35
+ def current_page?(url)
36
+ template.current_page?(url) if template
37
+ end
38
+
39
+ def link_to(name, url, options={})
40
+ template.link_to(html_safe(name), url, options) if template
41
+ end
42
+
43
+ def content_tag(type, content, options={})
44
+ template.content_tag(type, html_safe(content), options) if template
45
+ end
46
+
47
+ protected
48
+
49
+ def self.rails_root
50
+ rails3? ? ::Rails.root : ::RAILS_ROOT
51
+ end
52
+
53
+ def self.rails_env
54
+ rails3? ? ::Rails.env : ::RAILS_ENV
55
+ end
56
+
57
+ def self.rails3?
58
+ ::Rails::VERSION::MAJOR == 3
59
+ end
60
+
61
+ def template_from(controller)
62
+ controller.instance_variable_get(:@template) || (controller.respond_to?(:view_context) ? controller.view_context : nil)
63
+ end
64
+
65
+ # Marks the specified input as html_safe (for Rails3). Does nothing if html_safe is not defined on input.
66
+ #
67
+ def html_safe(input)
68
+ input.respond_to?(:html_safe) ? input.html_safe : input
69
+ end
70
+
71
+ # Extracts a controller from the context.
72
+ def extract_controller_from(context)
73
+ if context.respond_to? :controller
74
+ context.controller
75
+ else
76
+ context
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+
84
+ # Initializer for Rails3
85
+ if defined?(Rails) && Rails::VERSION::MAJOR == 3
86
+ module SimpleNavigation
87
+ class Railtie < Rails::Railtie
88
+ initializer "simple_navigation.register" do |app|
89
+ SimpleNavigation.register
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,76 @@
1
+ module SimpleNavigation
2
+ module Adapters
3
+ class Sinatra < Base
4
+
5
+ def self.register
6
+ SimpleNavigation.set_env(sinatra_root, sinatra_environment)
7
+ ::Sinatra::Application.send(:helpers, SimpleNavigation::Helpers)
8
+ end
9
+
10
+ def initialize(context)
11
+ @context = context
12
+ @request = context.request
13
+ end
14
+
15
+ def context_for_eval
16
+ raise 'no context set for evaluation the config file' unless context
17
+ context
18
+ end
19
+
20
+ def request_uri
21
+ request.fullpath
22
+ end
23
+
24
+ def request_path
25
+ request.path
26
+ end
27
+
28
+ def current_page?(url)
29
+ url_string = CGI.unescape(url)
30
+ if url_string.index("?")
31
+ uri = request_uri
32
+ else
33
+ uri = request_uri.split('?').first
34
+ end
35
+ if url_string =~ /^\w+:\/\//
36
+ url_string == "#{request.protocol}#{request.host_with_port}#{uri}"
37
+ else
38
+ url_string == uri
39
+ end
40
+ end
41
+
42
+ def link_to(name, url, options={})
43
+ "<a href='#{url}' #{to_attributes(options)}>#{name}</a>"
44
+ end
45
+
46
+ def content_tag(type, content, options={})
47
+ "<#{type} #{to_attributes(options)}>#{content}</#{type}>"
48
+ end
49
+
50
+ protected
51
+
52
+ def self.sinatra_root
53
+ ::Sinatra::Application.root
54
+ end
55
+
56
+ def self.sinatra_environment
57
+ ::Sinatra::Application.environment
58
+ end
59
+
60
+ def to_attributes(options)
61
+ options.map {|k, v| "#{k}='#{v}'"}.join(' ')
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+
68
+ module SimpleNavigation
69
+
70
+ # Adds registered method to SimpleNavigation. This is called when executing 'register SimpleNavigation'.
71
+ def self.registered(app)
72
+ register
73
+ app.helpers Helpers
74
+ end
75
+
76
+ end
@@ -0,0 +1,5 @@
1
+ require 'simple_navigation/core/configuration'
2
+ require 'simple_navigation/core/item_adapter'
3
+ require 'simple_navigation/core/item'
4
+ require 'simple_navigation/core/item_container'
5
+ require 'simple_navigation/core/items_provider'
@@ -1,29 +1,28 @@
1
1
  require 'singleton'
2
2
 
3
3
  module SimpleNavigation
4
-
5
- # Responsible for evaluating and handling the config/navigation.rb file.
4
+
5
+ # Responsible for evaluating and handling the config/navigation.rb file.
6
6
  class Configuration
7
7
  include Singleton
8
-
8
+
9
9
  attr_accessor :renderer, :selected_class, :autogenerate_item_ids, :id_generator, :auto_highlight
10
10
  attr_reader :render_all_levels, :primary_navigation
11
11
 
12
12
  class << self
13
13
 
14
- # Evals the config_file for the given navigation_context inside the specified context (usually a controller or view)
15
- def eval_config(context, navigation_context = :default)
16
- SimpleNavigation.set_template_from context
14
+ # Evals the config_file for the given navigation_context
15
+ def eval_config(navigation_context = :default)
17
16
  SimpleNavigation.context_for_eval.instance_eval(SimpleNavigation.config_files[navigation_context])
18
17
  end
19
-
18
+
20
19
  # Starts processing the configuration
21
20
  def run(&block)
22
21
  block.call Configuration.instance
23
- end
24
-
22
+ end
23
+
25
24
  end #class << self
26
-
25
+
27
26
  # Sets the config's default-settings
28
27
  def initialize
29
28
  @renderer = SimpleNavigation.default_renderer || SimpleNavigation::Renderer::List
@@ -32,17 +31,17 @@ module SimpleNavigation
32
31
  @id_generator = Proc.new {|id| id.to_s }
33
32
  @auto_highlight = true
34
33
  end
35
-
34
+
36
35
  # Adds a deprecation warning when this options is set in the config file
37
36
  def render_all_levels=(do_it)
38
37
  ActiveSupport::Deprecation.warn("Setting render_all_levels in the config-file has been deprected. Please use render_navigation(:expand_all => true) instead")
39
38
  @render_all_levels = do_it
40
39
  end
41
-
40
+
42
41
  # This is the main method for specifying the navigation items. It can be used in two ways:
43
- #
42
+ #
44
43
  # 1. Declaratively specify your items in the config/navigation.rb file using a block. It then yields an SimpleNavigation::ItemContainer for adding navigation items.
45
- # 1. Directly provide your items to the method (e.g. when loading your items from the database). Either specify
44
+ # 1. Directly provide your items to the method (e.g. when loading your items from the database). Either specify
46
45
  #
47
46
  # ==== Example for block style
48
47
  # config.items do |primary|
@@ -66,15 +65,11 @@ module SimpleNavigation
66
65
  @primary_navigation.items = SimpleNavigation::ItemsProvider.new(items_provider).items
67
66
  end
68
67
  end
69
-
68
+
70
69
  # Returns true if the config_file has already been evaluated.
71
70
  def loaded?
72
71
  !@primary_navigation.nil?
73
72
  end
74
-
75
- def context_for_eval
76
- self.class.context_for_eval
77
- end
78
73
 
79
74
  end
80
75
 
@@ -1,13 +1,13 @@
1
1
  module SimpleNavigation
2
-
2
+
3
3
  # Represents an item in your navigation. Gets generated by the item method in the config-file.
4
4
  class Item
5
5
  attr_reader :key, :name, :url, :sub_navigation, :method, :highlights_on
6
6
  attr_writer :html_options
7
-
7
+
8
8
  # see ItemContainer#item
9
9
  #
10
- # The subnavigation (if any) is either provided by a block or passed in directly as <tt>items</tt>
10
+ # The subnavigation (if any) is either provided by a block or passed in directly as <tt>items</tt>
11
11
  def initialize(container, key, name, url, options, items=nil, &sub_nav_block)
12
12
  @container = container
13
13
  @key = key
@@ -22,7 +22,7 @@ module SimpleNavigation
22
22
  @sub_navigation.items = items if items
23
23
  end
24
24
  end
25
-
25
+
26
26
  # Returns true if this navigation item should be rendered as 'selected'.
27
27
  # An item is selected if
28
28
  #
@@ -33,14 +33,14 @@ module SimpleNavigation
33
33
  def selected?
34
34
  @selected = @selected || selected_by_config? || selected_by_subnav? || selected_by_url?
35
35
  end
36
-
36
+
37
37
  # Returns the html-options hash for the item, i.e. the options specified for this item in the config-file.
38
- # It also adds the 'selected' class to the list of classes if necessary.
38
+ # It also adds the 'selected' class to the list of classes if necessary.
39
39
  def html_options
40
40
  default_options = self.autogenerate_item_ids? ? {:id => autogenerated_item_id} : {}
41
41
  options = default_options.merge(@html_options)
42
42
  options[:class] = [@html_options[:class], self.selected_class].flatten.compact.join(' ')
43
- options.delete(:class) if options[:class].blank?
43
+ options.delete(:class) if options[:class].nil? || options[:class] == ''
44
44
  options
45
45
  end
46
46
 
@@ -57,9 +57,8 @@ module SimpleNavigation
57
57
  sub_navigation && sub_navigation.selected?
58
58
  end
59
59
 
60
- # Return true if item has explicitly selected in controllers
61
60
  def selected_by_config?
62
- key == @container.current_explicit_navigation
61
+ false
63
62
  end
64
63
 
65
64
  # Returns true if the item's url matches the request's current url.
@@ -68,7 +67,7 @@ module SimpleNavigation
68
67
  raise ArgumentError, ':highlights_on must be a regexp' unless highlights_on.instance_of?(Regexp)
69
68
  SimpleNavigation.request_uri =~ highlights_on
70
69
  elsif auto_highlight?
71
- !!(root_path_match? || (SimpleNavigation.template && SimpleNavigation.template.current_page?(url)))
70
+ !!(root_path_match? || SimpleNavigation.current_page?(url))
72
71
  else
73
72
  false
74
73
  end
@@ -76,7 +75,7 @@ module SimpleNavigation
76
75
 
77
76
  # Returns true if both the item's url and the request's url are root_path
78
77
  def root_path_match?
79
- url == '/' && SimpleNavigation.controller.request.path == '/'
78
+ url == '/' && SimpleNavigation.request_path == '/'
80
79
  end
81
80
 
82
81
  # Returns true if the item's id should be added to the rendered output.
@@ -1,5 +1,7 @@
1
+ require 'forwardable'
2
+
1
3
  module SimpleNavigation
2
-
4
+
3
5
  # This class acts as an adapter to items that are not defined using the DSL in the config/navigation.rb, but directly provided inside the application.
4
6
  # When defining the items that way, every item you provide needs to define the following methods:
5
7
  #
@@ -8,34 +10,36 @@ module SimpleNavigation
8
10
  # * <tt>url</tt>
9
11
  #
10
12
  # and optionally
11
- #
13
+ #
12
14
  # * <tt>options</tt>
13
15
  # * <tt>items</tt> - if one of your items has a subnavigation it must respond to <tt>items</tt> providing the subnavigation.
14
16
  #
15
17
  # See SimpleNavigation::ItemContainer#item for the purpose of these methods.
16
18
  class ItemAdapter
17
- delegate :key, :name, :url, :to => :item
19
+ extend Forwardable
18
20
 
21
+ def_delegators :item, :key, :name, :url
22
+
19
23
  attr_reader :item
20
24
 
21
25
  def initialize(item)
22
26
  @item = item
23
27
  end
24
-
28
+
25
29
  # Returns the options for this item. If the wrapped item does not implement an options method, an empty hash is returned.
26
30
  def options
27
31
  @item.respond_to?(:options) ? @item.options : {}
28
32
  end
29
-
33
+
30
34
  # Returns the items (subnavigation) for this item if it responds to :items and the items-collection is not empty. Returns nil otherwise.
31
35
  def items
32
36
  (@item.respond_to?(:items) && !(@item.items.nil? || @item.items.empty?)) ? @item.items : nil
33
37
  end
34
-
38
+
35
39
  # Converts this Item into a SimpleNavigation::Item
36
40
  def to_simple_navigation_item(item_container)
37
41
  SimpleNavigation::Item.new(item_container, key, name, url, options, items)
38
42
  end
39
-
43
+
40
44
  end
41
45
  end
@@ -1,25 +1,25 @@
1
1
  module SimpleNavigation
2
-
2
+
3
3
  # Holds the Items for a navigation 'level'.
4
4
  class ItemContainer
5
-
5
+
6
6
  attr_reader :items, :level
7
7
  attr_accessor :renderer, :dom_id, :dom_class, :auto_highlight
8
-
8
+
9
9
  def initialize(level=1) #:nodoc:
10
10
  @level = level
11
11
  @items = []
12
12
  @renderer = SimpleNavigation.config.renderer
13
13
  @auto_highlight = true
14
14
  end
15
-
16
- # Creates a new navigation item.
15
+
16
+ # Creates a new navigation item.
17
17
  #
18
18
  # The <tt>key</tt> is a symbol which uniquely defines your navigation item in the scope of the primary_navigation or the sub_navigation.
19
- #
19
+ #
20
20
  # The <tt>name</tt> will be displayed in the rendered navigation. This can also be a call to your I18n-framework.
21
21
  #
22
- # The <tt>url</tt> is the address that the generated item points to. You can also use url_helpers (named routes, restful routes helper, url_for etc.)
22
+ # The <tt>url</tt> is the address that the generated item points to. You can also use url_helpers (named routes, restful routes helper, url_for etc.)
23
23
  #
24
24
  # The <tt>options</tt> can be used to specify the following things:
25
25
  # * <tt>any html_attributes</tt> - will be included in the rendered navigation item (e.g. id, class etc.)
@@ -30,7 +30,7 @@ module SimpleNavigation
30
30
  # be rendered (e.g. <tt>:unless => Proc.new { current_user.admin? }</tt>). The
31
31
  # proc should evaluate to a true or false value and is evaluated in the context of the view.
32
32
  # * <tt>:method</tt> - Specifies the http-method for the generated link - default is :get.
33
- # * <tt>:highlights_on</tt> - if autohighlighting is turned off and/or you want to explicitly specify
33
+ # * <tt>:highlights_on</tt> - if autohighlighting is turned off and/or you want to explicitly specify
34
34
  # when the item should be highlighted, you can set a regexp which is matched againstthe current URI.
35
35
  #
36
36
  # The <tt>block</tt> - if specified - will hold the item's sub_navigation.
@@ -66,7 +66,7 @@ module SimpleNavigation
66
66
  end
67
67
  return nil
68
68
  end
69
-
69
+
70
70
  # Renders the items in this ItemContainer using the configured renderer.
71
71
  #
72
72
  # The options are the same as in the view's render_navigation call (they get passed on)
@@ -92,14 +92,7 @@ module SimpleNavigation
92
92
  # Returns the currently selected item, nil if no item is selected.
93
93
  #
94
94
  def selected_item
95
- self[current_explicit_navigation] || items.find {|i| i.selected?}
96
- end
97
-
98
- # Returns the current navigation that has been explicitely defined in the controller for this container's level.
99
- # Returns nil if no explicit current navigation has been set.
100
- #
101
- def current_explicit_navigation
102
- SimpleNavigation.current_navigation_for(level)
95
+ items.find {|i| i.selected?}
103
96
  end
104
97
 
105
98
  # Returns the active item_container for the specified level
@@ -117,7 +110,7 @@ module SimpleNavigation
117
110
  end
118
111
 
119
112
  private
120
-
113
+
121
114
  def selected_sub_navigation?
122
115
  !!(selected_item && selected_item.sub_navigation)
123
116
  end
@@ -127,7 +120,7 @@ module SimpleNavigation
127
120
  [options.delete(:if)].flatten.compact.all? { |m| evaluate_method(m) } &&
128
121
  ![options.delete(:unless)].flatten.compact.any? { |m| evaluate_method(m) }
129
122
  end
130
-
123
+
131
124
  # partially borrowed from ActionSupport::Callbacks
132
125
  def evaluate_method(method) #:nodoc:
133
126
  case method
@@ -137,7 +130,7 @@ module SimpleNavigation
137
130
  raise ArgumentError, ":if or :unless must be procs or lambdas"
138
131
  end
139
132
  end
140
-
133
+
141
134
  end
142
-
135
+
143
136
  end