drg_cms 0.6.1.11 → 0.7.0.8

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +260 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +9 -5
  5. data/app/assets/javascripts/drg_cms/drg_cms.js +95 -34
  6. data/app/assets/javascripts/drg_cms/jquery.bpopup.js +372 -0
  7. data/app/assets/javascripts/drg_cms_application.js +1 -3
  8. data/app/assets/javascripts/drg_cms_cms.js +3 -4
  9. data/app/assets/stylesheets/drg_cms/drg_cms.css +37 -5
  10. data/app/assets/stylesheets/drg_cms/jstree.css +32 -27
  11. data/app/assets/stylesheets/drg_cms/select-multiple.css +6 -4
  12. data/app/controllers/cmsedit_controller.rb +22 -24
  13. data/app/controllers/dc_application_controller.rb +10 -9
  14. data/app/controllers/dc_common_controller.rb +14 -11
  15. data/app/controllers/dc_main_controller.rb +0 -1
  16. data/app/controls/dc_gallery_control.rb +46 -0
  17. data/app/controls/dc_image_control.rb +180 -0
  18. data/app/controls/dc_page_control.rb +3 -3
  19. data/app/controls/dc_poll_result_control.rb +7 -8
  20. data/app/controls/dc_report.rb +9 -4
  21. data/app/controls/design_element_settings_control.rb +88 -37
  22. data/app/forms/all_options.yml +18 -7
  23. data/app/forms/cms_menu.yml +10 -4
  24. data/app/forms/dc_category.yml +17 -8
  25. data/app/forms/dc_category_as_tree.yml +31 -0
  26. data/app/forms/dc_gallery.yml +1 -1
  27. data/app/forms/dc_image.yml +122 -0
  28. data/app/forms/dc_image_search.yml +72 -0
  29. data/app/forms/dc_page.yml +11 -8
  30. data/app/forms/dc_steps_template.yml +2 -1
  31. data/app/forms/help/dc_category_as_tree.en +4 -0
  32. data/app/forms/help/dc_category_as_tree.sl +5 -0
  33. data/app/helpers/cms_common_helper.rb +24 -16
  34. data/app/helpers/cms_edit_helper.rb +28 -35
  35. data/app/helpers/cms_helper.rb +21 -5
  36. data/app/helpers/cms_index_helper.rb +53 -38
  37. data/app/helpers/dc_application_helper.rb +95 -121
  38. data/app/helpers/dc_category_helper.rb +129 -0
  39. data/app/helpers/dc_image_helper.rb +127 -0
  40. data/app/models/concerns/dc_policy_rule_concern.rb +1 -1
  41. data/app/models/concerns/dc_user_concern.rb +12 -4
  42. data/app/models/dc_category.rb +62 -24
  43. data/app/models/dc_design.rb +5 -4
  44. data/app/models/dc_filter.rb +19 -18
  45. data/app/models/dc_image.rb +237 -0
  46. data/app/models/dc_internals.rb +5 -9
  47. data/app/models/dc_policy_role.rb +8 -8
  48. data/app/models/drgcms_form_fields/date_picker.rb +10 -12
  49. data/app/models/drgcms_form_fields/datetime_picker.rb +10 -11
  50. data/app/models/drgcms_form_fields/drgcms_field.rb +55 -30
  51. data/app/models/drgcms_form_fields/embedded.rb +11 -8
  52. data/app/models/drgcms_form_fields/journal_diff.rb +2 -2
  53. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +51 -47
  54. data/app/models/drgcms_form_fields/select.rb +20 -14
  55. data/app/models/drgcms_form_fields/text_with_select.rb +5 -9
  56. data/app/models/drgcms_form_fields/tree_select.rb +20 -19
  57. data/app/renderers/dc_gallery_renderer.rb +10 -4
  58. data/app/renderers/dc_page_renderer.rb +7 -7
  59. data/app/renderers/dc_poll_renderer.rb +13 -12
  60. data/app/views/cmsedit/_edit_stuff.html.erb +1 -1
  61. data/app/views/cmsedit/edit.html.erb +1 -1
  62. data/app/views/cmsedit/index.html.erb +1 -1
  63. data/app/views/cmsedit/new.html.erb +1 -0
  64. data/app/views/layouts/content.html.erb +1 -1
  65. data/config/locales/drgcms_en.yml +16 -2
  66. data/config/locales/drgcms_sl.yml +15 -2
  67. data/config/locales/models_en.yml +33 -0
  68. data/config/locales/models_sl.yml +44 -1
  69. data/drg_cms.gemspec +3 -3
  70. data/lib/drg_cms/version.rb +1 -1
  71. data/lib/drg_cms.rb +19 -5
  72. data/lib/generators/convert_to_ar/USAGE +8 -0
  73. data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
  74. data/lib/tasks/dc_cleanup.rake +20 -42
  75. metadata +25 -14
  76. data/History.log +0 -109
  77. data/app/assets/javascripts/drg_cms/jquery.bpopup.min.js +0 -7
  78. data/app/views/layouts/__cmsedit.html.erb +0 -16
