Module: EffectiveMenusHelper

Defined in:
app/helpers/effective_menus_helper.rb

Instance Method Summary collapse

Instance Method Details

#render_menu(menu, options = {}, &block) ⇒ Object



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'app/helpers/effective_menus_helper.rb', line 2

def render_menu(menu, options = {}, &block)
  menu = Effective::Menu.find_by_title(menu.to_s) if menu.kind_of?(String) || menu.kind_of?(Symbol)
  return "<ul class='nav navbar-nav'><li>Menu '#{menu}' does not exist</li></ul>".html_safe if !menu.present?

  if (effectively_editting? && EffectivePages.authorized?(controller, :edit, menu) rescue false)
    options[:menu_id] = menu.id
    form_for(menu, :url => '/') { |form| options[:form] = form }
  end

  menu_items = menu.menu_items

  if menu.new_record?
    menu_items = menu_items.to_a.sort! { |a, b| a.lft <=> b.lft }
  end

  if block_given? && options[:form].blank?
    render_menu_items(menu_items, options) { yield }
  else
    render_menu_items(menu_items, options)
  end

  # if options[:for_editor]
  #else
  #  Rails.cache.fetch(menu) { render_menu_items(menu.menu_items, options) }
  #end
end

#render_menu_items(items, options = {}, &block) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'app/helpers/effective_menus_helper.rb', line 29

def render_menu_items(items, options = {}, &block)
  if options[:form].present? && options[:form].kind_of?(ActionView::Helpers::FormBuilder) == false
    raise 'Expecting ActionView::Helpers::FormBuilder object for :form => option'
  end

  html = ''

  if options[:form]
    html << "<ul class='nav navbar-nav effective-menu #{options[:class]}'"
      html << " data-effective-menu-id='#{options[:menu_id] || 0}'"
      html << " data-effective-menu-expand-html=\"#{render(:partial => 'admin/menu_items/expand').gsub('"', "'").gsub("\n", '').gsub('  ', '')}\""
      html << " data-effective-menu-new-html=\"#{render(:partial => 'admin/menu_items/new', :locals => { :item => Effective::MenuItem.new(), :form => options[:form] }).gsub('"', "'").gsub("\n", '').gsub('  ', '').gsub('[0]', '[:new]').gsub('_0_', '_:new_')}\""

      maxdepth = ((options[:maxdepth].presence || EffectivePages.menu[:maxdepth].presence).to_i rescue 0)
      html << " data-effective-menu-maxdepth='#{maxdepth}'" if maxdepth > 0

    html << ">"
  else
    html << "<ul class='nav navbar-nav#{' ' + options[:class].to_s if options[:class].present?}'>"
  end

  stack = [items.to_a.first] # A stack to keep track of rgt values.
  skip_to_lft = 0 # This lets us skip over nodes we don't have visible_for? permission to see

  items.each_with_index do |item, index|
    next if index == 0 # We always skip the first Root node

    # This allows us to skip over nodes we don't have permission to view
    next if item.lft < skip_to_lft
    if options[:form].blank? && !item.visible_for?(defined?(current_user) ? current_user : nil)
      skip_to_lft = item.rgt + 1
      next
    end

    if stack.size > 1
      html << "<ul class='dropdown-menu'>" if (item.rgt < stack.last.rgt) # Level down?

      while item.rgt > stack.last.rgt # Level up?
        stack.pop
        html << "</ul></li>" if (item.rgt > stack.last.rgt)
      end
    end

    # Render the <li>...</li> with carets only on top level dropdowns, not sub dropdowns
    html << render_menu_item(item, stack.size == 1, options)

    stack.push(item)
  end

  while stack.size > 0
    item = stack.pop

    if stack.size == 0 # Very last one
      html << render(:partial => 'admin/menu_items/actions') if options[:form]
      html << (capture(&block) || '') if block_given? && !options[:form]
      html << '</ul>'
    elsif item.leaf? == false
      html << '</ul></li>'
    end
  end

  html.html_safe
end