Class: DcMenuRenderer

Inherits:
Object
  • Object
show all
Includes:
CmsCommonHelper, DcApplicationHelper
Defined in:
app/renderers/dc_menu_renderer.rb

Overview

Default menu renderer for dc_menus collection. Renderer produces output for rendering menu with (theoretically) infinite level of sub menus. In practice reasonable maximum level of 4 is advised.

Example (as used in design):

dc_render(:dc_menu, name: 'my_menu')
# when :name option is ommited it will use site document's menu_name field
dc_render(:dc_menu)

Instance Attribute Summary

Attributes included from DcApplicationHelper

#design, #form, #ids, #json_ld, #menu, #menu_item, #options, #page, #page_title, #part, #parts, #record, #record_footer, #site, #tables

Instance Method Summary collapse

Methods included from CmsCommonHelper

#dc_choices4_field, #dc_choices_for_field, dc_choices_for_field, #dc_date_time, #dc_format_date_time, dc_format_date_time, #dc_format_number, dc_format_number, #dc_help_body, #dc_help_button, #dc_help_fields, #dc_help_for_tab, #dc_icon4_boolean, #dc_icon_for_boolean, #dc_name4_id, #dc_name4_value, #dc_name_for_id, #dc_name_for_value, dc_name_for_value, #dc_steps_menu_get, #t, t, #t_label_for_column, #t_label_for_field, #t_tablename

Methods included from DcApplicationHelper

#_origin, #dc_add2_record_cookie, #dc_add_json_ld, #dc_add_meta_tag, #dc_big_table, #dc_big_table_name_for_value, #dc_choices4, #dc_choices4_all_collections, #dc_choices4_folders_list, #dc_choices4_menu, #dc_choices4_site_policies, #dc_cms_menu, #dc_deprecate, #dc_document_path, #dc_dont?, #dc_edit_mode?, #dc_edit_title, #dc_error_messages_for, #dc_flash_messages, #dc_get_json_ld, #dc_get_link_canonical_tag, #dc_get_seo_meta_tags, #dc_get_site, #dc_icon_for_link, #dc_iframe_edit, #dc_img_alt, #dc_img_alt_tag, #dc_internal_var, #dc_limit_string, #dc_link_for_create, #dc_link_for_edit, #dc_link_for_edit1, #dc_link_menu_tag, #dc_link_to, #dc_menu_class, #dc_new_title, #dc_page_bottom, #dc_page_class, #dc_page_edit_menu, #dc_page_top, #dc_render, #dc_render_design, #dc_render_design_part, #dc_render_from_site, #dc_render_partial, #dc_replace_in_design, #dc_submit_tag, #dc_table_title, #dc_user_can_view, #dc_user_has_role, #dc_warning_messages_for, #decamelize_type

Constructor Details

#initialize(parent, opts) ⇒ DcMenuRenderer

Object initialization. Will also prepare DcMenu document.



42
43
44
45
46
47
# File 'app/renderers/dc_menu_renderer.rb', line 42

def initialize( parent, opts ) #:nodoc:
  @parent = parent
  @menu = opts[:name] ? DcMenu.find_by(name: opts[:name].to_s) : DcMenu.find(@parent.site.menu_id)
  @opts = opts
  self
end

Instance Method Details

#defaultObject

Creates default menu.



163
164
165
166
167
168
169
170
171
172
# File 'app/renderers/dc_menu_renderer.rb', line 163

def default
  return "(#{@opts[:name]}) menu not found!" if @menu.nil?

  @selected = find_selected
  html = ''
  html << "<div id='#{@menu.div_name}'>" if @menu.div_name.present?
  html << do_menu_level(@menu, table: 'dc_menu')
  html << "</div>" if @menu.div_name.present?
  html
end

#do_menu_level(menu, options = {}) ⇒ Object

Creates HTML code required for submenu on single level. Subroutine of default.



124
125
126
127
128
129
130
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
156
157
158
# File 'app/renderers/dc_menu_renderer.rb', line 124