@@ -260,7 +260,7 @@ def dc_table_title(text, result_set = nil)
260
260
  c = %(<div class="dc-title">#{text})
261
261
  c << dc_help_button(result_set)
262
262
 
263
- if result_set && result_set.respond_to?(:current_page)
263
+ if result_set&.respond_to?(:current_page)
264
264
  c << %(<div class="dc-paginate">#{paginate(result_set, :params => {action: 'index', clear: 'no', filter: nil})}</div>)
265
265
  end
266
266
  c << '<div style="clear: both;"></div></div>'
@@ -268,26 +268,27 @@ def dc_table_title(text, result_set = nil)
268
268
  end
269
269
 
270
270
  ############################################################################
271
- # Creates title for cmsedit edit action dialog.
272
- #
271
+ # Creates title for cmsedit edit action dialog.
272
+ #
273
273
  # Returns:
274
274
  # String. HTML code for title.
275
275
  ############################################################################
276
276
  def dc_edit_title
277
277
  session[:form_processing] = "form:title:"
278
- title = @form['form']['title']
278
+ title_data = @form['form']['title']
279
+ if title_data.class == String
280
+ t(title_data, title_data)
279
281
  # defined as form:title:edit
280
- if title && title['edit'] && !@form['readonly']
281
- t( title['edit'], title['edit'] )
282
- elsif title && title['show'] && @form['readonly']
283
- t( title['show'], title['show'] )
282
+ elsif title_data&.dig('edit') && !@form['readonly']
283
+ t( title_data['edit'], title_data['edit'] )
284
+ elsif title_data&.dig('show') && @form['readonly']
285
+ t( title_data['show'], title_data['show'] )
284
286
  else
285
- # concatenate title
286
287
  c = (@form['readonly'] ? t('drgcms.show') : t('drgcms.edit')) + " : "
287
288
  c << (@form['title'].class == String ? t( @form['title'], @form['title'] ) : t_tablename(@form['table']))
288
- title = title.try('field')
289
-
290
- c << "#{@record[ title ]}" if title && @record.respond_to?(title)
289
+ # add description field value to title
290
+ field_name = title_data['field'] if title_data
291
+ c << " : #{@record[ field_name ]}" if field_name && @record.respond_to?(field_name)
291
292
  c
292
293
  end
293
294
  end
@@ -300,64 +301,40 @@ end
300
301
  ############################################################################
301
302
  def dc_new_title
302
303
  session[:form_processing] = "form:title:"
303
- title = @form['form']['title']
304
+ title_data = @form['form']['title']
305
+ if title_data.class == String
306
+ t(title_data, title_data)
304
307
  # defined as form:title:new
305
- if title && title['new']
306
- t( title['new'], title['new'] )
308
+ elsif title_data&.dig('new')
309
+ t( title_data['new'], title_data['new'] )
307
310
  else
308
311
  # in memory structures
309
312
  if @form['table'] == 'dc_memory'
310
- t( @form['title'], @form['title'] )
313
+ return t( @form['title'], @form['title'] ) if @form['title']
314
+
315
+ t("#{@form['i18n_prefix']}.tabletitle", '')
311
316
  else
312
317
  "#{t('drgcms.new')} : #{t_tablename(@form['table'])}"
313
318
  end
314
319
  end
315
320
  end
316
321
 
317
- ####################################################################
318
- # Formats label and html input code for display on edit form.
319
- #
320
- # Parameters:
321
- # [input_html] String. HTML code for data input field.
322
- # [label] String. Input field label.
323
- ####################################################################
324
- def dc_label_for(input_html, label)
325
- c =<<eot
326
- <tr>
327
- <td class="dc-edit-label">#{label}</td>
328
- <td class="dc-edit-field">#{input_html}</td>
329
- </tr>
330
- eot
331
- c.html_safe
332
- end
333
-
334
322
  ############################################################################
335
323
  # Similar to rails submit_tag, but also takes care of link icon, translation, ...
336
324
  ############################################################################
337
- def dc_submit_tag(caption, icon, parms, rest={})
338
- parms['class'] ||= 'dc-link'
339
- if icon
340
- icon_image = if icon.match(/\./)
341
- image_tag(icon)
342
- elsif icon.match('<i')
343
- icon
344
- else
345
- fa_icon(icon)
346
- end
347
- end
348
- html = icon_image || ''
349
- #html << submit_tag(t(caption, caption), parms)
350
- %Q[<button type="submit" class="dc-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>].html_safe
325
+ def dc_submit_tag(caption, icon, parms, rest = {})
326
+ icon_image = dc_icon_for_link(icon, nil)
327
+ %(<button type="submit" class="dc-submit" name="commit" value="#{t(caption, caption)}">#{icon_image} #{t(caption, caption)}</button>).html_safe
351
328
  end
352
329
 
353
330
  ############################################################################
354
331
  # Returns icon code if icon is specified
355
332
  ############################################################################
356
- def dc_icon_for_link(icon)
333
+ def dc_icon_for_link(icon, clas = 'dc-link-img')
357
334
  return '' if icon.blank?
358
335
 
359
336
  if icon.match(/\./)
360
- _origin.image_tag(icon, class: 'dc-link-img')
337
+ _origin.image_tag(icon, class: clas)
361
338
  elsif icon.match('<i')
362
339
  icon
363
340
  else
@@ -619,7 +596,7 @@ def dc_page_edit_menu(opts = @opts)
619
596
  opts[:editparams] ||= {}
620
597
  dc_link_menu_tag(title) do |html|
621
598
  opts[:editparams].merge!( controller: 'cmsedit', action: 'edit', 'icon' => 'edit-o' )
622
- opts[:editparams].merge!( :id => page.id, :t => _origin.site.page_class.underscore, f: opts[:form_name], edit_only: 'body' )
599
+ opts[:editparams].merge!( :id => page.id, :table => _origin.site.page_class.underscore, form_name: opts[:form_name], edit_only: 'body' )
623
600
  html << dc_link_for_edit1( opts[:editparams], t('drgcms.edit_content') )
624
601
 
625
602
  opts[:editparams].merge!( edit_only: nil, 'icon' => 'edit-o' )
@@ -712,51 +689,40 @@ end
712
689
  ############################################################################
713
690
  # Returns list of all collections (tables) as array of choices for usage in select fields.
714
691
  # List is collected from cms_menu.yml files and may not include all collections used in application.
715
- # Currently list is only used for helping defining collection names on dc_permission form.
716
- #
692
+ # Currently list is only used for helping defining collection names on dc_permission form.
693
+ #
717
694
  # Example (as used in forms):
718
695
  # form:
719
696
  # fields:
720
697
  # 10:
721
698
  # name: table_name
722
699
  # type: text_with_select
723
- # eval: dc_choices4_all_collections
700
+ # eval: dc_choices4_all_collections
724
701
  ############################################################################
725
702
  def dc_choices4_all_collections
726
- choices = {}
727
- DrgCms.paths(:forms).reverse.each do |path|
728
- filename = "#{path}/cms_menu.yml"
729
- next unless File.exist?(filename)
730
-
731
- menu = YAML.load_file(filename) rescue nil # load menu
732
- next if menu.nil? or !menu['menu'] # not menu or error
733
- menu['menu'].each do |section|
734
- next unless section.last['items'] # next if no items
735
- section.last['items'].each do |k, v| # look for caption and
736
- key = v['table']
737
- choices[key] ||= "#{key} - #{t(v['caption'], v['caption'])}"
738
- end
739
- end
740
- end
741
- choices.invert.to_a.sort # hash has to be inverted for values to be returned right
703
+ models = Mongoid.models.map(&:to_s).uniq.map(&:underscore).delete_if { |e| e.match('/') }
704
+ models.sort.inject([]) do |r, model_name|
705
+ r << ["#{model_name} - #{t("helpers.label.#{model_name}.tabletitle", '')}", model_name]
706
+ end
742
707
  end
743
708
 
744
709
  ##########################################################################
745
- # Returns choices for creating collection edit select field on CMS top menu.
710
+ # Code for top CMS menu.
746
711
  ##########################################################################
747
- def dc_choices4_cmsmenu
712
+ def dc_cms_menu
748
713
  menus = {}
749
714
  DrgCms.paths(:forms).reverse.each do |path|
750
715
  filename = "#{path}/cms_menu.yml"
751
- next unless File.exist?(filename)
752
- menu = YAML.load_file(filename) rescue nil # load menu
753
- next if menu.nil? or !menu['menu'] # not menu or error
754
- menus = CmsHelper.forms_merge(menu['menu'], menus) # ignore top level part
755
- end
716
+ next if !File.exist?(filename)
717
+
718
+ menu = YAML.load_file(filename) rescue nil # load menu
719
+ menus = CmsHelper.forms_merge(menu['menu'], menus) if menu.dig('menu') # merge menus
720
+ end
756
721
 
757
722
  html = '<ul>'
758
723
  menus.to_a.sort.each do |index, menu| # sort menus, result is array of sorted hashes
759
724
  next unless menu['caption']
725
+
760
726
  icon = menu['icon'].match('/') ? image_tag(menu['icon']) : fa_icon(menu['icon']) #external or fa- image
761
727
  html << %(<li class="cmsedit-top-level-menu"><div>#{icon}#{t(menu['caption'])}</div><ul>)
762
728
  menu['items'].to_a.sort.each do |index1, value| # again, sort menu items first
@@ -764,19 +730,18 @@ def dc_choices4_cmsmenu
764
730
  opts = { target: value['target'] || 'iframe_cms' }
765
731
  "<li>#{dc_link_to(t(value['caption']), value['icon'] || '', value['link'], opts)}</li>"
766
732
  else
767
- opts =
768
- { controller: value['controller'],
769
- action: value['action'],
770
- table: value['table'],
771
- form_name: value['form_name'] || value['table'],
772
- target: value['target'] || 'iframe_cms',
773
- }
733
+ opts = { controller: value['controller'], action: value['action'],
734
+ table: value['table'], form_name: value['form_name'] || value['table'],
735
+ target: value['target'] || 'iframe_cms',
736
+ }
737
+ # additional parameters
738
+ value['params'].each { |k, v| opts[k] = dc_value_for_parameter(v) } if value['params']
774
739
  "<li>#{dc_link_to(t(value['caption']), value['icon'] || '', opts)}</li>"
775
740
  end
776
741
  end
777
742
  html << '</ul></li>'
778
743
  end
779
- html
744
+ html.html_safe
780
745
  end
781
746
 
782
747
  ############################################################################
@@ -788,7 +753,7 @@ def dc_choices4_folders_list
788
753
  home = File.join(public,dc_get_site.files_directory)
789
754
  choices = Dir.glob(home + '/**/*/').select { |fn| File.directory?(fn) }
790
755
  choices << home # add home
791
- choices.collect! {|e| e.gsub(public,'')} # remove public part
756
+ choices.collect! { |e| e.gsub(public,'') } # remove public part
792
757
  choices.sort
793
758
  end
794
759
 
@@ -810,7 +775,7 @@ end
810
775
  # type: select
811
776
  # eval: dc_choices4('dc_poll','name','_id')
812
777
  ############################################################################
813
- def dc_choices4(model, name, id='_id', options = {})
778
+ def dc_choices4(model, name, id = '_id', options = {})
814
779
  model = model.classify.constantize
815
780
  qry = model.only(id, name)
816
781
  if (param = options[:site])
@@ -820,8 +785,6 @@ def dc_choices4(model, name, id='_id', options = {})
820
785
  end
821
786
  qry = qry.and(active: true) if model.method_defined?(:active)
822
787
  qry = qry.order_by(name => 1).collation(locale: I18n.locale.to_s)
823
- #choices = qry.inject([]) {|result,e| result << [ e[name], e[id] ]}
824
- #choices.sort_alphabetical_by(&:first) # use UTF-8 sort
825
788
  qry.map { |e| [e[name], e[id]] }
826
789
  end
827
790
 
@@ -867,7 +830,7 @@ end
867
830
  #
868
831
  # Parameters:
869
832
  # [ctrl] Controller object or object which holds methods to access session object. For example @parent
870
- # variable when called from renderer.
833
+ # when called from renderer.
871
834
  # [policy_id] Document or documents policy_id field value required to view data. Method will automatically
872
835
  # check if parameter send has policy_id field defined and use value of that field.
873
836
  #
@@ -882,9 +845,11 @@ end
882
845
  # False and message from policy that is blocking view if access is not allowed.
883
846
  ############################################################################
884
847
  def dc_user_can_view(ctrl, policy_id)
885
- policy_id = policy_id.policy_id if policy_id and policy_id.respond_to?(:policy_id)
848
+ @can_view_cache ||= {}
849
+ policy_id = policy_id.policy_id if policy_id&.respond_to?(:policy_id)
886
850
  # Eventualy object without policy_id will be checked. This is to prevent error
887
851
  policy_id = nil unless policy_id.class == BSON::ObjectId
852
+ return @can_view_cache[policy_id] if @can_view_cache[policy_id]
888
853
 
889
854
  site = ctrl.site
890
855
  policies = if site.inherit_policy.blank?
@@ -894,7 +859,7 @@ def dc_user_can_view(ctrl, policy_id)
894
859
  end
895
860
  # permission defined by default policy
896
861
  default_policy = Mongoid::QueryCache.cache { policies.find_by(is_default: true) }
897
- return false, 'Default access policy not found for the site!' unless default_policy
862
+ return cache_add(policy_id, false, 'Default access policy not found for the site!') unless default_policy
898
863
 
899
864
  permissions = {}
900
865
  default_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
@@ -902,28 +867,29 @@ def dc_user_can_view(ctrl, policy_id)
902
867
  part_policy = nil
903
868
  if policy_id
904
869
  part_policy = Mongoid::QueryCache.cache { policies.find(policy_id) }
905
- return false, 'Access policy not found for part!' unless part_policy
870
+ return cache_add(policy_id, false, 'Access policy not found for part!') unless part_policy
871
+
906
872
  part_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
907
873
  end
908
874
  # apply guest role if no roles defined
909
875
  if ctrl.session[:user_roles].nil?
910
876
  role = Mongoid::QueryCache.cache { DcPolicyRole.find_by(system_name: 'guest', active: true) }
911
- return false, 'System guest role not defined!' unless role
877
+ return cache_add(policy_id, false, 'System guest role not defined!') unless role
878
+
912
879
  ctrl.session[:user_roles] = [role.id]
913
880
  end
914
881
  # Check if user has any role that allows him to view part
915
- can_view, msg = false,''
916
- ctrl.session[:user_roles].each do |role|
917
- next unless permissions[role] # role not yet defined. Will die in next line.
918
- if permissions[role] > 0
919
- can_view = true
920
- break
921
- end
882
+ can_view = ctrl.session[:user_roles].reduce(false) do |result, role|
883
+ break true if permissions[role] && permissions[role] > 0
922
884
  end
923
- msg = if !can_view
924
- part_policy ? t(part_policy.message,part_policy.message) : t(default_policy.message,default_policy.message)
885
+
886
+ msg = ''
887
+ unless can_view
888
+ msg = part_policy ? t(part_policy.message, part_policy.message) : t(default_policy.message, default_policy.message)
889
+ # message may have variable content
890
+ msg = _origin.render(inline: msg, layout: nil) if msg.match('<%=')
925
891
  end
926
- return can_view, msg
892
+ cache_add(policy_id, can_view, msg)
927
893
  end
928
894
 
929
895
  ####################################################################
@@ -1098,25 +1064,25 @@ end
1098
1064
  ########################################################################
1099
1065
  def dc_internal_var(object, var_name, current_document = nil)
1100
1066
  begin
1101
- case
1102
- when object == 'session' then _origin.session[var_name]
1103
- when object == 'params' then _origin.params[var_name]
1104
- when object == 'site' then _origin.dc_get_site.send(var_name)
1105
- when object == 'page' then _origin.page.send(var_name)
1106
- when object == 'record' then
1067
+ case object
1068
+ when 'session' then _origin.session[var_name]
1069
+ when 'params' then _origin.params[var_name]
1070
+ when 'site' then _origin.dc_get_site.send(var_name)
1071
+ when 'page' then _origin.page.send(var_name)
1072
+ when 'record' then
1107
1073
  current_document ? current_document.send(var_name) : _origin.record.send(var_name)
1108
- when object == 'class' then
1074
+ when 'class' then
1109
1075
  clas, method_name = var_name.split('.')
1110
1076
  klas = clas.classify.constantize
1111
1077
  # call method. Error will be caught below.
1112
1078
  klas.send(method_name)
1113
1079
  else
1114
- 'VARIABLE: UNKNOWN OBJECT'
1080
+ 'dc_internal: UNKNOWN OBJECT'
1115
1081
  end
1116
1082
  rescue Exception => e
1117
1083
  Rails.logger.debug "\ndc_internal_var. Runtime error. #{e.message}\n"
1118
1084
  Rails.logger.debug(e.backtrace.join($/)) if Rails.env.development?
1119
- 'VARIABLE: ERROR'
1085
+ 'dc_internal: ERROR'
1120
1086
  end
1121
1087
  end
1122
1088
 
@@ -1147,11 +1113,10 @@ end
1147
1113
  def dc_get_json_ld()
1148
1114
  return '' if @json_ld.nil? or @json_ld.size == 0
1149
1115
 
1150
- %Q[
1116
+ %(
1151
1117
  <script type="application/ld+json">
1152
1118
  #{JSON.pretty_generate({'@context' => 'http://schema.org', '@graph' => @json_ld})}
1153
- </script>
1154
- ].html_safe
1119
+ </script>).html_safe
1155
1120
  end
1156
1121
 
1157
1122
  ########################################################################
@@ -1175,12 +1140,12 @@ end
1175
1140
  # Returns:
1176
1141
  # HTML data to be embedded into page header
1177
1142
  #######################################################################
1178
- def dc_get_seo_meta_tags()
1143
+ def dc_get_seo_meta_tags
1179
1144
  html = ''
1180
- html << "<link rel=\"canonical\" href=\"#{@page.canonical_link}\">\n " unless @page&.canonical_link.blank?
1145
+ html << %(<link rel="canonical" href="#{@page.canonical_link}">\n ) if @page&.canonical_link.present?
1181
1146
 
1182
1147
  html << @meta_tags.inject('') do |r, hash|
1183
- r << "<meta #{hash.first} content=\"#{hash.last}\">\n "
1148
+ r << %(<meta #{hash.first} content="#{hash.last}">\n )
1184
1149
  end if @meta_tags
1185
1150
  html.html_safe
1186
1151
  end
@@ -1195,6 +1160,7 @@ end
1195
1160
  ########################################################################
1196
1161
  def dc_add_meta_tag(type, name, content)
1197
1162
  return if content.blank?
1163
+
1198
1164
  @meta_tags ||= {}
1199
1165
  key = "#{type}=\"#{name}\""
1200
1166
  @meta_tags[key] = content
@@ -1213,7 +1179,7 @@ end
1213
1179
  # [String] alt="image-tag"
1214
1180
  #######################################################################
1215
1181
  def dc_img_alt_tag(file_name, text=nil)
1216
- " alt=\"#{dc_img_alt(file_name, text)}\" ".html_safe
1182
+ %( alt="#{dc_img_alt(file_name, text)}" ).html_safe
1217
1183
  end
1218
1184
 
1219
1185
  #######################################################################
@@ -1229,9 +1195,17 @@ end
1229
1195
  # [String] alt_image_name
1230
1196
  #######################################################################
1231
1197
  def dc_img_alt(file_name, text=nil)
1232
- return text unless text.blank?
1198
+ return text if text.present?
1199
+
1233
1200
  name = File.basename(file_name.to_s)
1234
- name[0,name.index('.')].downcase rescue name
1201
+ name[0, name.index('.')].downcase rescue name
1202
+ end
1203
+
1204
+ private
1205
+
1206
+ # will cache dc_user_can_view response
1207
+ def cache_add(id, can_view, msg)
1208
+ @can_view_cache[id] = [can_view, msg]
1235
1209
  end
1236
1210
 
1237
1211
 
@@ -0,0 +1,129 @@
1
+ #--
2
+ # Copyright (c) 2012+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+
25
+ ####################################################################
26
+ # Helper for editing categories as tree view.
27
+ ####################################################################
28
+ module DcCategoryHelper
29
+
30
+ ####################################################################
31
+ #
32
+ ####################################################################
33
+ def categories_as_tree
34
+ html = '<div id="catagories-as-tree"><ul><li data-id="nil"><span class="mi-o mi-home"></span>'
35
+ data = DcCategory.where(parent: nil).order_by(order: 1).to_a
36
+ html_for_category_tree(html, data)
37
+ (html << '</li></ul></div>' << js_for_category_tree).html_safe
38
+ end
39
+
40
+ private
41
+
42
+ ####################################################################
43
+ #
44
+ ####################################################################
45
+ def html_for_category_tree(html, data)
46
+ html << '<ul>'
47
+ data.each do |category|
48
+ icon = category.active ? 'check_box' : 'check_box_outline_blank'
49
+ html << %(<li id="#{category.id}" data-parent="#{category.parent}"><span class="mi-o mi-#{icon} mi-18"></span>#{category.name}\n)
50
+ children = DcCategory.where(parent: category.id).order_by(order: 1).to_a
51
+
52
+ html_for_category_tree(html, children) if children.size > 0
53
+ html << '</li>'
54
+ end
55
+ html << '</ul>'
56
+ end
57
+
58
+ ####################################################################
59
+ #
60
+ ####################################################################
61
+ def js_for_category_tree
62
+ %(<script>
63
+ $(function() {
64
+ $("#catagories-as-tree").jstree( {
65
+ core: { themes: { icons: false },
66
+ multiple: false
67
+ },
68
+ plugins: ["types", "contextmenu"],
69
+ contextmenu: {
70
+ items: function ($node) {
71
+ return {
72
+ edit: {
73
+ label: "<span class='dc-result-submenu'>#{t('drgcms.edit')}</span>",
74
+ icon: "mi-o mi-edit",
75
+ action: function (obj) {
76
+ let id = $('#catagories-as-tree').jstree('get_selected', true)[0].id;
77
+ let params = "&ids=" + id;
78
+ location.href = "/cmsedit/" + id + "/edit?t=dc_category&f=dc_category_as_tree" + params;
79
+ }
80
+ },
81
+
82
+ new_child: {
83
+ label: "<span class='dc-result-submenu'>#{t('drgcms.new')}</span>",
84
+ icon: "mi-o mi-plus",
85
+ action: function (obj) {
86
+ let id = $('#catagories-as-tree').jstree('get_selected', true)[0].id;
87
+ let params = "&ids=" + id + "&p_parent=" + id;
88
+ location.href = "/cmsedit/new?t=dc_category&f=dc_category_as_tree" + params
89
+ }
90
+ },
91
+
92
+ delete: {
93
+ label: "<span class='dc-result-submenu'>#{t('drgcms.delete')}</span>",
94
+ icon: "mi-o mi-delete",
95
+ action: function (obj) {
96
+ if (confirmation_is_cancled("#{t('drgcms.confirm_delete')}") === true) return false;
97
+
98
+ let id = $('#catagories-as-tree').jstree('get_selected', true)[0].id;
99
+ let id_return = $('#catagories-as-tree').jstree('get_selected', true)[0].data["parent"];
100
+
101
+ $.ajax({
102
+ url: "/cmsedit/" + id + "?t=dc_category",
103
+ type: 'DELETE',
104
+ success: function(data) {
105
+ let error = data.match("#{I18n.t('drgcms.category_has_subs')}");
106
+ if (error !== null) {
107
+ alert(error[0]);
108
+ params = "?t=dc_category&f=dc_category_as_tree&ids=" + id;
109
+ location.href = "/cmsedit" + params;
110
+ return true;
111
+ }
112
+ }
113
+ });
114
+
115
+ let params = "?t=dc_category&f=dc_category_as_tree&ids=" + id_return;
116
+ location.href = "/cmsedit" + params;
117
+ }
118
+ },
119
+ }
120
+ },
121
+ },
122
+ });
123
+ $("#catagories-as-tree").jstree(true).select_node("#{params[:ids]}");
124
+ });
125
+
126
+ </script>)
127
+ end
128
+
129
+ end