strikeroff-simple-navigation 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v2.0.2 add :level=>:all option for render_navigation
data/Manifest ADDED
@@ -0,0 +1,29 @@
1
+ CHANGELOG
2
+ generators/navigation_config/navigation_config_generator.rb
3
+ generators/navigation_config/templates/config/navigation.rb
4
+ generators/navigation_config/USAGE
5
+ init.rb
6
+ install.rb
7
+ lib/simple_navigation/configuration.rb
8
+ lib/simple_navigation/controller_methods.rb
9
+ lib/simple_navigation/helpers.rb
10
+ lib/simple_navigation/item.rb
11
+ lib/simple_navigation/item_container.rb
12
+ lib/simple_navigation/renderer/base.rb
13
+ lib/simple_navigation/renderer/list.rb
14
+ lib/simple_navigation.rb
15
+ Manifest
16
+ rails/init.rb
17
+ Rakefile
18
+ README
19
+ spec/lib/simple_navigation/configuration_spec.rb
20
+ spec/lib/simple_navigation/controller_methods_spec.rb
21
+ spec/lib/simple_navigation/helpers_spec.rb
22
+ spec/lib/simple_navigation/item_container_spec.rb
23
+ spec/lib/simple_navigation/item_spec.rb
24
+ spec/lib/simple_navigation/renderer/base_spec.rb
25
+ spec/lib/simple_navigation/renderer/list_spec.rb
26
+ spec/lib/simple_navigation_spec.rb
27
+ spec/spec_helper.rb
28
+ strikeroff-simple-navigation.gemspec
29
+ uninstall.rb
data/README ADDED
@@ -0,0 +1,30 @@
1
+ It is a fork of
2
+ http://github.com/andi/simple-navigation
3
+ == Simple Navigation
4
+
5
+ Simple Navigation is a plugin for creating a navigation (optionally with sub navigation) for your rails app.
6
+
7
+ Source code:
8
+ git://github.com/andi/simple-navigation.git
9
+
10
+ Documentation:
11
+ http://wiki.github.com/andi/simple-navigation
12
+
13
+ Online Demo:
14
+ http://simple-navigation-demo.andischacke.com
15
+
16
+ Discussion Group for Feedback and Questions
17
+ http://groups.google.com/group/simple-navigation
18
+
19
+
20
+ Diff from original
21
+ Some times you need to show all navigation tree on page(site map, for example), without config changes
22
+ Extra level :all can help you
23
+
24
+ render_navigation(:level=>:all)
25
+
26
+
27
+
28
+
29
+ Copyright (c) 2009 Andi Schacke, released under the MIT license
30
+
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('strikeroff-simple-navigation') do |p|
6
+
7
+ #fork of http://github.com/andi/simple-navigation
8
+ p.description = "strikeroff-simple-navigation"
9
+ p.url = "http://github.com/strikeroff"
10
+ p.author = "Vesov Ilya"
11
+ p.email = "strikeroff@gmail.com"
12
+ p.ignore_pattern = ["tmp/*", "script/*", ".svn", ".git"]
13
+ p.need_tar_gz = false
14
+ p.retain_gemspec = true
15
+ p.gemspec_name = 'strikeroff-simple-navigation.gemspec'
16
+ p.test_pattern = ["test/**/*_test.rb"]
17
+ p.rdoc_pattern = ["README", "CHANGELOG", "lib/**/*.rb"]
18
+ p.rdoc_options << "-c utf-8"
19
+ p.ignore_pattern = [".gitignore", "doc", ".idea", "*.bat", "*.sh"]
20
+ end
21
+
22
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
23
+
@@ -0,0 +1 @@
1
+ Creates a template config file for the simple-navigation plugin. You will find the generated file in config/navigation.rb.
@@ -0,0 +1,8 @@
1
+ class NavigationConfigGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.file "config/navigation.rb", "config/navigation.rb"
5
+ m.readme "../../../README"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,55 @@
1
+ # Configures your navigation
2
+ SimpleNavigation::Configuration.run do |navigation|
3
+ # Specify a custom renderer if needed.
4
+ # The default renderer is SimpleNavigation::Renderer::List which renders HTML lists.
5
+ # navigation.renderer = Your::Custom::Renderer
6
+
7
+ # Specify the class that will be applied to active navigation items. Defaults to 'selected'
8
+ # navigation.selected_class = 'your_selected_class'
9
+
10
+ # Normally only the current sub menu is renderedwhen render_navigation is called
11
+ # setting this to true render all submenus which is useful for javascript
12
+ # driven hovering menus like the jquery superfish plugin
13
+ # navigation.render_all_levels = true
14
+
15
+ # Item keys are normally added to list items as id.
16
+ # This setting turns that off
17
+ # navigation.autogenerate_item_ids = false
18
+
19
+ # The auto highlight feature is turned on by default.
20
+ # This turns it off globally (for the whole plugin)
21
+ # navigation.auto_highlight = false
22
+
23
+ # Define the primary navigation
24
+ navigation.items do |primary|
25
+ # Add an item to the primary navigation. The following params apply:
26
+ # key - a symbol which uniquely defines your navigation item in the scope of the primary_navigation
27
+ # name - will be displayed in the rendered navigation. This can also be a call to your I18n-framework.
28
+ # url - the address that the generated item links to. You can also use url_helpers (named routes, restful routes helper, url_for etc.)
29
+ # options - can be used to specify attributes that will be included in the rendered navigation item (e.g. id, class etc.)
30
+ #
31
+ primary.item :key_1, 'name', url, options
32
+
33
+ # Add an item which has a sub navigation (same params, but with block)
34
+ primary.item :key_2, 'name', url, options do |sub_nav|
35
+ # Add an item to the sub navigation (same params again)
36
+ sub_nav.item :key_2_1, 'name', url, options
37
+ end
38
+
39
+ # You can also specify a condition-proc that needs to be fullfilled to display an item.
40
+ # Conditions are part of the options. They are evaluated in the context of the views,
41
+ # thus you can use all the methods and vars you have available in the views.
42
+ primary.item :key_3, 'Admin', url, :class => 'special', :if => Proc.new { current_user.admin? }
43
+ primary.item :key_4, 'Account', url, :unless => Proc.new { logged_in? }
44
+
45
+ # you can also specify a css id or class to attach to this particular level
46
+ # works for all levels of the menu
47
+ # primary.dom_id = 'menu-id'
48
+ # primary.dom_class = 'menu-class'
49
+
50
+ # You can turn off auto highlighting for a specific level
51
+ # primary.auto_highlight = false
52
+
53
+ end
54
+
55
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/rails/init"
data/install.rb ADDED
@@ -0,0 +1,5 @@
1
+ begin
2
+ puts IO.read(File.join(File.dirname(__FILE__), 'README'))
3
+ rescue Exception => e
4
+ puts "The following error ocurred while installing the plugin: #{e.message}"
5
+ end
@@ -0,0 +1,66 @@
1
+ require 'singleton'
2
+
3
+ module SimpleNavigation
4
+
5
+ # Responsible for evaluating and handling the config/navigation.rb file.
6
+ class Configuration
7
+ include Singleton
8
+
9
+ attr_accessor :renderer, :selected_class, :render_all_levels, :autogenerate_item_ids, :auto_highlight
10
+ attr_reader :primary_navigation
11
+
12
+ class << self
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.controller = extract_controller_from context
17
+ SimpleNavigation.template = SimpleNavigation.controller.instance_variable_get(:@template)
18
+ context_for_eval.instance_eval(SimpleNavigation.config_files[navigation_context])
19
+ end
20
+
21
+ # Starts processing the configuration
22
+ def run(&block)
23
+ block.call Configuration.instance
24
+ end
25
+
26
+ # Returns the context in which the config file should be evaluated.
27
+ # This is preferably the template, otherwise te controller
28
+ def context_for_eval
29
+ raise 'no context set for evaluation the config file' unless SimpleNavigation.template || SimpleNavigation.controller
30
+ SimpleNavigation.template || SimpleNavigation.controller
31
+ end
32
+
33
+ # Extracts a controller from the context.
34
+ def extract_controller_from(context)
35
+ if context.respond_to? :controller
36
+ context.controller
37
+ else
38
+ context
39
+ end
40
+ end
41
+
42
+ end #class << self
43
+
44
+ # Sets the config's default-settings
45
+ def initialize
46
+ @renderer = SimpleNavigation::Renderer::List
47
+ @selected_class = 'selected'
48
+ @render_all_levels = false
49
+ @autogenerate_item_ids = true
50
+ @auto_highlight = true
51
+ end
52
+
53
+ # Yields an SimpleNavigation::ItemContainer for adding navigation items
54
+ def items(&block)
55
+ @primary_navigation = ItemContainer.new
56
+ block.call @primary_navigation
57
+ end
58
+
59
+ # Returns true if the config_file has already been evaluated.
60
+ def loaded?
61
+ !@primary_navigation.nil?
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,79 @@
1
+ #TODO: add :except and :only options to navigation method
2
+ module SimpleNavigation
3
+
4
+ # Adds methods for explicitely setting the current 'active' navigation to the controllers.
5
+ # Since version 2.0.0 the simple_navigation plugin determines the active navigation based on the current url by default (auto highlighting),
6
+ # so explicitely defining the active navigation in the controllers is only needed for edge cases where automatic highlighting does not work.
7
+ #
8
+ # On the controller class level, use the <tt>navigation</tt> method to set the active navigation for all actions in the controller.
9
+ # Let's assume that we have a primary navigation item :account which in turn has a sub navigation item :settings.
10
+ #
11
+ # ==== Examples
12
+ # class AccountController << ActionController
13
+ # navigation :account
14
+ # ...
15
+ # end
16
+ #
17
+ # class AccountSettingsController << ActionController
18
+ # navigation :settings
19
+ # ...
20
+ # end
21
+ #
22
+ # The first example sets the current primary navigation to :account for all actions. No active sub_navigation.
23
+ # The second example sets the current sub navigation to :settings and since it is a child of :account the current primary navigation is set to :account.
24
+ #
25
+ # On the controller instance level, use the <tt>current_navigation</tt> method to define the active navigation for a specific action.
26
+ # The navigation item that is set in <tt>current_navigation</tt> overrides the one defined on the controller class level (see <tt>navigation</tt> method).
27
+ # Thus if you have an :account primary item with a :special sub navigation item:
28
+ #
29
+ # ==== Example
30
+ # class AccountController << ActionController
31
+ # navigation :account
32
+ #
33
+ # def your_special_action
34
+ # ...
35
+ # current_navigation :special
36
+ # end
37
+ # end
38
+ #
39
+ # The code above still sets the active primary navigation to :account for all actions, but sets the sub_navigation to :account -> :special for 'your_special_action'.
40
+ #
41
+ # Note 1: As you can see above you just have to set the navigation item of your 'deepest' navigation level as active and all its parents are marked as active, too.
42
+ #
43
+ # Note 2: The specified symbols must match the keys for your navigation items in your config/navigation.rb file.
44
+ module ControllerMethods
45
+ def self.included(base) #:nodoc:
46
+ base.class_eval do
47
+ extend ClassMethods
48
+ include InstanceMethods
49
+ include SimpleNavigation::Helpers
50
+ base.helper_method :render_navigation, :render_primary_navigation, :render_sub_navigation
51
+ end
52
+ end
53
+
54
+ module ClassMethods
55
+ # Sets the active navigation for all actions in this controller.
56
+ #
57
+ # The specified symbol must match the keys for your navigation items in your config/navigation.rb file.
58
+ def navigation(*args)
59
+ self.class_eval do
60
+ define_method :sn_set_navigation do
61
+ current_navigation(*args)
62
+ end
63
+ before_filter :sn_set_navigation
64
+ end
65
+ end
66
+ end
67
+
68
+ module InstanceMethods
69
+ # Sets the active navigation. Call this method in any action to override the controller-wide active navigation
70
+ # specified by navigation.
71
+ #
72
+ # The specified symbol must match the keys for your navigation items in your config/navigation.rb file.
73
+ def current_navigation(*args)
74
+ @sn_current_navigation_args = args
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,82 @@
1
+ module SimpleNavigation
2
+
3
+ # View helpers to render the navigation.
4
+ #
5
+ # Use render_navigation as following to render your navigation:
6
+ # * call <tt>render_navigation</tt> without :level option to render your navigation as nested tree.
7
+ # * call <tt>render_navigation(:level => x)</tt> to render a specific navigation level (e.g. :level => 1 to render your primary navigation, :level => 2 to render the sub navigation and so forth)
8
+ #
9
+ # ==== Examples (using Haml)
10
+ # #primary_navigation= render_navigation(:level => 1)
11
+ #
12
+ # #sub_navigation= render_navigation(:level => 2)
13
+ #
14
+ # #nested_navigation= render_navigation
15
+ #
16
+ # Please note that <tt>render_primary_navigation</tt> and <tt>render_sub_navigation</tt> still work, but have been deprecated and may be removed in a future release.
17
+ module Helpers
18
+
19
+ # Renders the navigation according to the specified options-hash.
20
+ #
21
+ # The following options are supported:
22
+ # * <tt>:level</tt> - defaults to :nested which renders the the sub_navigation for an active primary_navigation inside that active primary_navigation item.
23
+ # Specify a specific level to only render that level of navigation (e.g. :level => 1 for primary_navigation etc...).
24
+ # * <tt>:context</tt> - specifies the context for which you would render the navigation. Defaults to :default which loads the default navigation.rb (i.e. config/navigation.rb).
25
+ # If you specify a context then the plugin tries to load the configuration file for that context, e.g. if you call <tt>render_navigation(:context => :admin)</tt> the file config/admin_navigation.rb
26
+ # will be loaded and used for rendering the navigation.
27
+ #
28
+ def render_navigation(*args)
29
+ args = [Hash.new] if args.empty?
30
+ options = extract_backwards_compatible_options(*args)
31
+ options = {:context => :default, :level => :nested}.merge(options)
32
+ SimpleNavigation.load_config(options[:context])
33
+ SimpleNavigation::Configuration.eval_config(self, options[:context])
34
+ SimpleNavigation.handle_explicit_navigation
35
+ case options[:level]
36
+ when Integer
37
+ active_item_container = SimpleNavigation.active_item_container_for(options[:level])
38
+ active_item_container.render if active_item_container
39
+ when :nested
40
+ SimpleNavigation.primary_navigation.render(true)
41
+ when :all
42
+ SimpleNavigation.primary_navigation.render(true,:all=>true)
43
+ else
44
+ raise ArgumentError, "Invalid navigation level: #{options[:level]}"
45
+ end
46
+ end
47
+
48
+ # Deprecated. Renders the primary_navigation with the configured renderer. Calling render_navigation(:level => 0) has the same effect.
49
+ def render_primary_navigation(options = {})
50
+ ActiveSupport::Deprecation.warn("SimpleNavigation::Helpers.render_primary_navigation has been deprected. Please use render_navigation(:level => 1) instead")
51
+ render_navigation(options.merge(:level => 1))
52
+ end
53
+
54
+ # Deprecated. Renders the sub_navigation with the configured renderer. Calling render_navigation(:level => 1) has the same effect.
55
+ def render_sub_navigation(options = {})
56
+ ActiveSupport::Deprecation.warn("SimpleNavigation::Helpers.render_primary_navigation has been deprected. Please use render_navigation(:level => 2) instead")
57
+ render_navigation(options.merge(:level => 2))
58
+ end
59
+
60
+ private
61
+
62
+ def extract_backwards_compatible_options(*args)
63
+ case args.first
64
+ when Hash
65
+ options = args.first
66
+ options[:level] = 1 if options[:level] == :primary
67
+ options[:level] = 2 if options[:level] == :secondary
68
+ when Symbol
69
+ raise ArgumentError, "Invalid arguments" unless [:primary, :secondary, :nested].include? args.first
70
+ options = Hash.new
71
+ options[:level] = args.first
72
+ options[:level] = 1 if options[:level] == :primary
73
+ options[:level] = 2 if options[:level] == :secondary
74
+ options.merge!(args[1] || {})
75
+ else
76
+ raise ArgumentError, "Invalid arguments"
77
+ end
78
+ options
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,89 @@
1
+ module SimpleNavigation
2
+
3
+ # Represents an item in your navigation. Gets generated by the item method in the config-file.
4
+ class Item
5
+ attr_reader :key, :name, :url, :sub_navigation, :method
6
+ attr_writer :html_options
7
+
8
+ # see ItemContainer#item
9
+ def initialize(container, key, name, url, options, sub_nav_block) #:nodoc:
10
+ @container = container
11
+ @key = key
12
+ @method = options.delete(:method)
13
+ @name = name
14
+ @url = url
15
+ @html_options = options
16
+ if sub_nav_block
17
+ @sub_navigation = ItemContainer.new(@container.level + 1)
18
+ sub_nav_block.call @sub_navigation
19
+ end
20
+ end
21
+
22
+ # Returns true if this navigation item should be rendered as 'selected'.
23
+ # An item is selected if
24
+ #
25
+ # * it has been explicitly selected in a controller or
26
+ # * it has a subnavigation and one of its subnavigation items is selected or
27
+ # * its url matches the url of the current request (auto highlighting)
28
+ #
29
+ def selected?
30
+ @selected = @selected || selected_by_config? || selected_by_subnav? || selected_by_url?
31
+ end
32
+
33
+ # Returns the html-options hash for the item, i.e. the options specified for this item in the config-file.
34
+ # It also adds the 'selected' class to the list of classes if necessary.
35
+ def html_options
36
+ default_options = self.autogenerate_item_ids? ? {:id => key.to_s} : {}
37
+ options = default_options.merge(@html_options)
38
+ options[:class] = [@html_options[:class], self.selected_class].flatten.compact.join(' ')
39
+ options.delete(:class) if options[:class].blank?
40
+ options
41
+ end
42
+
43
+ # Returns the configured selected_class if the item is selected, nil otherwise
44
+ #
45
+ def selected_class
46
+ selected? ? SimpleNavigation.config.selected_class : nil
47
+ end
48
+
49
+ protected
50
+
51
+ # Returns true if item has a subnavigation and the sub_navigation is selected
52
+ def selected_by_subnav?
53
+ sub_navigation && sub_navigation.selected?
54
+ end
55
+
56
+ # Return true if item has explicitly selected in controllers
57
+ def selected_by_config?
58
+ key == @container.current_explicit_navigation
59
+ end
60
+
61
+ # Returns true if the item's url matches the request's current url.
62
+ def selected_by_url?
63
+ if auto_highlight?
64
+ !!(root_path_match? || (SimpleNavigation.template && SimpleNavigation.template.current_page?(url)))
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ # Returns true if both the item's url and the request's url are root_path
71
+ def root_path_match?
72
+ url == '/' && SimpleNavigation.controller.request.path == '/'
73
+ end
74
+
75
+ # Converts url to url_hash. Accesses routing system, quite slow... Not used at the moment
76
+ # def hash_for_url(url) #:nodoc:
77
+ # ActionController::Routing::Routes.recognize_path(url, {:method => (method || :get)})
78
+ # end
79
+
80
+ def autogenerate_item_ids?
81
+ SimpleNavigation.config.autogenerate_item_ids
82
+ end
83
+
84
+ def auto_highlight?
85
+ SimpleNavigation.config.auto_highlight && @container.auto_highlight
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,119 @@
1
+ module SimpleNavigation
2
+
3
+ # Holds the Items for a navigation 'level'.
4
+ class ItemContainer
5
+
6
+ attr_reader :items, :level
7
+ attr_accessor :renderer, :dom_id, :dom_class, :auto_highlight
8
+
9
+ def initialize(level=1) #:nodoc:
10
+ @level = level
11
+ @items = []
12
+ @renderer = SimpleNavigation.config.renderer
13
+ @auto_highlight = true
14
+ end
15
+
16
+ # Creates a new navigation item.
17
+ #
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
+ #
20
+ # The <tt>name</tt> will be displayed in the rendered navigation. This can also be a call to your I18n-framework.
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.)
23
+ #
24
+ # The <tt>options</tt> can be used to specify the following things:
25
+ # * <tt>html_attributes</tt> - will be included in the rendered navigation item (e.g. id, class etc.)
26
+ # * <tt>:if</tt> - Specifies a proc to call to determine if the item should
27
+ # be rendered (e.g. <tt>:if => Proc.new { current_user.admin? }</tt>). The
28
+ # proc should evaluate to a true or false value and is evaluated in the context of the view.
29
+ # * <tt>:unless</tt> - Specifies a proc to call to determine if the item should not
30
+ # be rendered (e.g. <tt>:unless => Proc.new { current_user.admin? }</tt>). The
31
+ # proc should evaluate to a true or false value and is evaluated in the context of the view.
32
+ #
33
+ # The <tt>block</tt> - if specified - will hold the item's sub_navigation.
34
+ def item(key, name, url, options={}, &block)
35
+ (@items << SimpleNavigation::Item.new(self, key, name, url, options, block)) if should_add_item?(options)
36
+ end
37
+
38
+ # Returns the Item with the specified key, nil otherwise.
39
+ #
40
+ def [](navi_key)
41
+ items.find {|i| i.key == navi_key}
42
+ end
43
+
44
+ # Returns the level of the item specified by navi_key.
45
+ # Recursively works its way down the item's sub_navigations if the desired item is not found directly in this container's items.
46
+ # Returns nil item cannot be found.
47
+ #
48
+ def level_for_item(navi_key)
49
+ my_item = self[navi_key]
50
+ return self.level if my_item
51
+ items.each do |i|
52
+ if i.sub_navigation
53
+ level = i.sub_navigation.level_for_item(navi_key)
54
+ return level unless level.nil?
55
+ end
56
+ end
57
+ return nil
58
+ end
59
+
60
+ # Renders the items in this ItemContainer using the configured renderer.
61
+ #
62
+ # Set <tt>include_sub_navigation</tt> to true if you want to nest the sub_navigation into the active parent_navigation
63
+ def render(include_sub_navigation=false, options={})
64
+ self.renderer.new.render(self, include_sub_navigation, options)
65
+ end
66
+
67
+ # Returns true if any of this container's items is selected.
68
+ #
69
+ def selected?
70
+ items.any? {|i| i.selected?}
71
+ end
72
+
73
+ # Returns the currently selected item, nil if no item is selected.
74
+ #
75
+ def selected_item
76
+ self[current_explicit_navigation] || items.find {|i| i.selected?}
77
+ end
78
+
79
+ # Returns the current navigation that has been explicitely defined in the controller for this container's level.
80
+ # Returns nil if no explicit current navigation has been set.
81
+ #
82
+ def current_explicit_navigation
83
+ SimpleNavigation.current_navigation_for(level)
84
+ end
85
+
86
+ # Returns the active item_container for the specified level
87
+ # (recursively looks up items in selected sub_navigation if level is deeper than this container's level).
88
+ #
89
+ def active_item_container_for(desired_level)
90
+ return self if self.level == desired_level
91
+ return nil unless selected_sub_navigation?
92
+ return selected_item.sub_navigation.active_item_container_for(desired_level)
93
+ end
94
+
95
+ private
96
+
97
+ def selected_sub_navigation?
98
+ !!(selected_item && selected_item.sub_navigation)
99
+ end
100
+
101
+ # partially borrowed from ActionSupport::Callbacks
102
+ def should_add_item?(options) #:nodoc:
103
+ [options.delete(:if)].flatten.compact.all? { |m| evaluate_method(m) } &&
104
+ ![options.delete(:unless)].flatten.compact.any? { |m| evaluate_method(m) }
105
+ end
106
+
107
+ # partially borrowed from ActionSupport::Callbacks
108
+ def evaluate_method(method) #:nodoc:
109
+ case method
110
+ when Proc, Method
111
+ method.call
112
+ else
113
+ raise ArgumentError, ":if or :unless must be procs or lambdas"
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ end
@@ -0,0 +1,44 @@
1
+ module SimpleNavigation
2
+ module Renderer
3
+
4
+ # This is the base class for all renderers.
5
+ #
6
+ # A renderer is responsible for rendering an ItemContainer and its containing items to HTML.
7
+ class Base
8
+ include ActionView::Helpers::UrlHelper
9
+ include ActionView::Helpers::TagHelper
10
+
11
+ attr_reader :controller
12
+
13
+ class << self
14
+
15
+ # Delegates method calls to the controller.
16
+ def controller_method(*methods)
17
+ methods.each do |method|
18
+ delegate method, :to => :controller
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ controller_method :form_authenticity_token, :protect_against_forgery?, :request_forgery_protection_token
25
+
26
+ def initialize #:nodoc:
27
+ @controller = SimpleNavigation.controller
28
+ end
29
+
30
+ # Renders the specified ItemContainer to HTML.
31
+ #
32
+ # If <tt>include_sub_navigation</tt> is set to true, the renderer should nest the sub_navigation for the active navigation
33
+ # inside that navigation item.
34
+ #
35
+ # A renderer should also take the option SimpleNavigation.config.render_all_levels into account. If it is set to true then it should render all navigation levels
36
+ # independent of the <tt>include_sub_navigation</tt> option.
37
+ #
38
+ def render(item_container, include_sub_navigation=false,options={})
39
+ raise 'subclass responsibility'
40
+ end
41
+
42
+ end
43
+ end
44
+ end