drg_cms 0.5.52.5 → 0.5.52.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -253,6 +253,7 @@ def index
253
253
  end
254
254
  end
255
255
  #
256
+ call_callback_method('dc_footer')
256
257
  respond_to do |format|
257
258
  format.html { render action: :index }
258
259
  format.js { render partial: :result }
@@ -328,7 +328,7 @@ def fill_login_data(user, remember_me)
328
328
  # This was previously in dc_user_can. I belive it should be here.
329
329
  #TODO This might not be the best idea. Check in the future.
330
330
  if session[:user_roles].size == 0
331
- guest = DcUserRole.find_by(:system_name => 'guest')
331
+ guest = DcPolicyRole.find_by(:system_name => 'guest')
332
332
  session[:user_roles] << guest.id if guest
333
333
  end
334
334
  # Save remember me cookie if not CMS user and remember me is selected
@@ -47,17 +47,17 @@ result_set:
47
47
  table_class: tclass
48
48
  tr_style: 'color: green;'
49
49
  tr_class: trclass
50
+ tr_class:
51
+ eval: "document['result'] < 0 ? 'color: red;' : 'color: #000;'"
50
52
 
51
53
  actions: standard
52
54
 
53
55
  actions:
56
+
54
57
  1: edit
55
58
  2:
56
59
  type: duplicate
57
60
  dup_fields: name,another_field
58
- td_class: class-name
59
- td_style:
60
- eval: "document['field'] == document['description'] ? 'color: gold;' : 'color: #000;'"
61
61
 
62
62
  3:
63
63
  type: delete
@@ -77,7 +77,12 @@ result_set:
77
77
  1:
78
78
  name: name
79
79
  eval: dc_name4_id,dc_site,name
80
- style: 'align: left; width: 100px'
80
+ width: 10%
81
+ align: right (center)
82
+ style: 'color: red;'
83
+ td_class: class-name
84
+ td_style:
85
+ eval: "document['field'] == document['description'] ? 'color: gold;' : 'color: #000;'"
81
86
  2:
82
87
  name: title
83
88
  3:
@@ -129,6 +134,7 @@ form:
129
134
  type: hidden_field
130
135
  type: readonly
131
136
  type: file_select
137
+ preview: no
132
138
 
133
139
  size: 50 or
134
140
  html:
data/app/forms/dc_ad.yml CHANGED
@@ -15,8 +15,10 @@ result_set:
15
15
  columns:
16
16
  0:
17
17
  name: position
18
+ width: 10%
18
19
  2:
19
20
  name: description
21
+ width: 30%
20
22
  3:
21
23
  name: displayed
22
24
  4:
@@ -19,6 +19,7 @@ result_set:
19
19
  columns:
20
20
  2:
21
21
  name: description
22
+ width: 80%
22
23
 
23
24
  form:
24
25
  title:
@@ -17,6 +17,7 @@ result_set:
17
17
  1:
18
18
  name: name
19
19
  style: "text-align: left;"
20
+ width: 40%
20
21
  2:
21
22
  name: params
22
23
  style: "text-align: left;"
@@ -17,10 +17,9 @@ result_set:
17
17
  columns:
18
18
  10:
19
19
  name: name
20
- style: "text-align: left;"
21
20
  20:
22
21
  name: description
23
- style: "text-align: left;"
22
+ width: 50%
24
23
 
25
24
  form:
26
25
  title:
@@ -1,4 +1,4 @@
1
- ## YAML Template for dc_simple_menu_items
1
+ ## dc_menu_items
2
2
  ---
3
3
  table: dc_menu_item
4
4
 
@@ -14,15 +14,11 @@ result_set:
14
14
  columns:
15
15
  1:
16
16
  name: caption
17
- style: "text-align: left;"
18
17
  2:
19
18
  name: link
20
- style: "text-align: left;"
21
-
22
19
  3:
23
20
  name: order
24
- style: "text-align: right;"
25
-
21
+ align: right
26
22
 
27
23
  form:
28
24
  title:
@@ -35,35 +31,32 @@ form:
35
31
  10:
36
32
  name: caption
37
33
  type: text_field
38
- html:
39
- size: 30
34
+ size: 30
40
35
  20:
41
36
  name: picture
