Class: DcSimpleMenuRenderer

Inherits:
Object
  • Object
show all
Includes:
DcApplicationHelper
Defined in:
app/helpers/dc_simple_menu_renderer.rb

Overview

Before dc_menu dc_simple_menu was the way to provide menu system. Renderer provides 3 different renderer methods: default, as_dropdown, as_table.

Example (as used in design):

dc_render(:dc_simple_menu, name: 'my_menu', method: 'as_table')

If name parameter is omitted it must be provided in site document menu_name field.

Instance Attribute Summary

Attributes included from DcApplicationHelper

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

Instance Method Summary collapse

Methods included from DcApplicationHelper

#_origin, #dc_add2_record_cookie, #dc_big_table, #dc_choices4, #dc_choices4_all_collections, #dc_choices4_cmsmenu, #dc_choices4_field, #dc_choices4_folders_list, #dc_choices4_menu, #dc_choices4_site_policies, #dc_date_time, #dc_deprecate, #dc_dont?, #dc_edit_mode?, #dc_edit_title, #dc_error_messages_for, #dc_flash_messages, #dc_format_date_time, #dc_get_site, #dc_icon4_boolean, #dc_iframe_edit, #dc_internal_var, #dc_label_for, #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_name4_id, #dc_name4_value, #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, #decamelize_type, #forms_merge, #t, #t_name, #t_tablename

Constructor Details

#initialize(parent, opts) ⇒ DcSimpleMenuRenderer

Object initialization.



40
41
42
43
44
45
46
# File 'app/helpers/dc_simple_menu_renderer.rb', line 40

def initialize( parent, opts )
  @parent = parent
  opts[:name] = parent.site.menu_name if opts[:name].nil? # default in site
  @menu = DcSimpleMenu.find_by(name: opts[:name].to_s)
  @opts = opts
  self
end

Instance Method Details

#as_dropdownObject

Creates menu with single level dropdown menu.



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'app/helpers/dc_simple_menu_renderer.rb', line 226

def as_dropdown
  html = link_4edit
  return "#{html}#{@opts[:name]}<br>Menu not found!" if @menu.nil?
  # 
  items = @menu.dc_simple_menu_items.sort {|a,b| a.order <=> b.order}
  @selected = find_selected

  html << "<div id='#{@menu.div_name}'>" unless @menu.div_name.blank?
  html << '<table><tr>'
  # sort items acording to :order 
  items.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
#
    selector = item.id == @selected.id ? 'th' : 'td'
    html << "<#{selector}>#{ link_4menu(item) }"
    y = YAML.load(item.submenu) || {}
    if y.size > 0
      html << '<ul>'
      y.each do |k,v|
        html << "<li>#{@parent.link_to(v['title'], v['link'], {target: v['target']})}</li>"
      end
      html << '</ul>'
    end
    html << "</#{selector}>"

  end
  html << '</tr></table>'
  html << '</div>' unless @menu.div_name.blank?
  html
end

#as_dropdown_oldObject

Creates menu with single level dropdown menu. This is older version of method which also provided select field for selecting menu if mobile device is beeing detected.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'app/helpers/dc_simple_menu_renderer.rb', line 175

def as_dropdown_old
  html = link_4edit
  return "#{html}#{@opts[:name]}<br>Menu not found!" if @menu.nil?
  # 
  items = @menu.dc_simple_menu_items.sort {|a,b| a.order <=> b.order}
# CSS dropdown-s don't work very well on mobiles. Create simple select menu instead 
  if @parent.session[:is_mobile] == 1
    html << "<div class=\"#{@menu.name.downcase}-mobile\">\n"
    html << '<select onchange="window.location.href=this.options[this.selectedIndex].value">'
    html << "<option value=\"\">#{t('drgcms.simple_menu_mobile_menu_text',' M E N U ')}</option>"
#    
    items.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 << "<option value=\"#{item.link}\">#{item.caption}</option>"
      y = YAML.load(item.submenu) || {}
      y.each { |k,v| html << "<option value=\"#{v['link']}\">--#{v['title']}</option>" }
    end    
    html << "</select>\n</div>\n"
  else  
    @selected = find_selected
    html << "<table class=\"#{@menu.name.downcase}\"><tr>"
    # sort items acording to :order  
    items.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
      
      klas = item.id == @selected.id ? 'menu-selected' : 'menu-item'
#      caption = item.caption.match('pic:') ? @parent.image_tag(item.caption.sub('pic:','')) : item.caption
      html << "<td class=\"td-#{klas}\">#{ link_4menu(item) }"
      y = YAML.load(item.submenu) || {}
      if y.size > 0
        html << '<ul>'
        y.each do |k,v|
          html << "<li>#{@parent.link_to(v['title'], v['link'], {target: v['target']})}</li>"
        end
        html << '</ul>'
      end
      html << '</td>'
    end
    html << '</tr></table>'
  end
end

#as_responsiveObject

display menu options evenly justified.



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'app/helpers/dc_simple_menu_renderer.rb', line 151

def as_responsive
  html = link_4edit
  return "#{html}#{@opts[:name]}<br>Menu not found!" if @menu.nil?
