drg_cms 0.6.0.1 → 0.6.1.1.1

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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +454 -145
  3. data/app/assets/javascripts/drg_cms_application.js +1 -1
  4. data/app/assets/stylesheets/drg_cms/drg_cms.css +635 -244
  5. data/app/assets/stylesheets/drg_cms/select-multiple.css +18 -12
  6. data/app/assets/stylesheets/drg_cms_cms.css +1 -1
  7. data/app/controllers/cmsedit_controller.rb +515 -335
  8. data/app/controllers/dc_application_controller.rb +378 -111
  9. data/app/controllers/dc_common_controller.rb +105 -14
  10. data/app/{controllers → controls}/browse_models_control.rb +0 -0
  11. data/app/controls/dc_help_control.rb +126 -0
  12. data/app/{controllers → controls}/dc_page_control.rb +24 -8
  13. data/app/controls/dc_poll_result_control.rb +88 -0
  14. data/app/controls/dc_report.rb +223 -0
  15. data/app/{controllers → controls}/design_element_settings_control.rb +0 -0
  16. data/app/forms/all_options.yml +44 -9
  17. data/app/forms/cms_menu.yml +28 -18
  18. data/app/forms/dc_ad.yml +11 -22
  19. data/app/forms/dc_big_table.yml +1 -0
  20. data/app/forms/dc_big_table_value.yml +1 -0
  21. data/app/forms/dc_category.yml +2 -1
  22. data/app/forms/dc_design.yml +20 -16
  23. data/app/forms/dc_filter.yml +3 -6
  24. data/app/forms/dc_help_1.yml +109 -0
  25. data/app/forms/dc_journal.yml +3 -1
  26. data/app/forms/dc_json_ld.yml +59 -0
  27. data/app/forms/dc_key_value.yml +32 -0
  28. data/app/forms/dc_link.yml +1 -1
  29. data/app/forms/dc_menu.yml +2 -0
  30. data/app/forms/dc_menu_item.yml +2 -0
  31. data/app/forms/dc_page.yml +3 -5
  32. data/app/forms/dc_part.yml +1 -0
  33. data/app/forms/dc_piece.yml +1 -0
  34. data/app/forms/dc_poll.yml +15 -5
  35. data/app/forms/dc_poll_item.yml +2 -1
  36. data/app/forms/dc_poll_result.yml +83 -0
  37. data/app/forms/dc_poll_result_export.yml +35 -0
  38. data/app/forms/dc_seo.yml +33 -0
  39. data/app/forms/dc_simple_menu.yml +2 -0
  40. data/app/forms/dc_site.yml +4 -12
  41. data/app/forms/dc_user.yml +27 -11
  42. data/app/forms/dc_user_role.yml +3 -0
  43. data/app/forms/json_ld_schema.yml +168 -0
  44. data/app/helpers/cms_common_helper.rb +375 -0
  45. data/app/helpers/cms_edit_helper.rb +506 -0
  46. data/app/helpers/cms_helper.rb +268 -0
  47. data/app/helpers/cms_index_helper.rb +580 -0
  48. data/app/helpers/dc_application_helper.rb +218 -306
  49. data/app/models/concerns/dc_page_concern.rb +40 -6
  50. data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
  51. data/app/models/concerns/dc_seo_concern.rb +66 -0
  52. data/app/models/concerns/dc_site_concern.rb +67 -44
  53. data/app/models/concerns/dc_user_concern.rb +57 -18
  54. data/app/models/dc_design.rb +30 -18
  55. data/app/models/dc_filter.rb +22 -13
  56. data/app/models/dc_json_ld.rb +152 -0
  57. data/app/models/dc_key_value.rb +48 -0
  58. data/app/models/dc_key_value_store.rb +1 -0
  59. data/app/models/dc_memory.rb +8 -1
  60. data/app/models/dc_page.rb +0 -1
  61. data/app/models/dc_permission.rb +49 -9
  62. data/app/models/dc_policy.rb +25 -14
  63. data/app/models/dc_policy_role.rb +22 -11
  64. data/app/models/dc_poll.rb +39 -19
  65. data/app/models/dc_poll_result.rb +46 -0
  66. data/app/models/dc_temp.rb +140 -0
  67. data/app/models/dc_user_role.rb +2 -2
  68. data/app/models/drgcms_form_fields.rb +12 -1
  69. data/app/models/drgcms_form_fields/action.rb +61 -0
  70. data/app/models/drgcms_form_fields/comment.rb +8 -4
  71. data/app/models/drgcms_form_fields/date_picker.rb +11 -9
  72. data/app/models/drgcms_form_fields/date_select.rb +1 -1
  73. data/app/models/drgcms_form_fields/datetime_picker.rb +12 -10
  74. data/app/models/drgcms_form_fields/datetime_select.rb +1 -1
  75. data/app/models/drgcms_form_fields/drgcms_field.rb +55 -9
  76. data/app/models/drgcms_form_fields/embedded.rb +26 -16
  77. data/app/models/drgcms_form_fields/file_field.rb +52 -0
  78. data/app/models/drgcms_form_fields/file_select.rb +2 -2
  79. data/app/models/drgcms_form_fields/hash_field.rb +90 -0
  80. data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
  81. data/app/models/drgcms_form_fields/html_field.rb +1 -1
  82. data/app/models/drgcms_form_fields/link_to.rb +2 -2
  83. data/app/models/drgcms_form_fields/method.rb +66 -0
  84. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +23 -14
  85. data/app/models/drgcms_form_fields/number_field.rb +15 -6
  86. data/app/models/drgcms_form_fields/radio.rb +96 -0
  87. data/app/models/drgcms_form_fields/readonly.rb +2 -2
  88. data/app/models/drgcms_form_fields/select.rb +92 -29
  89. data/app/models/drgcms_form_fields/text_area.rb +1 -1
  90. data/app/models/drgcms_form_fields/text_autocomplete.rb +31 -17
  91. data/app/models/drgcms_form_fields/text_field.rb +1 -1
  92. data/app/models/drgcms_form_fields/text_with_select.rb +6 -3
  93. data/app/models/drgcms_form_fields/tree_select.rb +15 -4
  94. data/app/{helpers → renderers}/dc_ad_renderer.rb +0 -0
  95. data/app/{helpers → renderers}/dc_big_menu_renderer.rb +1 -0
  96. data/app/{helpers → renderers}/dc_captcha_renderer.rb +0 -0
  97. data/app/{helpers → renderers}/dc_common_renderer.rb +0 -0
  98. data/app/{helpers → renderers}/dc_gallery_renderer.rb +1 -0
  99. data/app/{helpers → renderers}/dc_menu_renderer.rb +11 -4
  100. data/app/{helpers → renderers}/dc_page_renderer.rb +1 -0
  101. data/app/{helpers → renderers}/dc_part_renderer.rb +5 -4
  102. data/app/{helpers → renderers}/dc_piece_renderer.rb +1 -1
  103. data/app/{helpers → renderers}/dc_poll_renderer.rb +91 -64
  104. data/app/{helpers → renderers}/dc_renderer.rb +1 -0
  105. data/app/{helpers → renderers}/dc_simple_menu_renderer.rb +1 -0
  106. data/app/views/cmsedit/{remove_edit_stuff.js.erb → __remove_edit_stuff.js.erb} +0 -0
  107. data/app/views/cmsedit/{show.html.erb → __show.html.erb} +0 -0
  108. data/app/views/cmsedit/_edit_stuff.html.erb +4 -25
  109. data/app/views/cmsedit/_form.html.erb +4 -3
  110. data/app/views/cmsedit/_result.html.erb +2 -3
  111. data/app/views/cmsedit/edit.html.erb +4 -1
  112. data/app/views/cmsedit/index.html.erb +7 -1
  113. data/app/views/cmsedit/new.html.erb +3 -1
  114. data/app/views/dc_common/_help.html.erb +17 -0
  115. data/app/views/layouts/models.html.erb +2 -1
  116. data/config/locales/drgcms_en.yml +27 -3
  117. data/config/locales/drgcms_sl.yml +32 -5
  118. data/config/locales/models_en.yml +65 -17
  119. data/config/locales/models_sl.yml +69 -18
  120. data/drg_cms.gemspec +1 -1
  121. data/lib/drg_cms.rb +61 -1
  122. data/lib/drg_cms/version.rb +1 -1
  123. data/lib/generators/new_drg_form/new_drg_form_generator.rb +9 -2
  124. data/lib/tasks/database.rake +6 -56
  125. metadata +73 -54
  126. data/app/assets/stylesheets/drg_cms/__jquery-ui.css +0 -339
  127. data/app/helpers/application_helper.rb +0 -2
  128. data/app/helpers/cmsedit_helper.rb +0 -888
  129. data/app/models/dc_dummy.rb +0 -102
  130. data/test/fixtures/drg_cms_test_data.rb +0 -87
