strikeroff-simple-navigation 2.0.2

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.
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