#  
  @selected = find_selected
  klas = @opts[:classes] ? @opts[:classes] : 'small-2 middle-4 large-6 columns'
  klas << ' columns' unless klas.match('column')
  klas=''
#  
  items = @menu.dc_simple_menu_items.where(active: true).order(order: 1)
  items.each do |item|
# menu can be hidden from user
    can_view, msg = dc_user_can_view(@parent, item)
    p msg unless can_view
    next unless can_view
    html << "<li class=\"#{klas}#{(item.id == @selected.id) ? 'selected' : 'item'}\">#{ link_4menu(item) }</li>" #
  end
  html
end

#as_tableObject

Renders menu as table. This is single level menu only and uses table elements to display menu options evenly justified.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/helpers/dc_simple_menu_renderer.rb', line 127

def as_table
  html = link_4edit
  return "#{html}#{@opts[:name]}<br>Menu not found!" if @menu.nil?
#  
  @selected = find_selected
# use div_name if specified otherwise menu.name  
  div_name  = (@menu.div_name.to_s.size > 2 ? @menu.div_name : @menu.name).downcase
  html << "<table class=\"#{div_name}\"><tr>"
#
  items = @menu.dc_simple_menu_items.where(active: true).order(order: 1)
  items.each do |item|
# menu can be hidden from user
    can_view, msg = dc_user_can_view(@parent, item)
    next unless can_view
    
    klas = item.id == @selected.id ? "#{div_name}-selected" : "#{div_name}-item"
    html << "<td class=\"td-#{klas}\">#{ link_4menu(item) }</td>" #
  end
  html << "</tr></table>"
end

#defaultObject

Default renderer provides top menu menu with submenu items displayed in a line (div) below.

Top menu and submenu items are styled separately. If div_name is specified in menu document it will be used in div, ul and li CSS names of generated HTML code. If div_name is not defined then document name will be used.



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'app/helpers/dc_simple_menu_renderer.rb', line 267

def default
  html = link_4edit
  return "#{html}#{@opts[:name]}<br>Menu not found!" if @menu.nil?
#  
  @selected = find_selected
# use div_name if specified otherwise menu.name  
  div_name  = (@menu.div_name.to_s.size > 2 ? @menu.div_name : @menu.name).downcase
  html << "<div class=\"#{div_name}\">"
  html << "<ul class=\"ul-#{div_name}\">"
# sort items acording to :order  
  items = @menu.dc_simple_menu_items.sort {|a,b| a.order <=> b.order}
  items.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
    
    klas = item.id == @selected.id ? "#{div_name}-selected" : "#{div_name}-item"
    html << "<li class=\"li-#{klas}\">#{ link_4menu(item) }</li>"
  end
  html << "</ul></div>"
# submenu
  html << "<div class=\"sub-#{div_name}\">
        <ul class=\"ul-sub-#{div_name}\">"
  y = YAML.load(@selected.submenu) rescue []
  if y.class == Hash
    y.each do |k,v|
      html << "<li class=\"li-sub-#{div_name}\">#{@parent.link_to(v['title'], v['link'])}</li>"
    end
  end
  html << '</ul></div>'
end

#find_selectedObject

Return selected top level menu document. Subroutine of menu renders.



51
52
53
54
55
# File 'app/helpers/dc_simple_menu_renderer.rb', line 51

def find_selected #:nodoc:
  ret = @menu.dc_simple_menu_items.find( @parent.page.menu_id ) if @parent.page.menu_id
# return first if not found (something is wrong)
  ret ||= @menu.dc_simple_menu_items[0]
end

Creates edit icon for menu if in edit mode.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/helpers/dc_simple_menu_renderer.rb', line 60

def link_4edit()  #:nodoc:
  html = ''
  return html unless @opts[:edit_mode] > 1
#
  @opts[:editparams].merge!( { table: 'dc_simple_menu', controller: 'cmsedit', action: 'edit' } )
  if @menu # edit, when menu exists
    title = "#{t('drgcms.edit')}: "
    @opts[:editparams].merge!( { id: @menu.id, title: "#{title}#{@menu.name}" } ) 
    html << dc_link_for_edit( @opts[:editparams] )
  else # list available menus when menu does not yet exist
    title = "#{t('drgcms.new')}: "
    title << t('helpers.label.dc_simple_menu.tabletitle')
    @opts[:editparams].merge!( { action: 'index', title: title })
    html << dc_link_for_create( @opts[:editparams] )
  end
  html
end

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

Parameters:

item

SimpleMenuItem.



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
120
121
# File 'app/helpers/dc_simple_menu_renderer.rb', line 84

def link_4menu(item)
# 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.



312
313
314
# File 'app/helpers/dc_simple_menu_renderer.rb', line 312

def render_css
  @menu ? "#{@menu.css}\n #{@selected ? @selected.css : ''}\n" : ''
end

#render_htmlObject

Renderer dispatcher. Method returns HTML part of code.



304
305
306
307
# File 'app/helpers/dc_simple_menu_renderer.rb', line 304

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