def do_menu_level(menu, options = {})
  html = "<ul>"
  if @opts[:edit_mode] > 1
    options[:title] = menu.respond_to?('name') ? menu.name : menu.caption # 1. level or submenus
    options[:id]    = menu._id
    html << link_4edit(options)
  end
  # sort items according to :order
  menu.dc_menu_items.order_by(order: 1).each do |item|
    next unless item.active
    # menu can be hidden from user
    can_view, msg = dc_user_can_view(@parent, item)
    next unless can_view

    html << if @opts[:path]&.include?(item.link)
              %(<li class="menu-selected">#{ link_4menu(item) })
            elsif item.id == @selected.id
              %(<li class="menu-selected">#{ link_4menu(item) })
            else
              "<li>#{ link_4menu(item) }"
            end
    # do submenu
    if item.dc_menu_items.size > 0
      if @opts[:edit_mode] > 1
        opts = options.clone
        opts['ids']   = (opts['ids']   ? "#{opts['ids']};" : '')   + menu._id.to_s
        opts['table'] = (opts['table'] ? "#{opts['table']};" : '') + 'dc_menu_item'
        opts['form_name'] = nil # must be
      end
      html << do_menu_level(item, opts)
    end
    html << '</li>'
  end
  html << '</ul>'
end

#find_selectedObject

Return selected topmenu level.



52
53
54
55
56
57
58
59
60
# File 'app/renderers/dc_menu_renderer.rb', line 52

def find_selected
  if @parent.page.menu_id
    top_menu_id = @parent.page.menu_id
    top_menu_id = @parent.page.menu_id.split(';')[1] if @parent.page.menu_id.match(';')
    ret = @menu.dc_menu_items.find(top_menu_id)
  end
  # return first if not found (something is wrong)
  ret ||= @menu.dc_menu_items[0]
end

Creates edit link if in edit mode.



65
66
67
68
69
70
71
72
# File 'app/renderers/dc_menu_renderer.rb', line 65

def link_4edit(opts) #:nodoc:
  html = ''
  opts.merge!( { controller: 'cmsedit', action: 'edit' } )
  title = "#{t('drgcms.edit')}: "
  opts[:title] = "#{title} #{opts[:title]}"
  
  html << "<li>#{dc_link_for_edit(opts)}</li>"
end

Returns html code required for creating one link in a menu.

Parameters:

item

MenuItem.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/renderers/dc_menu_renderer.rb', line 80

def link_4menu(item)
  # just horizontal line
  return item.caption if item.caption == '<hr>'
  # prepand to link
  link = if !item.link_prepend.blank?
    item.link_prepend
  elsif !@menu.link_prepend.blank?
    @menu.link_prepend
  else
    ''
  end

  if item.link.match('http')
    link = item.link
  else
    link += (item.link[0] == '/' ? '' : '/') + item.link
    link  = '/' + link unless link[0] == '/'   # link should start with '/'
  end

  caption = ''
  unless item.picture.blank? 
    caption = case
      when item.picture[0] == '@' then # call method
        method = item.picture[1,100]   # remove leading @
        return send(method) if respond_to?(method)
        return @parent.send(method) if @parent.respond_to?(method)
        return 'ERROR!'
      when item.picture.match(/\./) then @parent.image_tag(item.picture)
      when item.picture.match('<i') then item.picture
      else
        @parent.fa_icon(item.picture)
    end
    caption << ' '
   end
  # - in first place won't write caption text
  caption = caption.html_safe + (item.caption[0] == '-' ? '' : item.caption.html_safe )
  
  target = item.target.blank? ? nil : item.target
  @parent.link_to(caption, link, {target: target})
end

#render_cssObject

Return CSS part of code.



185
186
187
# File 'app/renderers/dc_menu_renderer.rb', line 185

def render_css
  @menu.css if @menu
end

#render_htmlObject

Renderer dispatcher. Method returns HTML part of code.



177
178
179
180
# File 'app/renderers/dc_menu_renderer.rb', line 177

def render_html
  method = @opts[:method] || 'default'
  respond_to?(method) ? send(method) : "Error DcMenu: Method #{method} doesn't exist!"
end