Module: Redmine::MenuManager::MenuHelper

Defined in:
lib/redmine/menu_manager.rb

Instance Method Summary collapse

Instance Method Details

#allowed_node?(node, user, project) ⇒ Boolean

See MenuItem#allowed?

Returns:

  • (Boolean)


235
236
237
238
239
240
241
# File 'lib/redmine/menu_manager.rb', line 235

def allowed_node?(node, user, project)
  unless node.is_a? MenuItem
    raise MenuError, ":child_menus must be an array of MenuItems"
  end

  node.allowed?(user, project)
end

#current_menu_itemObject

Returns the current menu item name



97
98
99
# File 'lib/redmine/menu_manager.rb', line 97

def current_menu_item
  controller.current_menu_item
end

#display_main_menu?(project) ⇒ Boolean

Returns:

  • (Boolean)


108
109
110
111
# File 'lib/redmine/menu_manager.rb', line 108

def display_main_menu?(project)
  menu_name = controller.current_menu(project)
  menu_name.present? && Redmine::MenuManager.items(menu_name).children.present?
end

#extract_node_details(node, project = nil) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/redmine/menu_manager.rb', line 215

def extract_node_details(node, project=nil)
  item = node
  url =
    case item.url
    when Hash
      project.nil? ? item.url : {item.param => project}.merge(item.url)
    when Symbol
      if project
        send(item.url, project)
      else
        send(item.url)
      end
    else
      item.url
    end
  caption = item.caption(project)
  return [caption, url, (current_menu_item == item.name)]
end


201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/redmine/menu_manager.rb', line 201

def menu_items_for(menu, project=nil)
  items = []
  Redmine::MenuManager.items(menu).root.children.each do |node|
    if node.allowed?(User.current, project)
      if block_given?
        yield node
      else
        items << node  # TODO: not used?
      end
    end
  end
  return block_given? ? nil : items
end

#render_main_menu(project) ⇒ Object

Renders the application main menu



102
103
104
105
106
# File 'lib/redmine/menu_manager.rb', line 102

def render_main_menu(project)
  if menu_name = controller.current_menu(project)
    render_menu(menu_name, project)
  end
end

#render_menu(menu, project = nil) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/redmine/menu_manager.rb', line 113

def render_menu(menu, project=nil)
  links = []
  menu_items_for(menu, project) do |node|
    links << render_menu_node(node, project)
  end
  links.empty? ? nil : ('ul', links.join.html_safe)
end

#render_menu_node(node, project = nil) ⇒ Object



121
122
123
124
125
126
127
128
129
# File 'lib/redmine/menu_manager.rb', line 121

def render_menu_node(node, project=nil)
  if node.children.present? || !node.child_menus.nil?
    return render_menu_node_with_children(node, project)
  else
    caption, url, selected = extract_node_details(node, project)
    return ('li',
                       render_single_menu_node(node, caption, url, selected))
  end
end

#render_menu_node_with_children(node, project = nil) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/redmine/menu_manager.rb', line 131

def render_menu_node_with_children(node, project=nil)
  caption, url, selected = extract_node_details(node, project)

  html = [].tap do |html|
    html << '<li>'
    # Parent
    html << render_single_menu_node(node, caption, url, selected)

    # Standard children
    standard_children_list = "".html_safe.tap do |child_html|
      node.children.each do |child|
        child_html << render_menu_node(child, project) if allowed_node?(child, User.current, project)
      end
    end

    html << (:ul, standard_children_list, :class => 'menu-children') unless standard_children_list.empty?

    # Unattached children
    unattached_children_list = render_unattached_children_menu(node, project)
    html << (:ul, unattached_children_list, :class => 'menu-children unattached') unless unattached_children_list.blank?

    html << '</li>'
  end
  return html.join("\n").html_safe
end

#render_single_menu_node(item, caption, url, selected) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/redmine/menu_manager.rb', line 174

def render_single_menu_node(item, caption, url, selected)
  options = item.html_options(:selected => selected)

  # virtual nodes are only there for their children to be displayed in the menu
  # and should not do anything on click, except if otherwise defined elsewhere
  if url.blank?
    url = '#'
    options.reverse_merge!(:onclick => 'return false;')
  end

  label = if item.icon.present?
            sprite_icon(item.icon, h(caption))
          else
            h(caption)
          end

  link_to(label, use_absolute_controller(url), options)
end

#render_unattached_children_menu(node, project) ⇒ Object

Returns a list of unattached children menu items



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/redmine/menu_manager.rb', line 158

def render_unattached_children_menu(node, project)
  return nil unless node.child_menus

  "".html_safe.tap do |child_html|
    unattached_children = node.child_menus.call(project)
    # Tree nodes support #each so we need to do object detection
    if unattached_children.is_a? Array
      unattached_children.each do |child|
        child_html << (:li, render_unattached_menu_item(child, project)) if allowed_node?(child, User.current, project)
      end
    else
      raise MenuError, ":child_menus must be an array of MenuItems"
    end
  end
end

#render_unattached_menu_item(menu_item, project) ⇒ Object

Raises:



193
194
195
196
197
198
199
# File 'lib/redmine/menu_manager.rb', line 193

def render_unattached_menu_item(menu_item, project)
  raise MenuError, ":child_menus must be an array of MenuItems" unless menu_item.is_a? MenuItem

  if menu_item.allowed?(User.current, project)
    link_to(menu_item.caption, use_absolute_controller(menu_item.url), menu_item.html_options)
  end
end

#use_absolute_controller(url) ⇒ Object

Prevent hash type URLs (e.g. ‘foo’, action: ‘bar) from being namespaced when menus are rendered from views in namespaced controllers in plugins or engines



245
246
247
248
249
250
# File 'lib/redmine/menu_manager.rb', line 245

def use_absolute_controller(url)
  if url.is_a?(Hash) && url[:controller].present? && !url[:controller].start_with?('/')
    url[:controller] = "/#{url[:controller]}"
  end
  url
end