drg_cms 0.6.1.11 → 0.7.0.8

Sign up to get free protection for your applications and to get access to all the features.
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