module RocketNavigation # View helpers to render the navigation. # # Use render_navigation as following to render your navigation: # * call render_navigation without :level option to render your # complete navigation as nested tree. # * call render_navigation(level: x) 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) # * call render_navigation(:level => 2..3) to render navigation # levels 2 and 3). # # For example, you could use render_navigation(level: 1) to render your # primary navigation as tabs and render_navigation(level: 2..3) to render # the rest of the navigation as a tree in a sidebar. # # ==== Examples (using Haml) # #primary_navigation= render_navigation(level: 1) # # #sub_navigation= render_navigation(level: 2) # # #nested_navigation= render_navigation # # #top_navigation= render_navigation(level: 1..2) # #sidebar_navigation= render_navigation(level: 3) module Helpers # Renders the navigation according to the specified options-hash. # # The following options are supported: # * :level - defaults to :all which renders the the sub_navigation # for an active primary_navigation inside that active # primary_navigation item. # Specify a specific level to only render that level of navigation # (e.g. level: 1 for primary_navigation, etc). # Specifiy a Range of levels to render only those specific levels # (e.g. level: 1..2 to render both your first and second levels, maybe # you want to render your third level somewhere else on the page) # * :expand_all - defaults to false. If set to true the all # specified levels will be rendered as a fully expanded # tree (always open). This is useful for javascript menus like Superfish. # * :items - you can specify the items directly (e.g. if items are # dynamically generated from database). # * :renderer - specify the renderer to be used for rendering the # navigation. Either provide the Class or a symbol matching a registered # renderer. Defaults to :list (html list renderer). # # Instead of using the :items option, a block can be passed to # specify the items dynamically # # ==== Examples # render_navigation do |menu| # menu.item :posts, "Posts", posts_path # end # def render_navigation(options = {}, &block) container = ItemContainer.new(1, options) container.view_context = view_context if block_given? yield container end container.render(options) end # Returns true or false based on the provided path and condition # Possible condition values are: # Boolean -> true | false # Symbol -> :exclusive | :inclusive # Regex -> /regex/ # Controller/Action Pair -> [[:controller], [:action_a, :action_b]] # # Example usage: # # is_active_nav_link?('/root', true) # is_active_nav_link?('/root', :exclusive) # is_active_nav_link?('/root', /^\/root/) # is_active_nav_link?('/root', ['users', ['show', 'edit']]) # # Source: https://github.com/comfy/active_link_to/blob/master/lib/active_link_to/active_link_to.rb # Copyright (c) 2009-17 Oleg Khabarov # MIT License def is_active_nav_link?(url, condition = nil) @is_active_link ||= {} @is_active_link[[url, condition]] ||= begin original_url = url url = Addressable::URI::parse(url).path path = request.original_fullpath case condition when :inclusive, nil !path.match(/^#{Regexp.escape(url).chomp('/')}(\/.*|\?.*)?$/).blank? when :exclusive !path.match(/^#{Regexp.escape(url)}\/?(\?.*)?$/).blank? when :exact path == original_url when Proc condition.call(original_url) when Regexp !path.match(condition).blank? when Array controllers = Array.wrap(condition[0]) actions = Array.wrap(condition[1]) (controllers.blank? || controllers.member?(params[:controller])) && (actions.blank? || actions.member?(params[:action])) || controllers.any? do |controller, action| params[:controller] == controller.to_s && params[:action] == action.to_s end when TrueClass true when FalseClass false when Hash condition.all? do |key, value| params[key].to_s == value.to_s end end end end end end