42
37
  type: file_select
43
- html:
44
- size: 50
38
+ size: 50
45
39
  30:
46
40
  name: link
47
41
  type: text_with_select
48
42
  eval: '@parent.dc_page_class.all_pages_for_site(@parent.dc_get_site)'
49
- html:
50
- size: 50
43
+ size: 50
44
+
51
45
  40:
52
46
  name: link_prepend
53
47
  type: text_field
54
- html:
55
- size: 20
48
+ size: 20
56
49
 
57
50
  50:
58
51
  name: target
59
52
  type: text_field
60
- html:
61
- size: 10
53
+ size: 10
54
+
62
55
  60:
63
56
  name: order
64
57
  type: text_field
65
- html:
66
- size: 2
58
+ size: 2
59
+
67
60
  80:
68
61
  name: policy_id
69
62
  type: select
@@ -17,6 +17,7 @@ result_set:
17
17
  columns:
18
18
  1:
19
19
  name: subject
20
+ width: 40%
20
21
  2:
21
22
  name: alt_link
22
23
  3:
@@ -19,6 +19,7 @@ result_set:
19
19
  name: name
20
20
  1:
21
21
  name: description
22
+ width: 30%
22
23
  2:
23
24
  name: div_id
24
25
  4:
@@ -13,10 +13,10 @@ result_set:
13
13
  columns:
14
14
  1:
15
15
  name: name
16
- style: "text-align: left;"
16
+ width: 20%
17
17
  2:
18
18
  name: description
19
- style: "text-align: left;"
19
+ width: 50%
20
20
 
21
21
  form:
22
22
  title:
@@ -32,6 +32,7 @@ form:
32
32
  name: dc_policy_role_id
33
33
  type: select
34
34
  eval: DcPolicyRole.choices4_roles
35
+ width: 30%;
35
36
 
36
37
  20:
37
38
  name: permission
@@ -20,6 +20,7 @@ result_set:
20
20
  name: name
21
21
  2:
22
22
  name: title
23
+ width: 40%
23
24
  3:
24
25
  name: valid_from
25
26
  4:
@@ -17,10 +17,9 @@ result_set:
17
17
  columns:
18
18
  10:
19
19
  name: name
20
- style: "text-align: left;"
21
20
  20:
22
21
  name: description
23
- style: "text-align: left;"
22
+ width: 50%
24
23
 
25
24
  form:
26
25
  title:
@@ -33,25 +32,23 @@ form:
33
32
  10:
34
33
  name: name
35
34
  type: text_field
36
- html:
37
- size: 20
35
+ size: 20
38
36
 
39
37
  20:
40
38
  name: description
41
39
  type: text_field
42
- html:
43
- size: 20
40
+ size: 20
44
41
 
45
42
  30:
46
43
  name: div_name
47
44
  type: text_field
48
- html:
49
- size: 20
45
+ size: 20
46
+
50
47
  40:
51
48
  name: link_prepend
52
49
  type: text_field
53
- html:
54
- size: 20
50
+ size: 20
51
+
55
52
  50:
56
53
  name: dc_site_id
57
54
  type: select
@@ -71,7 +68,6 @@ form:
71
68
  20:
72
69
  name: css
73
70
  type: text_area
74
- html:
75
- size: 100x50
71
+ size: 100x50
76
72
 
77
73
 
@@ -17,15 +17,14 @@ result_set:
17
17
  # style: "text-align: left;"
18
18
  1:
19
19
  name: caption
20
- style: "text-align: left;"
20
+ width: 30%
21
21
  2:
22
22
  name: link
23
- style: "text-align: left;"
24
-
23
+ width: 30%
25
24
  3:
26
25
  name: order
27
26
  style: "text-align: right;"
28
-
27
+ width: 5%
29
28
  form:
30
29
  title:
31
30
  field: caption
@@ -19,6 +19,7 @@ result_set:
19
19
  name: name
20
20
  2:
21
21
  name: description
22
+ width: 80%
22
23
 
23
24
  form:
24
25
  title:
@@ -48,7 +48,7 @@ def dc_actions_for_index()
48
48
  # start div with hidden spinner image
49
49
  html = <<EOT
50
50
  <div id="dc-action-menu">