@@ -58,6 +58,8 @@ attr_accessor :parts
58
58
  attr_accessor :record
59
59
  #
60
60
  attr_accessor :record_footer
61
+ # json_ld
62
+ attr_reader :json_ld
61
63
 
62
64
  ############################################################################
63
65
  # When @parent is present then helper methods are called from parent class otherwise
@@ -96,6 +98,7 @@ def dc_render(renderer, opts={})
96
98
  #
97
99
  opts[:edit_mode] = session[:edit_mode]
98
100
  opts[:editparams] = {}
101
+
99
102
  opts = @options.merge(opts) # merge options with parameters passed on site, page, design ...
100
103
  opts.symbolize_keys! # this makes lots of things easier
101
104
  # Create renderer object
@@ -240,8 +243,8 @@ end
240
243
  # Helper for adding additional css and javascript code added by documents
241
244
  # and renderers during page rendering.
242
245
  ########################################################################
243
- def dc_page_bottom()
244
- %Q[<style type="text/css">#{@css}</style>#{javascript_tag @js}].html_safe
246
+ def dc_page_bottom
247
+ %(<style type="text/css">#{@css}</style>#{javascript_tag @js}).html_safe
245
248
  end
246
249
 
247
250
  ############################################################################
@@ -255,10 +258,16 @@ end
255
258
  # Returns:
256
259
  # String. HTML code for title.
257
260
  ############################################################################
258
- def dc_table_title(text, result_set=nil)
259
- c = %Q[<div class="dc-title">#{text}]
261
+ def dc_table_title(text, result_set = nil)
262
+ c = %(<div class="dc-title">#{text})
263
+ # help button
264
+ type = result_set.nil? ? 'form' : 'index'
265
+ form_name = params[:form_name] || params[:table]
266
+ url = url_for(controller: :dc_common, action: :help, type: type, form_name: form_name)
267
+ c << %(<div class="dc-help dc-link-ajax" data-url=#{url}>#{fa_icon('question-circle')}</div>)
268
+
260
269
  if result_set and result_set.respond_to?(:current_page)
261
- c << %Q[<div class="dc-paginate">#{paginate(result_set, :params => {:action => 'index'})}</div>]
270
+ c << %(<div class="dc-paginate">#{paginate(result_set, :params => {action: 'index', clear: 'no', filter: nil})}</div>)
262
271
  end
263
272
  c << '<div style="clear: both;"></div></div>'
264
273
  c.html_safe
@@ -270,7 +279,8 @@ end
270
279
  # Returns:
271
280
  # String. HTML code for title.
272
281
  ############################################################################
273
- def dc_edit_title()
282
+ def dc_edit_title
283
+ session[:form_processing] = "form:title:"
274
284
  title = @form['form']['title']
275
285
  # defined as form:title:edit
276
286
  if title and title['edit'] and !@form['readonly']
@@ -297,6 +307,7 @@ end
297
307
  # String. HTML code for title.
298
308
  ############################################################################
299
309
  def dc_new_title()
310
+ session[:form_processing] = "form:title:"
300
311
  title = @form['form']['title']
301
312
  # defined as form:title:new
302
313
  if title and title['new']
@@ -347,8 +358,24 @@ def dc_submit_tag(caption, icon, parms, rest={})
347
358
  end
348
359
  end
349
360
  html = icon_image || ''
350
- html << submit_tag(t(caption, caption), parms)
361
+ #html << submit_tag(t(caption, caption), parms)
362
+ %Q[<button type="submit" class="dc-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>].html_safe
351
363
  end
364
+
365
+ ############################################################################
366
+ # Returns icon code if icon is specified
367
+ ############################################################################
368
+ def dc_icon_for_link(icon)
369
+ return nil unless icon
370
+ if icon.match(/\./)
371
+ _origin.image_tag(icon, class: 'dc-link-img dc-animate')
372
+ elsif icon.match('<i')
373
+ icon
374
+ else
375
+ _origin.fa_icon(icon)
376
+ end
377
+ end
378
+
352
379
  ############################################################################
353
380
  # Similar to rails link_to, but also takes care of link icon, translation, ...
354
381
  ############################################################################
@@ -357,22 +384,13 @@ def dc_link_to(caption, icon, parms, rest={})
357
384
  if parms.class == Hash
358
385
  parms.stringify_keys!
359
386
  rest.stringify_keys!
360
- rest['class'] = rest['class'].to_s + ' dc-animate'
387
+ rest['class'] = rest['class'].to_s + ' dc-animate' unless rest['class'].to_s.match('dc-animate')
361
388
  rest['target'] ||= parms.delete('target')
362
389
  parms['controller'] ||= 'cmsedit'
363
390
  icon_pos = parms.delete('icon_pos') || 'first'
364
391
  end
365
392
  #
366
- if icon
367
- icon_image = if icon.match(/\./)
368
- _origin.image_tag(icon, class: 'dc-link-img dc-animate')
369
- elsif icon.match('<i')
370
- icon
371
- else
372
- _origin.fa_icon(icon)
373
- end
374
- end
375
- #
393
+ icon_image = dc_icon_for_link(icon)
376
394
  if caption
377
395
  caption = t(caption, caption)
378
396
  icon_image << ' ' if icon_image
@@ -389,23 +407,31 @@ end
389
407
  # String. HTML code formatted for display.
390
408
  ####################################################################
391
409
  def dc_flash_messages()
392
- err = _origin.flash[:error]
393
- war = _origin.flash[:warning]
394
- inf = _origin.flash[:info]
395
- note = _origin.flash[:note]
410
+ err = _origin.flash[:error]
411
+ war = _origin.flash[:warning]
412
+ inf = _origin.flash[:info]
413
+ note = _origin.flash[:note]
414
+ html = ''
396
415
  unless err.nil? and war.nil? and inf.nil? and note.nil?
397
- c = ''
398
- c << "<div class=\"dc-form-error\">#{err}</div>" if err
399
- c << "<div class=\"dc-form-warning\">#{war}</div>" if war
400
- c << "<div class=\"dc-form-info\">#{inf}</div>" if inf
401
- c << note if note
416
+ html << "<div class=\"dc-form-error\">#{err}</div>" if err
417
+ html << "<div class=\"dc-form-warning\">#{war}</div>" if war
418
+ html << "<div class=\"dc-form-info\">#{inf}</div>" if inf
419
+ html << note if note
402
420
  _origin.flash[:error] = nil
403
421
  _origin.flash[:warning] = nil
404
422
  _origin.flash[:info] = nil
405
423
  _origin.flash[:note] = nil
406
-
407
- c.html_safe
408
424
  end
425
+ # Update fields on the form
426
+ if _origin.flash[:update]
427
+ html << "<div class=\"dc-form-updates\">\n"
428
+ _origin.flash[:update].each do |field, value|
429
+ html << %Q[<div data-field="#{field}" data-value="#{value}"></div>\n]
430
+ end
431
+ html << '</div>'
432
+ _origin.flash[:update] = nil
433
+ end
434
+ html.html_safe
409
435
  end
410
436
 
411
437
  ########################################################################
@@ -570,12 +596,13 @@ end
570
596
  # Returns:
571
597
  # String. HTML code required for manipulation of currently processed document.
572
598
  ########################################################################
573
- def dc_page_edit_menu(opts=@opts)
599
+ def dc_page_edit_menu(opts = @opts)
574
600
  opts[:edit_mode] ||= _origin.session[:edit_mode]
575
601
  return '' if opts[:edit_mode] < 2
576
- # save some data to cookie. This can not go to session.
602
+
603
+ # save some data to cookie. This can not go to session.
577
604
  page = opts[:page] || @page
578
- table = _origin.site.page_table
605
+ table = _origin.site.page_class.underscore
579
606
  kukis = { "#{table}.dc_design_id" => page.dc_design_id,
580
607
  # "#{table}.menu_id" => page.menu_id,
581
608
  "#{table}.kats" => page.kats,
@@ -587,19 +614,17 @@ def dc_page_edit_menu(opts=@opts)
587
614
  opts[:editparams] ||= {}
588
615
  dc_link_menu_tag(title) do |html|
589
616
  opts[:editparams].merge!( controller: 'cmsedit', action: 'edit', 'icon' => 'edit' )
590
- opts[:editparams].merge!( :id => page.id, :table => _origin.site.page_table, form_name: opts[:form_name], edit_only: 'body' )
617
+ opts[:editparams].merge!( :id => page.id, :table => _origin.site.page_class.underscore, form_name: opts[:form_name], edit_only: 'body' )
591
618
  html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_content') )
592
619
 
593
- # opts[:editparams][:edit_only] = nil
594
620
  opts[:editparams].merge!( edit_only: nil, 'icon' => 'pencil' )
595
621
  html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_advanced') )
596
622
 
597
- # opts[:editparams][:action] = 'new'
598
623
  opts[:editparams].merge!( action: 'new', 'icon' => 'plus' )
599
624
  html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_new_page') )
600
625
 
601
626
  opts[:editparams].merge!(ids: page.id, form_name: 'dc_part', 'icon' => 'plus-square-o',
602
- table: "#{_origin.site.page_table};dc_part" )
627
+ table: "#{_origin.site.page_class.underscore};dc_part" )
603
628
  html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_new_part') )
604
629
  end.html_safe
605
630
  end
@@ -616,9 +641,8 @@ end
616
641
  # type: text_with_select
617
642
  # eval: 'dc_page_class.all_pages_for_site(@parent.dc_get_site)'
618
643
  ########################################################################
619
- def dc_page_class()
620
- # dc_get_site.page_class.classify.constantize
621
- dc_get_site.page_table.classify.constantize
644
+ def dc_page_class
645
+ dc_get_site.page_klass
622
646
  end
623
647
 
624
648
  ########################################################################
@@ -632,228 +656,10 @@ end
632
656
  # type: tree_view
633
657
  # eval: 'dc_menu_class.all_menus_for_site(@parent.dc_get_site)'
634
658
  ########################################################################
635
- def dc_menu_class()
659
+ def dc_menu_class
636
660
  dc_get_site.menu_class.classify.constantize
637
661
  end
638
662
 
639
-
640
- ####################################################################
641
- # Wrapper for i18 t method, with some spice added. If translation is not found English
642
- # translation value will be returned. And if still not found default value will be returned if passed.
643
- #
644
- # Parameters:
645
- # [key] String. String to be translated into locale.
646
- # [default] String. Value returned if translation is not found.
647
- #
648
- # Example:
649
- # t('translate.this','Enter text for ....')
650
- #
651
- # Returns:
652
- # String. Translated text.
653
- ####################################################################
654
- def t(key, default=nil)
655
- c = I18n.t(key)
656
- if c.class == Hash or c.match( 'translation missing' )
657
- c = I18n.t(key, locale: 'en')
658
- # Still not found. Return default if set
659
- if c.class == Hash or c.match( 'translation missing' )
660
- c = default.nil? ? key : default
661
- end
662
- end
663
- c
664
- end
665
-
666
- ####################################################################
667
- # Returns table (collection) name translation for usage in dialog title. Tablename
668
- # title is provided by helpers.label.table_name.tabletitle locale.
669
- #
670
- # Parameters:
671
- # [tablename] String. Table (collection) name to be translated.
672
- # [default] String. Value returned if translation is not found.
673
- #
674
- # Returns:
675
- # String. Translated text.
676
- ####################################################################
677
- def t_tablename(tablename, default=nil)
678
- t('helpers.label.' + tablename + '.tabletitle', default || tablename)
679
- end
680
-
681
- ############################################################################
682
- # Returns label for field translated to current locale for usage on data entry form.
683
- # Translation is provided by lang.helpers.label.table_name.field_name locale. If
684
- # translation is not found method will capitalize field_name and replace '_' with ' '.
685
- ############################################################################
686
- def t_name(field_name, default='')
687
- c = t("helpers.label.#{@form['table']}.#{field_name}", default)
688
- c = field_name.capitalize.gsub('_',' ') if c.match( 'translation missing' )
689
- c
690
- end
691
-
692
- ############################################################################
693
- # When select field is used on form options for select can be provided by
694
- # helpers.label.table_name.choices4_name locale. This is how select
695
- # field options are translated. Method returns selected choice translated
696
- # to current locale.
697
- #
698
- # Parameters:
699
- # [model] String. Table (collection) model name (lowercase).
700
- # [field] String. Field name used.
701
- # [value] String. Value of field which translation will be returned.
702
- #
703
- # Example:
704
- # # usage in program. Choice values for state are 'Deactivated:0,Active:1,Waiting:2'
705
- # dc_name4_value('dc_user', 'state', @record.active )
706
- #
707
- # # usage in form
708
- # columns:
709
- # 2:
710
- # name: state
711
- # eval: dc_name4_value dc_user, state
712
- #
713
- # Returns:
714
- # String. Descriptive text (translated) for selected choice value.
715
- ############################################################################
716
- def dc_name4_value(model, field, value)
717
- return '' if value.nil?
718
- c = t('helpers.label.' + model + '.choices4_' + field )
719
- a = c.chomp.split(',').inject([]) {|r,v| r << v.split(':') }
720
- a.each {|e| return e.first if e.last.to_s == value.to_s }
721
- ''
722
- end
723
-
724
- ############################################################################
725
- # Return choices for field in model if choices are defined in localization text.
726
- #
727
- # Parameters:
728
- # [model] String. Table (collection) model name (lowercase).
729
- # [field] String. Field name used.
730
- #
731
- # Example:
732
- # dc_choices4_field('dc_user', 'state' )
733
- #
734
- # Returns:
735
- # Array. Choices for select input field
736
- ############################################################################
737
- def dc_choices4_field(model, field)
738
- c = t('helpers.label.' + model + '.choices4_' + field )
739
- return ['error'] if c.match( 'translation missing' )
740
- c.chomp.split(',').inject([]) {|r,v| r << v.split(':') }
741
- end
742
-
743
- ############################################################################
744
- # Will return descriptive text for id key when field in one table (collection) has belongs_to
745
- # relation to other table.
746
- #
747
- # Parameters:
748
- # [model] String. Table (collection) model name (lowercase).
749
- # [field] String. Field name holding the value of descriptive text.
750
- # [field_name] String. ID field name. This is by default id, but can be any other
751
- # (preferred unique) field.
752
- # [value] Value of id_field. Usually a BSON Key but can be any other data type.
753
- #
754
- # Example:
755
- # # usage in program.
756
- # dc_name4_id('dc_user', 'name', nil, dc_page.created_by)
757
- #
758
- # # usage in form
759
- # columns:
760
- # 2:
761
- # name: site_id
762
- # eval: dc_name4_id,site,name
763
- # # username is saved to document instead of user.id field
764
- # 5:
765
- # name: user
766
- # eval: dc_name4_id,dc_user,name,username
767
- #
768
- # Returns:
769
- # String. Name (descriptive value) for specified key in table.
770
- ############################################################################
771
- def dc_name4_id(model, field, field_name, id=nil)
772
- return '' if id.nil?
773
- field_name ||= 'id'
774
- model = model.strip.classify.constantize if model.class == String
775
- rec = Mongoid::QueryCache.cache { model.find_by(field_name.strip.to_sym => id) }
776
- rec.nil? ? '' : (rec.send(field) rescue 'not defined')
777
- end
778
-
779
- ############################################################################
780
- # Return html code for icon presenting boolean value. Icon is a picture of checked or unchecked box.
781
- #
782
- # Parameters:
783
- # [value] Boolean.
784
- #
785
- # Example:
786
- # # usage from program
787
- # dc_icon4_boolean(some_value)
788
- #
789
- # # usage from form description
790
- # columns:
791
- # 10:
792
- # name: active
793
- # eval: dc_icon4_boolean
794
- ############################################################################
795
- def dc_icon4_boolean(value)
796
- dc_dont?(value, true) ? fa_icon('square-o lg') : fa_icon('check-square-o lg')
797
- end
798
-
799
- ############################################################################
800
- # Returns html code for displaying date/time formatted by strftime. Will return '' if value is nil.
801
- #
802
- # Parameters:
803
- # [value] Date/DateTime/Time.
804
- # [format] String. strftime format mask. Defaults to locale's default format.
805
- ############################################################################
806
- def dc_format_date_time(value, format=nil)
807
- return '' if value.nil?
808
- format ||= value.class == Date ? t('date.formats.default') : t('time.formats.default')
809
- value.strftime(format)
810
- end
811
-
812
- ####################################################################
813
- #
814
- ####################################################################
815
- def dc_date_time(value, format) #:nodoc:
816
- dc_deprecate 'dc_date_time will be deprecated! Use dc_format_date_time instead.'
817
- dc_format_date_time(value, format)
818
- end
819
-
820
- ############################################################################
821
- # Returns html code for displaying formatted number.
822
- #
823
- # Parameters:
824
- # [value] Numeric number.
825
- # [decimals] Integer. Number of decimals
826
- # [separator] String. Decimals separator
827
- # [delimiter] String. Thousands delimiter.
828
- # [currency] String. Currency symbol if applied to result string.
829
- ############################################################################
830
- def dc_format_number(value=0, decimals=nil, separator=nil, delimiter=nil, currency=nil)
831
- decimals ||= I18n.t('number.currency.format.precision')
832
- separator ||= I18n.t('number.currency.format.separator')
833
- separator = '' if decimals == 0
834
- delimiter ||= I18n.t('number.currency.format.delimiter')
835
- whole, dec = value.to_s.split('.')
836
- whole = '0' if whole.blank?
837
- # remove and remember sign
838
- sign = ''
839
- if whole[0] == '-'
840
- whole.delete_prefix!('-')
841
- sign << '-'
842
- end
843
- # format decimals
844
- dec ||= '0'
845
- dec = dec[0,decimals]
846
- while dec.size < decimals do dec += '0' end
847
- # slice whole on chunks of 3
848
- ar = []
849
- while whole.size > 0 do
850
- n = whole.size >=3 ? 3 : whole.size
851
- ar << whole.slice!(n*-1,n)
852
- end
853
- # put it all back and format
854
- "#{sign}#{ar.reverse.join(delimiter)}#{separator}#{dec}"
855
- end
856
-
857
663
  ####################################################################
858
664
  # Parse site name from url and return dc_site document. Site document will be cached in
859
665
  # @site variable.
@@ -864,23 +670,20 @@ end
864
670
  # Returns:
865
671
  # DCSite. Site document.
866
672
  ####################################################################
867
- def dc_get_site()
673
+ def dc_get_site
868
674
  return @site if @site # already cached
869
- #
675
+
870
676
  req = _origin.request.url # different when called from renderer
871
677
  uri = URI.parse(req)
872
678
  @site = DcSite.find_by(name: uri.host)
873
- # Site can be aliased
874
- if @site and !@site.alias_for.blank?
875
- @site = DcSite.find_by(name: @site.alias_for)
876
- end
877
- # Development environment. Check if site with name test exists and use
878
- # alias_for field as pointer to real site name.
879
- if @site.nil? and ENV["RAILS_ENV"] != 'production'
679
+ # Site can be aliased
680
+ @site = DcSite.find_by(name: @site.alias_for) if @site&.alias_for.present?
681
+ # Development. If site with name test exists use alias_for field as pointer to real site data
682
+ if @site.nil? && ENV["RAILS_ENV"] != 'production'
880
683
  @site = DcSite.find_by(name: 'test')
881
684
  @site = DcSite.find_by(name: @site.alias_for) if @site
882
685
  end
883
- @site = nil if @site and !@site.active # site is disabled
686
+ @site = nil if @site && !@site.active # site is disabled
884
687
  @site
885
688
  end
886
689
 
@@ -896,9 +699,9 @@ end
896
699
  # html:
897
700
  # include_blank: true
898
701
  ############################################################################
899
- def dc_choices4_site_policies()
702
+ def dc_choices4_site_policies
900
703
  site = dc_get_site()
901
- site.dc_policies.all.inject([]) { |r, policy| r << [ policy.name, policy.id] if policy.active }
704
+ site.dc_policies.where(active: true).order_by(name: 1).map { |policy| [ policy.name, policy.id] }
902
705
  end
903
706
 
904
707
  ############################################################################
@@ -919,7 +722,7 @@ def dc_choices4_all_collections
919
722
  DrgCms.paths(:forms).reverse.each do |path|
920
723
  filename = "#{path}/cms_menu.yml"
921
724
  next unless File.exist?(filename)
922
- #
725
+
923
726
  menu = YAML.load_file(filename) rescue nil # load menu
924
727
  next if menu.nil? or !menu['menu'] # not menu or error
925
728
  menu['menu'].each do |section|
@@ -946,8 +749,8 @@ def forms_merge(hash1, hash2) #:nodoc:
946
749
  end
947
750
  target[key] = hash2[key] == '/' ? nil : hash2[key]
948
751
  end
949
- # delete keys with nil value
950
- target.delete_if{ |k,v| v.nil? }
752
+ # delete keys with nil value
753
+ target.delete_if{ |k, v| v.nil? }
951
754
  end
952
755
 
953
756
  ##########################################################################
@@ -962,7 +765,7 @@ def dc_choices4_cmsmenu()
962
765
  next if menu.nil? or !menu['menu'] # not menu or error
963
766
  menus = forms_merge(menu['menu'], menus) # ignore top level part
964
767
  end
965
- #
768
+
966
769
  html = '<ul>'
967
770
  menus.to_a.sort.each do |index, menu| # sort menus, result is array of sorted hashes
968
771
  next unless menu['caption']
@@ -1027,12 +830,11 @@ def dc_choices4(model, name, id='_id', options = {})
1027
830
  sites << nil if param == :with_nil
1028
831
  qry = qry.in(dc_site_id: sites) if sites
1029
832
  end
1030
- qry = qry.and(active: true) if model.method_defined?(:active)
1031
- # qry = qry.sort(name => 1)
1032
- # choices = []
1033
- # qry.each {|v| choices << [ v[name], v[id] ] }
1034
- choices = qry.inject([]) {|result,e| result << [ e[name], e[id] ]}
1035
- choices.sort_alphabetical_by(&:first) # use UTF-8 sort
833
+ qry = qry.and(active: true) if model.method_defined?(:active)
834
+ qry = qry.order_by(name => 1).collation(locale: I18n.locale.to_s)
835
+ #choices = qry.inject([]) {|result,e| result << [ e[name], e[id] ]}
836
+ #choices.sort_alphabetical_by(&:first) # use UTF-8 sort
837
+ qry.map { |e| [e[name], e[id]] }
1036
838
  end
1037
839
 
1038
840
  ############################################################################
@@ -1093,35 +895,35 @@ end
1093
895
  ############################################################################
1094
896
  def dc_user_can_view(ctrl, policy_id)
1095
897
  policy_id = policy_id.policy_id if policy_id and policy_id.respond_to?(:policy_id)
1096
- # Eventualy object without policy_id will be checked. This is to prevent error
898
+ # Eventualy object without policy_id will be checked. This is to prevent error
1097
899
  policy_id = nil unless policy_id.class == BSON::ObjectId
1098
- #
900
+
1099
901
  site = ctrl.site
1100
902
  policies = if site.inherit_policy.blank?
1101
903
  site.dc_policies
1102
904
  else
1103
905
  Mongoid::QueryCache.cache { DcSite.find(site.inherit_policy) }.dc_policies
1104
906
  end
1105
- # permission defined by default policy
907
+ # permission defined by default policy
1106
908
  default_policy = Mongoid::QueryCache.cache { policies.find_by(is_default: true) }
1107
909
  return false, 'Default access policy not found for the site!' unless default_policy
1108
- #
910
+
1109
911
  permissions = {}
1110
912
  default_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
1111
- # update permissions with defined policy
913
+ # update permissions with defined policy
1112
914
  part_policy = nil
1113
915
  if policy_id
1114
916
  part_policy = Mongoid::QueryCache.cache { policies.find(policy_id) }
1115
917
  return false, 'Access policy not found for part!' unless part_policy
1116
918
  part_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
1117
919
  end
1118
- # apply guest role if no roles defined
920
+ # apply guest role if no roles defined
1119
921
  if ctrl.session[:user_roles].nil?
1120
922
  role = Mongoid::QueryCache.cache { DcPolicyRole.find_by(system_name: 'guest', active: true) }
1121
923
  return false, 'System guest role not defined!' unless role
1122
924
  ctrl.session[:user_roles] = [role.id]
1123
925
  end
1124
- # Check if user has any role that allows him to view part
926
+ # Check if user has any role that allows him to view part
1125
927
  can_view, msg = false,''
1126
928
  ctrl.session[:user_roles].each do |role|
1127
929
  next unless permissions[role] # role not yet defined. Will die in next line.
@@ -1157,10 +959,10 @@ def dc_user_has_role( role, user=nil, roles=nil )
1157
959
  roles = _origin.session[:user_roles] if roles.nil?
1158
960
  user = _origin.session[:user_id] if user.nil?
1159
961
  return false if user.nil? or roles.nil?
1160
- #
962
+
1161
963
  role = DcPolicyRole.get_role(role)
1162
964
  return false if role.nil?
1163
- # role is included in roles array
965
+ # role is included in roles array
1164
966
  roles.include?(role._id)
1165
967
  end
1166
968
 
@@ -1179,7 +981,8 @@ end
1179
981
  ####################################################################
1180
982
  def dc_dont?(what, default=false)
1181
983
  return default if what.nil?
1182
- %w(0 no - false none).include?(what.to_s.downcase.strip)
984
+
985
+ %w(0 n - no none false).include?(what.to_s.downcase.strip)
1183
986
  end
1184
987
 
1185
988
  ############################################################################
@@ -1198,6 +1001,7 @@ end
1198
1001
  ############################################################################
1199
1002
  def dc_limit_string(string, size)
1200
1003
  return string if string.size < size
1004
+
1201
1005
  string = string[0,size]
1202
1006
  string.chop! until (string[-1,1] == ' ' or string == '')
1203
1007
  string << '...'
@@ -1225,10 +1029,11 @@ def dc_big_table(key)
1225
1029
  bt = DcBigTable.find_by(key: key, site: dc_get_site._id, active: true)
1226
1030
  bt = DcBigTable.find_by(key: key, site: nil, active: true) if bt.nil?
1227
1031
  return ret if bt.nil?
1228
- #
1032
+
1229
1033
  locale = I18n.locale.to_s
1230
1034
  bt.dc_big_table_values.each do |v| # iterate each value
1231
1035
  next unless v.active
1036
+
1232
1037
  desc = ''
1233
1038
  v.dc_big_table_locales.each do |l| # iterate each locale
1234
1039
  if l.locale == locale
@@ -1283,40 +1088,50 @@ def dc_iframe_edit(table, opts={})
1283
1088
  end
1284
1089
 
1285
1090
  ########################################################################
1286
- # Will return value from internal DRG variables.
1287
- # This objects can be params, session, ...
1091
+ # Will return value from Rails and DRG internal objects.
1092
+ # This objects can be params, session, record, site, page
1288
1093
  #
1289
1094
  # Parameters:
1290
- # [object] String: Internal object holding variable. Current values can be session, params, site, page
1095
+ # [object] String: Internal object holding variable. Possible values are session, params, record, site, page, class
1291
1096
  # [var_name] String[symbol]: Variable name (:user_name, 'user_id', ...)
1097
+ # [current_document] Object: If passed and object is 'record' then it will be used for retrieving data.
1292
1098
  #
1293
1099
  # Example:
1294
1100
  # # called when constructing iframe for display
1295
- # dc_internal_var(session, :user_id)
1296
- # dc_internal_var(params, :some_external_parameter)
1297
- # dc_internal_var(site, :name)
1101
+ # dc_internal_var('session', :user_id)
1102
+ # dc_internal_var('params', :some_external_parameter)
1103
+ # dc_internal_var('site', :name)
1104
+ # # or even
1105
+ # dc_internal_var('class', 'ClassName.class_method_name')
1106
+ #
1298
1107
  #
1299
1108
  # Returns:
1300
- # Value of variable or nil when not found
1109
+ # Value of variable or error when not found
1301
1110
  ########################################################################
1302
- def dc_internal_var(object, var_name)
1111
+ def dc_internal_var(object, var_name, current_document = nil)
1303
1112
  begin
1304
1113
  case
1305
- when object == 'session' then _origin.session[var_name]
1306
- when object == 'params' then _origin.params[var_name]
1307
- when object == 'site' then _origin.dc_get_site.send(var_name)
1308
- when object == 'page' then _origin.page.send(var_name)
1309
- when object == 'record' then _origin.record.send(var_name)
1114
+ when object == 'session' then _origin.session[var_name]
1115
+ when object == 'params' then _origin.params[var_name]
1116
+ when object == 'site' then _origin.dc_get_site.send(var_name)
1117
+ when object == 'page' then _origin.page.send(var_name)
1118
+ when object == 'record' then
1119
+ current_document ? current_document.send(var_name) : _origin.record.send(var_name)
1120
+ when object == 'class' then
1121
+ clas, method_name = var_name.split('.')
1122
+ klas = clas.classify.constantize
1123
+ # call method. Error will be caught below.
1124
+ klas.send(method_name)
1310
1125
  else
1311
1126
  'VARIABLE: UNKNOWN OBJECT'
1312
1127
  end
1313
1128
  rescue Exception => e
1314
- Rails.logger.error "Method dc_internal var. Runtime error. #{e.message}"
1129
+ Rails.logger.debug "\ndc_internal_var. Runtime error. #{e.message}\n"
1130
+ Rails.logger.debug(e.backtrace.join($/)) if Rails.env.development?
1315
1131
  'VARIABLE: ERROR'
1316
1132
  end
1317
1133
  end
1318
1134
 
1319
-
1320
1135
  ########################################################################
1321
1136
  # Will return whole path to document if document is embedded in another document.
1322
1137
  #
@@ -1335,4 +1150,101 @@ def dc_document_path(document)
1335
1150
  path.reverse.join(';')
1336
1151
  end
1337
1152
 
1153
+ ########################################################################
1154
+ # Will return formated code for embedding json+ld data into page
1155
+ #
1156
+ # Returns:
1157
+ # HTML data to be embedded into page header
1158
+ #######################################################################
1159
+ def dc_get_json_ld()
1160
+ return '' if @json_ld.nil? or @json_ld.size == 0
1161
+
1162
+ %Q[
1163
+ <script type="application/ld+json">
1164
+ #{JSON.pretty_generate({'@context' => 'http://schema.org', '@graph' => @json_ld})}
1165
+ </script>
1166
+ ].html_safe
1167
+ end
1168
+
1169
+ ########################################################################
1170
+ # Will add new element to json_ld structure
1171
+ #
1172
+ # Parameters:
1173
+ # [element] Hash or Array of hashes: json+ld element
1174
+ #######################################################################
1175
+ def dc_add_json_ld(element)
1176
+ @json_ld ||= []
1177
+ if element.class == Array
1178
+ @json_ld += element
1179
+ else
1180
+ @json_ld << element
1181
+ end
1182
+ end
1183
+
1184
+ ########################################################################
1185
+ # Will return meta data for SEO optimizations
1186
+ #
1187
+ # Returns:
1188
+ # HTML data to be embedded into page header
1189
+ #######################################################################
1190
+ def dc_get_seo_meta_tags()
1191
+ html = ''
1192
+ html << "<link rel=\"canonical\" href=\"#{@page.canonical_link}\">\n " unless @page&.canonical_link.blank?
1193
+
1194
+ html << @meta_tags.inject('') do |r, hash|
1195
+ r << "<meta #{hash.first} content=\"#{hash.last}\">\n "
1196
+ end if @meta_tags
1197
+ html.html_safe
1198
+ end
1199
+
1200
+ ########################################################################
1201
+ # Will add a meta tag to internal hash structure. If meta tag already exists it
1202
+ # will be overwritten.
1203
+ #
1204
+ # Parameters:
1205
+ # [name] String: meta name
1206
+ # [content] String: meta content
1207
+ ########################################################################
1208
+ def dc_add_meta_tag(type, name, content)
1209
+ return if content.blank?
1210
+ @meta_tags ||= {}
1211
+ key = "#{type}=\"#{name}\""
1212
+ @meta_tags[key] = content
1213
+ end
1214
+
1215
+ #######################################################################
1216
+ # Will return alt image option when text is provided. When text is blank
1217
+ # it will extract alt name from picture file_name. This method returns
1218
+ # together with alt="image-tag" tag.
1219
+ #
1220
+ # Parameters:
1221
+ # [file_name] String: Filename of a picture
1222
+ # [text] String: Alt text name
1223
+ #
1224
+ # Returns:
1225
+ # [String] alt="image-tag"
1226
+ #######################################################################
1227
+ def dc_img_alt_tag(file_name, text=nil)
1228
+ " alt=\"#{dc_img_alt(file_name, text)}\" ".html_safe
1229
+ end
1230
+
1231
+ #######################################################################
1232
+ # Will return alt image option when text is provided. When text is blank
1233
+ # it will extract alt name from picture file_name. This method returns just
1234
+ # alt name.
1235
+ #
1236
+ # Parameters:
1237
+ # [file_name] String: Filename of a picture
1238
+ # [text] String: Alt text name
1239
+ #
1240
+ # Returns:
1241
+ # [String] alt_image_name
1242
+ #######################################################################
1243
+ def dc_img_alt(file_name, text=nil)
1244
+ return text unless text.blank?
1245
+ name = File.basename(file_name.to_s)
1246
+ name[0,name.index('.')].downcase rescue name
1247
+ end
1248
+
1249
+
1338
1250
  end