51
- <span id="dc-spinner" class="div-hidden">#{fa_icon('spinner lg spin')}</span>
51
+ <span class="dc-spinner div-hidden">#{fa_icon('spinner lg spin')}</span>
52
52
  <ul class="dc-action-menu">
53
53
  EOT
54
54
  # Remove actions settings and sort
@@ -155,15 +155,14 @@ def dc_div_filter()
155
155
  html =<<EOT
156
156
  <div id="drgcms_filter" class="div-hidden">
157
157
  <h1>#{t('drgcms.filter_set')}</h1>
158
- <table class="dc-menu"><td>
158
+
159
159
  #{ select(nil, 'filter_field1', options_for_select(choices, field_name), { include_blank: true }) }
160
160
  #{ select(nil, 'filter_oper', options_for_select(choices4_operators, operators_value)) }
161
-
162
- </td>
163
- <td class="dc-link dc-animate drgcms_popup_submit" data-url="#{url}">#{fa_icon('check-square-o')} #{t('drgcms.filter_on')}</td>
164
- <td class="dc-link dc-animate">#{dc_link_to('drgcms.filter_off','close', {action: :index, filter: 'off', table: @form['table'], form_name: params['form_name']}) }</td>
165
- </table>
166
- </div>
161
+ <div class="dc-menu">
162
+ <div class="dc-link dc-animate drgcms_popup_submit" data-url="#{url}">#{fa_icon('check-square-o')} #{t('drgcms.filter_on')}</div>
163
+ <div class="dc-link dc-animate">#{dc_link_to('drgcms.filter_off','close', {action: :index, filter: 'off', table: @form['table'], form_name: params['form_name']}) }</div>
164
+ </div>
165
+ </div>
167
166
  EOT
168
167
  html.html_safe
169
168
  end
@@ -203,18 +202,27 @@ def dc_link_or_ajax(yaml, parms) #:nodoc:
203
202
  end
204
203
 
205
204
  ############################################################################
206
- # Creates actions that could be performed on single row of result set.
205
+ # Determines actions and width of actions column
207
206
  ############################################################################
208
- def dc_actions_for_result(document)
207
+ def dc_actions_column()
209
208
  actions = @form['result_set']['actions']
210
- return '' if actions.nil? or @form['readonly']
211
209
  # standard actions
212
210
  actions = {'standard' => true} if actions.class == String && actions == 'standard'
213
211
  std_actions = {' 2' => 'edit', ' 3' => 'delete'}
214
212
  actions.merge!(std_actions) if actions['standard']
215
213
  #
216
214
  width = @form['result_set']['actions_width'] || 20*actions.size
217
- html = "<td style=\"width: #{width}px;\">"
215
+ [ actions, "<div class=\"actions\" style=\"width: #{width}px;\">" ]
216
+ end
217
+
218
+ ############################################################################
219
+ # Creates actions that could be performed on single row of result set.
220
+ ############################################################################
221
+ def dc_actions_for_result(document)
222
+ actions = @form['result_set']['actions']
223
+ return '' if actions.nil? or @form['readonly']
224
+ #
225
+ actions, html = dc_actions_column()
218
226
  actions.each do |k,v|
219
227
  session[:form_processing] = "result_set:actions: #{k}=#{v}"
220
228
  next if k == 'standard' # ignore standard definition
@@ -259,7 +267,7 @@ def dc_actions_for_result(document)
259
267
  yaml['type'].to_s
260
268
  end
261
269
  end
262
- html << '</td>'
270
+ html << '</div>'
263
271
  html.html_safe
264
272
  end
265
273
 
@@ -267,9 +275,11 @@ end
267
275
  # Creates header div for result set.
268
276
  ############################################################################
269
277
  def dc_header_for_result()
270
- c = ''
271
- actions = @form['result_set']['actions']
272
- c = '<th>&nbsp;</th>' unless actions.nil? or @form['readonly']
278
+ html = '<div class="dc-result-header">'
279
+ if @form['result_set']['actions'] and !@form['readonly']
280
+ ignore, code = dc_actions_column()
281
+ html << code + '</div>'
282
+ end
273
283
  # preparation for sort icon
274
284
  sort_field, sort_direction = nil, nil
275
285
  if session[@form['table']]
@@ -279,8 +289,9 @@ def dc_header_for_result()
279
289
  if (columns = @form['result_set']['columns'])
280
290
  columns.each do |k,v|
281
291
  session[:form_processing] = "result_set:columns: #{k}=#{v}"
282
- th = '<th '
283
- v = {'name' => v} if v.class == String
292
+ #
293
+ th = %Q[<div class="th" style="width: #{v['width'] || '15%'};text-align: #{v['align'] || 'left'};"]
294
+ v = {'name' => v} if v.class == String
284
295
  caption = v['caption'] || t("helpers.label.#{@form['table']}.#{v['name']}")
285
296
  # no sorting when embedded documents or custom filter is active
286
297
  sort_ok = @form['result_set'].nil? || (@form['result_set'] && @form['result_set']['filter'].nil?)
@@ -290,14 +301,14 @@ def dc_header_for_result()
290
301
  if v['name'] == sort_field
291
302
  icon = sort_direction == '1' ? 'sort-alpha-asc lg' : 'sort-alpha-desc lg'
292
303
  end
293
- th << ">#{dc_link_to(caption, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index )}</th>"
304
+ th << ">#{dc_link_to(caption, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}</div>"
294
305
  else
295
- th << ">#{caption}</th>"
306
+ th << ">#{caption}</div>"
296
307
  end
297
- c << th
308
+ html << "<div class=\"spacer\"></div>" + th
298
309
  end
299
310
  end
300
- c.html_safe
311
+ (html << '</div>').html_safe
301
312
  end
302
313
 
303
314
  ############################################################################
@@ -347,7 +358,7 @@ end
347
358
  ############################################################################
348
359
  def dc_style_or_class(selector, yaml, value, record)
349
360
  return '' if yaml.nil?
350
- # alias record and value so both names can be used
361
+ # alias record and value so both names can be used in eval
351
362
  field = value
352
363
  document = record
353
364
  html = selector ? "#{selector}=\"" : ''
@@ -364,9 +375,9 @@ end
364
375
  # Creates tr code for each row of result set.
365
376
  ############################################################################
366
377
  def dc_row_for_result(document)
367
- clas = "dc-#{cycle('odd','even')} " + dc_style_or_class(nil,@form['result_set']['tr_class'],nil,document)
368
- style = dc_style_or_class('style',@form['result_set']['tr_style'],nil,document)
369
- "<tr class=\"#{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
378
+ clas = "dc-#{cycle('odd','even')} " + dc_style_or_class(nil, @form['result_set']['tr_class'], nil, document)
379
+ style = dc_style_or_class('style', @form['result_set']['tr_style'], nil, document)
380
+ "<div class=\"dc-result-data #{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
370
381
  end
371
382
 
372
383
  ############################################################################
@@ -419,10 +430,19 @@ def dc_columns_for_result(document)
419
430
  "!!! #{v['name']}"
420
431
  end
421
432
  #
422
- td = '<td '
423
- td << dc_style_or_class('class',v['td_class'],value,document)
424
- td << dc_style_or_class('style',v['td_style'] || v['style'],value,document)
425
- html << "#{td}>#{value}</td>"
433
+ td = '<div class="spacer"></div><div class="td" '
434
+ td << dc_style_or_class('class', v['td_class'], value, document)
435
+
436
+ width_align = %Q[width: #{v['width'] || '15%'};text-align: #{v['align'] || 'left'};]
437
+ style = dc_style_or_class('style', v['td_style'] || v['style'], value, document)
438
+ style = if style.size > 1
439
+ # remove trailing " add width and add trailing " back
440
+ style.slice(0..-1) + width_align + '"'
441
+ else
442
+ # create style string
443
+ "style=\"#{width_align}\""
444
+ end
445
+ html << "#{td} #{style}>#{value}</div>"
426
446
  end
427
447
  html.html_safe
428
448
  end
@@ -470,7 +490,7 @@ def dc_actions_for_form()
470
490
  # Sort so that standard actions come first
471
491
  actions = actions.to_a.sort {|x,y| x[0].to_s <=> y[0].to_s}
472
492
  # Add spinner to the beginning
473
- c = %Q[<td id="dc-spinner" class="div-hidden">#{fa_icon('spinner lg spin')}</td>]
493
+ c = %Q[<span class="dc-spinner div-hidden">#{fa_icon('spinner lg spin')}</span><ul class="dc-menu">]
474
494
 
475
495
  actions.each do |element|
476
496
  session[:form_processing] = "form:actions: #{element}"
@@ -487,7 +507,7 @@ def dc_actions_for_form()
487
507
  if v.class == String
488
508
  next if params[:readonly] and !(v == 'back')
489
509
 
490
- c << '<td class="dc-link dc-animate">'
510
+ c << '<li class="dc-link dc-animate">'
491
511
  c << case
492
512
  when (v == 'back' or v == 'cancle') then
493
513
  # If return_to is present link directly to URL
@@ -525,18 +545,18 @@ def dc_actions_for_form()
525
545
  when v['type'] == 'submit'
526
546
  caption = v['caption'] || 'drgcms.save'
527
547
  icon = v['icon'] || 'save'
528
- '<td class="dc-link-submit dc-animate">' +
548
+ '<li class="dc-link-submit dc-animate">' +
529
549
  dc_submit_tag(caption, icon, {:data => v['params'], :title => v['title']}) +
530
- '</td>'
550
+ '</li>'
531
551
  # delete with some sugar added
532
552
  when v['type'] == 'delete'
533
553
  parms['id'] = @record.id
534
554
  parms.merge!(v['params'])
535
555
  caption = v['caption'] || 'drgcms.delete'
536
556
  icon = v['icon'] || 'remove'
537
- '<td class="dc-link dc-animate">' +
557
+ '<li class="dc-link dc-animate">' +
538
558
  dc_link_to( caption, icon, parms, data: t('drgcms.confirm_delete'), method: :delete ) +
539
- '</td>'
559
+ '</li>'
540
560
  # ajax or link button
541
561
  when v['type'] == 'ajax' || v['type'] == 'link'
542
562
  parms = {}
@@ -556,7 +576,7 @@ def dc_actions_for_form()
556
576
  end
557
577
  # Error if controller param is missing
558
578
  if parms['controller'].nil?
559
- "<td>#{t('drgcms.error')}</td>"
579
+ "<li>#{t('drgcms.error')}</li>"
560
580
  else
561
581
  v['caption'] ||= v['text']
562
582
  caption = t("#{v['caption'].downcase}", v['caption'])
@@ -564,11 +584,11 @@ def dc_actions_for_form()
564
584
  request = v['request'] || v['method'] || 'get'
565
585
  icon = v['icon'] ? "#{fa_icon(v['icon'])} " : ''
566
586
  if v['type'] == 'ajax' # ajax button
567
- %Q[<td class="dc-link-ajax dc-animate" id="dc-submit-ajax" data-url="#{url}"
568
- data-request="#{request}" title="#{v['title']}">#{icon}#{caption}</td>]
587
+ %Q[<li class="dc-link-ajax dc-animate" id="dc-submit-ajax" data-url="#{url}"
588
+ data-request="#{request}" title="#{v['title']}">#{icon}#{caption}</li>]
569
589
  else # link button
570
590
  # %Q[<td class="dc-link dc-animate" title="#{v['title']}><a href="#{url}">#{icon}#{caption}</a></td>]
571
- %Q[<td class="dc-link dc-animate">#{dc_link_to(v['caption'],v['icon'], parms)}</td>]
591
+ %Q[<li class="dc-link dc-animate">#{dc_link_to(v['caption'],v['icon'], parms)}</li>]
572
592
  end
573
593
  end
574
594
  # Javascript action
@@ -576,13 +596,13 @@ def dc_actions_for_form()
576
596
  # v['caption'] ||= 'Caption missing!'
577
597
  # caption = t("#{v['caption'].downcase}", v['caption'])
578
598
  data = {'request' => 'script', 'script' => v['js']}
579
- %Q[<td class="dc-link-ajax dc-animate">#{ dc_link_to(v['caption'],v['icon'], '#', data: data ) }</td>]
599
+ %Q[<li class="dc-link-ajax dc-animate">#{ dc_link_to(v['caption'],v['icon'], '#', data: data ) }</li>]
580
600
  else
581
- '<td>err2</td>'
601
+ '<li>err2</li>'
582
602
  end
583
603
  end
584
604
  end
585
- c.html_safe
605
+ (c << '</ul>').html_safe
586
606
  end
587
607
 
588
608
  ############################################################################
@@ -591,13 +611,12 @@ end
591
611
  def dc_background_for_result(start)
592
612
  if start == :start
593
613
  html = '<div class="dc-result-div" '
594
- html << (@form['result_set']['table_style'] ? "style=\"overflow-x: scroll;\" >" : '>')
595
- html << "\n"
614
+ html << (@form['result_set']['table_style'] ? 'style="overflow-x: scroll;" >' : '>')
596
615
  #
597
- html << "<table class=\"dc-result #{@form['result_set']['table_class']}\" "
616
+ html << "\n<div class=\"dc-result #{@form['result_set']['table_class']}\" "
598
617
  html << (@form['result_set']['table_style'] ? "style=\"#{@form['result_set']['table_style']}\" >" : '>')
599
618
  else
600
- html = '</table></div>'
619
+ html = '</div></div>'
601
620
  end
602
621
  html.html_safe
603
622
  end
@@ -776,29 +795,22 @@ end
776
795
  ############################################################################
777
796
  def dc_document_statistics
778
797
  return '' if @record.new_record? or dc_dont?(@form['form']['info'])
779
- html = "<div id='dc-document-info'>#{t('drgcms.doc_info')}</div>"
780
- # html = "<div id='dc-document-info'>#{fa_icon 'info-circle 2x'}</div>"
781
- html = '<div id="dc-document-info">' + fa_icon('info-circle lg') + '</div>'
798
+ html = %Q[<div id="dc-document-info">#{fa_icon('info-circle lg')}</div> <div id="dc-document-info-popup" class="div-hidden"> ]
782
799
  #
783
- html << "<div id='dc-document-info-popup' class='div-hidden'><table>"
784
800
  u = _get_user_for('created_by')
785
- html << "<tr><td>#{t('drgcms.created_by', 'Created by')}: </td><td><b>#{u}</td></tr>" if u
801
+ html << %Q[<div><span>#{t('drgcms.created_by', 'Created by')}: </span><span>#{u}</span></div>] if u
786
802
  u = _get_user_for('updated_by')
787
- html << "<tr><td>#{t('drgcms.updated_by', 'Updated by')}: </td><td><b>#{u}</td></tr>" if u
788
- html << "<tr><td>#{t('drgcms.created_at', 'Created at')}: </td><td><b>#{dc_format_value(@record.created_at)}</td></tr>" if @record['created_at']
789
- html << "<tr><td>#{t('drgcms.updated_at', 'Updated at')}: </td><td><b>#{dc_format_value(@record.updated_at)}</td></tr>" if @record['updated_at']
790
- html << '</table>'
791
- # Copy to clipboard icon
803
+ html << %Q[<div><span>#{t('drgcms.updated_by', 'Updated by')}: </span><span>#{u}</span></div>] if u
804
+ html << %Q[<div><span>#{t('drgcms.created_at', 'Created at')}: </span><span>#{dc_format_value(@record.created_at)}</span></div>] if @record['created_at']
805
+ html << %Q[<div><span>#{t('drgcms.updated_at', 'Updated at')}: </span><span>#{dc_format_value(@record.updated_at)}</span></div>] if @record['updated_at']
806
+ # copy to clipboard icon
792
807
  parms = params.clone
793
808
  parms[:controller] = 'dc_common'
794
809
  parms[:action] = 'copy_clipboard'
795
810
  url = url_for(parms.permit!)
796
- # caption = image_tag('drg_cms/copy.png', title: t('drgcms.doc_copy_clipboard'))
797
- # html << %Q[<hr><img class="dc-link-img dc-link-ajax dc-animate" data-url="#{url}" data-request="get" #{caption}]
798
811
  html << fa_icon('copy 2x', class: 'dc-link-img dc-link-ajax dc-animate',
799
812
  'data-url' => url, 'data-request' => 'get', title: t('drgcms.doc_copy_clipboard') )
800
- (html << '</div>').html_safe
801
- # html.html_safe
813
+ (html << '</div></div>').html_safe
802
814
  end
803
815
 
804
816
  end