camaleon_cms 2.1.1.4 → 2.1.2.0

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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -3
  3. data/app/apps/plugins/contact_form/contact_form_helper.rb +3 -44
  4. data/app/apps/plugins/contact_form/contact_form_html_helper.rb +1 -1
  5. data/app/apps/plugins/contact_form/views/contact_form/{_submission.html.erb → _email_content.html.erb} +0 -0
  6. data/app/apps/themes/camaleon_first/views/index.html.erb +1 -1
  7. data/app/apps/themes/default/views/category.html.erb +1 -1
  8. data/app/apps/themes/default/views/page.html.erb +1 -1
  9. data/app/apps/themes/default/views/partials/_comments.html.erb +5 -5
  10. data/app/apps/themes/default/views/post.html.erb +1 -1
  11. data/app/apps/themes/default/views/post_tag.html.erb +1 -1
  12. data/app/apps/themes/default/views/post_type.html.erb +1 -1
  13. data/app/apps/themes/default/views/search.html.erb +2 -2
  14. data/app/apps/themes/new/views/category.html.erb +1 -1
  15. data/app/apps/themes/new/views/page.html.erb +1 -1
  16. data/app/apps/themes/new/views/post_tag.html.erb +1 -1
  17. data/app/apps/themes/new/views/post_type.html.erb +1 -1
  18. data/app/apps/themes/new/views/search.html.erb +2 -2
  19. data/app/assets/javascripts/camaleon_cms/admin/_actions.js +1 -1
  20. data/app/assets/javascripts/camaleon_cms/admin/{bootstrap-datepicker.js → _bootstrap-datepicker.js} +0 -0
  21. data/app/assets/javascripts/camaleon_cms/admin/_bootstrap-select.js +7 -0
  22. data/app/assets/javascripts/camaleon_cms/admin/_custom_fields.js +9 -0
  23. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +2 -1
  24. data/app/assets/javascripts/camaleon_cms/admin/jquery.validate.js +3 -1
  25. data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js.coffee +125 -0
  26. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +53 -23
  27. data/app/assets/javascripts/camaleon_cms/admin/user_profile.js +23 -29
  28. data/app/assets/stylesheets/camaleon_cms/admin/{bootstrap-datepicker.css.scss → _bootstrap-datepicker.css.scss} +0 -0
  29. data/app/assets/stylesheets/camaleon_cms/admin/_bootstrap-select.css +6 -0
  30. data/app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css +2 -3
  31. data/app/assets/stylesheets/camaleon_cms/admin/colorpicker.css.scss +9 -8
  32. data/app/assets/stylesheets/camaleon_cms/admin/uploader/_uploadfile.css.scss +1 -12
  33. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +102 -81
  34. data/app/controllers/camaleon_cms/admin/media_controller.rb +8 -25
  35. data/app/controllers/camaleon_cms/admin_controller.rb +1 -1
  36. data/app/controllers/camaleon_cms/camaleon_controller.rb +24 -0
  37. data/app/controllers/camaleon_cms/frontend_controller.rb +0 -1
  38. data/app/decorators/camaleon_cms/application_decorator.rb +5 -8
  39. data/app/decorators/camaleon_cms/post_decorator.rb +5 -5
  40. data/app/decorators/camaleon_cms/post_type_decorator.rb +2 -5
  41. data/app/decorators/camaleon_cms/site_decorator.rb +12 -0
  42. data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +1 -1
  43. data/app/helpers/camaleon_cms/admin/application_helper.rb +8 -1
  44. data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +17 -16
  45. data/app/helpers/camaleon_cms/admin/menus_helper.rb +1 -1
  46. data/app/helpers/camaleon_cms/camaleon_helper.rb +2 -2
  47. data/app/helpers/camaleon_cms/captcha_helper.rb +15 -14
  48. data/app/helpers/camaleon_cms/email_helper.rb +7 -3
  49. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +7 -1
  50. data/app/helpers/camaleon_cms/html_helper.rb +1 -1
  51. data/app/helpers/camaleon_cms/site_helper.rb +6 -15
  52. data/app/helpers/camaleon_cms/uploader_helper.rb +31 -187
  53. data/app/mailers/camaleon_cms/html_mailer.rb +4 -8
  54. data/app/models/camaleon_cms/custom_field_group.rb +1 -0
  55. data/app/models/camaleon_cms/nav_menu.rb +1 -20
  56. data/app/models/camaleon_cms/nav_menu_item.rb +13 -0
  57. data/app/models/camaleon_cms/post.rb +1 -1
  58. data/app/models/camaleon_cms/post_type.rb +8 -7
  59. data/app/models/camaleon_cms/site.rb +22 -2
  60. data/app/models/camaleon_cms/user.rb +2 -1
  61. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +21 -29
  62. data/app/models/concerns/camaleon_cms/metas.rb +4 -3
  63. data/app/uploaders/camaleon_cms_aws_uploader.rb +81 -0
  64. data/app/uploaders/camaleon_cms_local_uploader.rb +84 -0
  65. data/app/uploaders/camaleon_cms_uploader.rb +146 -0
  66. data/app/views/camaleon_cms/admin/appearances/nav_menus/_custom_fields.html.erb +3 -5
  67. data/app/views/camaleon_cms/admin/appearances/nav_menus/_external_menu.html.erb +7 -6
  68. data/app/views/camaleon_cms/admin/appearances/nav_menus/_form.html.erb +13 -0
  69. data/app/views/camaleon_cms/admin/appearances/nav_menus/_left_menu_items.html.erb +77 -0
  70. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_items.html.erb +18 -0
  71. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_items_list.html.erb +12 -0
  72. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_options.html.erb +21 -0
  73. data/app/views/camaleon_cms/admin/appearances/nav_menus/index.html.erb +5 -98
  74. data/app/views/camaleon_cms/admin/media/_files_list.html.erb +2 -7
  75. data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +28 -26
  76. data/app/views/camaleon_cms/admin/media/_render_folder_item.html.erb +14 -12
  77. data/app/views/camaleon_cms/admin/media/index.html.erb +23 -22
  78. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +4 -5
  79. data/app/views/camaleon_cms/admin/posts/form.html.erb +1 -0
  80. data/app/views/camaleon_cms/admin/sessions/forgot.html.erb +6 -6
  81. data/app/views/camaleon_cms/admin/sessions/login.html.erb +7 -7
  82. data/app/views/camaleon_cms/admin/sessions/register.html.erb +8 -8
  83. data/app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb +30 -6
  84. data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +26 -23
  85. data/app/views/camaleon_cms/admin/settings/_file_system_settings.html.erb +25 -20
  86. data/app/views/camaleon_cms/admin/settings/_media_settings.html.erb +10 -0
  87. data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +2 -3
  88. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +2 -2
  89. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_audio.html.erb +1 -1
  90. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_colorpicker.html.erb +2 -2
  91. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_date.html.erb +1 -1
  92. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_field_attrs.html.erb +2 -2
  93. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_file.html.erb +1 -1
  94. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_image.html.erb +1 -1
  95. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_video.html.erb +1 -1
  96. data/app/views/camaleon_cms/admin/settings/post_types/_form.html.erb +2 -2
  97. data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -1
  98. data/app/views/camaleon_cms/admin/settings/site.html.erb +11 -13
  99. data/app/views/camaleon_cms/admin/settings/sites/index.html.erb +5 -3
  100. data/app/views/camaleon_cms/admin/users/form.html.erb +14 -22
  101. data/app/views/camaleon_cms/default_theme/category.html.erb +1 -1
  102. data/app/views/camaleon_cms/default_theme/partials/_comments.html.erb +5 -5
  103. data/app/views/camaleon_cms/default_theme/partials/_search_form.html.erb +1 -1
  104. data/app/views/camaleon_cms/default_theme/partials/_sidebar.html.erb +4 -4
  105. data/app/views/camaleon_cms/default_theme/post_tag.html.erb +1 -1
  106. data/app/views/camaleon_cms/default_theme/post_type.html.erb +1 -1
  107. data/app/views/camaleon_cms/default_theme/search.html.erb +1 -1
  108. data/app/views/camaleon_cms/default_theme/single.html.erb +1 -1
  109. data/config/locales/camaleon_cms/admin/en.yml +1 -1
  110. data/config/locales/camaleon_cms/admin/es.yml +36 -0
  111. data/config/locales/camaleon_cms/common.yml +4 -2
  112. data/config/routes/admin.rb +13 -7
  113. data/config/routes/frontend.rb +9 -7
  114. data/config/system.json +1 -0
  115. data/lib/camaleon_cms/engine.rb +1 -1
  116. data/lib/camaleon_cms/version.rb +1 -1
  117. data/lib/ext/string.rb +12 -0
  118. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +1 -1
  119. data/lib/plugin_routes.rb +1 -1
  120. metadata +17 -24
  121. data/app/assets/javascripts/camaleon_cms/admin/bootstrap-select.js +0 -1022
  122. data/app/assets/javascripts/camaleon_cms/admin/nav-menu.js +0 -177
  123. data/app/assets/stylesheets/camaleon_cms/admin/nav-menu.css.scss +0 -33
  124. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_form.html.erb +0 -36
  125. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_list.html.erb +0 -22
@@ -13,7 +13,7 @@ window["cama_init_media"] = (media_panel) ->
13
13
  "<div class='p_label'><b>"+I18n("button.name")+": </b><br> <span>"+data["name"]+"</span></div>" +
14
14
  "<div class='p_body'>" +
15
15
  "<div><b>"+I18n("button.url")+":</b><br> <a target='_blank' href='"+data["url"]+"'>"+data["url"]+"</a></div>" +
16
- "<div><b>"+I18n("button.size")+":</b><br> <span>"+data["size"]+"</span></div>" +
16
+ "<div><b>"+I18n("button.size")+":</b> <span>"+cama_humanFileSize(data["size"])+"</span></div>" +
17
17
  "</div>"
18
18
 
19
19
  if window["callback_media_uploader"]
@@ -24,15 +24,16 @@ window["cama_init_media"] = (media_panel) ->
24
24
 
25
25
  media_info.html(tpl)
26
26
  media_info.find(".p_thumb").html(item.find(".thumb").html())
27
- if data["format"] == "image" && media_panel.attr("data-dimension") # verify dimensions
28
- img = $('<img src="'+data["url"]+'">').hide()
29
- btn = media_info.append(img).find(".p_footer .insert_btn")
30
- btn.prop('disabled', true)
31
- img.load ->
32
- media_info.find(".p_body").append("<div class='cdimension'><b>"+I18n("button.dimension")+": </b><span>"+this.width+"x"+this.height+"</span></div>")
33
- ww = parseInt(media_panel.attr("data-dimension").split("x")[0]) || this.width
34
- hh = parseInt(media_panel.attr("data-dimension").split("x")[1]) || this.height
35
- if media_panel.attr("data-dimension") && this.width == ww && this.height == hh
27
+ if data["format"] == "image"
28
+ ww = parseInt(data['dimension'].split("x")[0])
29
+ hh = parseInt(data['dimension'].split("x")[1])
30
+ media_info.find(".p_body").append("<div class='cdimension'><b>"+I18n("button.dimension")+": </b><span>"+ww+"x"+hh+"</span></div>")
31
+ if media_panel.attr("data-dimension") # verify dimensions
32
+ btn = media_info.find(".p_footer .insert_btn")
33
+ btn.prop('disabled', true)
34
+ _ww = parseInt(media_panel.attr("data-dimension").split("x")[0])
35
+ _hh = parseInt(media_panel.attr("data-dimension").split("x")[1])
36
+ if _ww == ww && _hh == hh
36
37
  btn.prop('disabled', false)
37
38
  else
38
39
  media_info.find(".cdimension").css("color", 'red')
@@ -40,7 +41,6 @@ window["cama_init_media"] = (media_panel) ->
40
41
  $.fn.upload_url({url: data["url"]})
41
42
  )
42
43
  btn.after(cut)
43
- media_info.find(".p_thumb").html(img.show())
44
44
 
45
45
  if window["callback_media_uploader"] # trigger callback
46
46
  media_info.find(".insert_btn").click ->
@@ -59,16 +59,17 @@ window["cama_init_media"] = (media_panel) ->
59
59
  ########## file uploader
60
60
  p_upload = media_panel.find(".cama_media_fileuploader")
61
61
  customFileData = ->
62
- return {folder: media_panel.attr("data-folder"), formats: media_panel.attr("data-formats") }
62
+ return {folder: media_panel.attr("data-folder").replace(/\/{2,}/g, '/'), formats: media_panel.attr("data-formats") }
63
63
 
64
64
  p_upload.uploadFile({
65
65
  url: p_upload.attr("data-url"),
66
66
  fileName: "file_upload",
67
- dragDropStr: '<span><b>'+p_upload.attr('data-dragDropStr')+'</b></span>',
67
+ uploadButtonClass: "btn btn-primary btn-block",
68
+ dragDropStr: '<span style="display: block;"><b>'+p_upload.attr('data-dragDropStr')+'</b></span>',
68
69
  uploadStr: p_upload.attr('data-uploadStr'),
69
70
  dynamicFormData: customFileData,
70
71
  onSuccess: ((files,res_upload,xhr,pd)->
71
- if res_upload.search("<") == 0 # success upload
72
+ if res_upload.search("media_item") >= 0 # success upload
72
73
  media_panel.trigger("add_file", {item: res_upload, selected: $(pd.statusbar).siblings().not('.error_file_upload').size() == 0})
73
74
  $(pd.statusbar).remove();
74
75
  else
@@ -83,9 +84,13 @@ window["cama_init_media"] = (media_panel) ->
83
84
  ######### folders breadcrumb
84
85
  media_panel.find(".media_folder_breadcrumb").on("click", "a", ->
85
86
  media_panel.trigger("navigate_to", {folder: $(this).attr("data-path")})
87
+ return false
86
88
  )
87
89
  media_panel.on("click", ".folder_item", ->
88
- media_panel.trigger("navigate_to", {folder: media_panel.attr("data-folder")+"/"+$(this).attr("data-key")})
90
+ f = media_panel.attr("data-folder")+"/"+$(this).attr("data-key")
91
+ if $(this).attr("data-key").search('/') >= 0
92
+ f = $(this).attr("data-key")
93
+ media_panel.trigger("navigate_to", {folder: f.replace(/\/{2,}/g, '/')})
89
94
  )
90
95
  media_panel.bind("update_breadcrumb", ->
91
96
  folder = media_panel.attr("data-folder").replace("//", "/")
@@ -103,7 +108,7 @@ window["cama_init_media"] = (media_panel) ->
103
108
  breadrumb.push("<li><span>"+name+"</span></li>")
104
109
  else
105
110
  folder_prefix.push(value)
106
- breadrumb.push("<li><a data-path='"+(folder_prefix.join("/") || "/")+"' href='#'>"+name+"</a></li>")
111
+ breadrumb.push("<li><a data-path='"+(folder_prefix.join("/") || "/").replace(/\/{2,}/g, '/')+"' href='#'>"+name+"</a></li>")
107
112
  media_panel.find(".media_folder_breadcrumb").html(breadrumb.join(""))
108
113
  ).trigger("update_breadcrumb")
109
114
  ## end folders
@@ -118,7 +123,7 @@ window["cama_init_media"] = (media_panel) ->
118
123
  media_link_tab_upload.click()
119
124
 
120
125
  showLoading()
121
- $.get(media_panel.attr("data-url"), {folder: folder, partial: true, media_formats: media_panel.attr("data-formats")}, (res)->
126
+ $.get(media_panel.attr("data-url"), {folder: folder.replace(/\/{2,}/g, '/'), partial: true, media_formats: media_panel.attr("data-formats")}, (res)->
122
127
  media_panel.find(".media_browser_list").html(res)
123
128
  hideLoading()
124
129
  )
@@ -129,6 +134,23 @@ window["cama_init_media"] = (media_panel) ->
129
134
  item.click()
130
135
  )
131
136
 
137
+ # search file
138
+ media_panel.find('#cama_search_form').submit ->
139
+ showLoading()
140
+ $.get(media_panel.attr("data-url"), {search: $(this).find('input:text').val(), partial: true, media_formats: media_panel.attr("data-formats")}, (res)->
141
+ media_panel.find(".media_browser_list").html(res)
142
+ hideLoading()
143
+ )
144
+ return false
145
+
146
+ # reload current directory
147
+ media_panel.find('.cam_media_reload').click (e)->
148
+ showLoading()
149
+ $.get(media_panel.attr("data-url"), {partial: true, media_formats: media_panel.attr("data-formats"), folder: media_panel.attr("data-folder"), cama_media_reload: $(this).attr('data-action')}, (res)->
150
+ media_panel.find(".media_browser_list").html(res)
151
+ hideLoading()
152
+ )
153
+ e.preventDefault()
132
154
 
133
155
  # element actions
134
156
  media_panel.on("click", "a.add_folder", ->
@@ -143,10 +165,10 @@ window["cama_init_media"] = (media_panel) ->
143
165
  ).trigger("keyup")
144
166
  modal.find("form").submit ->
145
167
  showLoading()
146
- $.post(media_panel.attr("data-url_actions"), {folder: media_panel.attr("data-folder")+"/"+input.val(), media_action: "new_folder"}, (res)->
168
+ $.post(media_panel.attr("data-url_actions"), {folder: media_panel.attr("data-folder")+"/"+input.val().replace(/\/{2,}/g, '/'), media_action: "new_folder"}, (res)->
147
169
  hideLoading()
148
170
  modal.modal("hide")
149
- if res.search("<") == 0 # success upload
171
+ if res.search("folder_item") >= 0 # success upload
150
172
  media_panel.find(".media_browser_list").append(res)
151
173
  else
152
174
  $.fn.alert({type: 'error', content: res, title: "Error"})
@@ -163,7 +185,7 @@ window["cama_init_media"] = (media_panel) ->
163
185
  link = $(this)
164
186
  item = link.closest(".media_item")
165
187
  showLoading()
166
- $.post(media_panel.attr("data-url_actions"), {folder: media_panel.attr("data-folder")+"/"+item.attr("data-key"), media_action: if link.hasClass("del_folder") then "del_folder" else "del_file"}, (res)->
188
+ $.post(media_panel.attr("data-url_actions"), {folder: media_panel.attr("data-folder")+"/"+item.attr("data-key").replace(/\/{2,}/g, '/'), media_action: if link.hasClass("del_folder") then "del_folder" else "del_file"}, (res)->
167
189
  hideLoading()
168
190
  if res
169
191
  $.fn.alert({type: 'error', content: res, title: I18n("button.error")})
@@ -192,14 +214,14 @@ $ ->
192
214
  # folder: default current folder
193
215
  $.fn.upload_url = (args)->
194
216
  media_panel = $("#cama_media_gallery")
195
- data = {folder: media_panel.attr("data-folder"), media_action: "crop_url", formats: media_panel.attr("data-formats"), onerror: (message) ->
217
+ data = {folder: media_panel.attr("data-folder").replace(/\/{2,}/g, '/'), media_action: "crop_url", formats: media_panel.attr("data-formats"), onerror: (message) ->
196
218
  $.fn.alert({type: 'error', content: message, title: I18n("msg.error_uploading")})
197
219
  }
198
220
  $.extend(data, args); on_error = data["onerror"]; delete data["onerror"];
199
221
  showLoading()
200
222
  $.post(media_panel.attr("data-url_actions"), data, (res_upload)->
201
223
  hideLoading()
202
- if res_upload.search("<") == 0 # success upload
224
+ if res_upload.search("media_item") >= 0 # success upload
203
225
  media_panel.trigger("add_file", {item: res_upload})
204
226
  if data["callback"]
205
227
  data["callback"](res_upload)
@@ -217,8 +239,16 @@ $ ->
217
239
  # dimension: dimension: "30x30" | "x30" | dimension: "30x"
218
240
  $.fn.upload_filemanager = (args)->
219
241
  args = args || {}
220
- open_modal({title: args["title"] || I18n("msg.media_title"), id: 'cama_modal_file_uploader', modal_size: "modal-lg", mode: "ajax", url: root_url+"/admin/media/ajax", ajax_params: {media_formats: args["formats"], dimension: args["dimension"] }, callback: (modal)->
242
+ open_modal({title: args["title"] || I18n("msg.media_title"), id: 'cama_modal_file_uploader', modal_size: "modal-lg", mode: "ajax", url: root_admin_url+"/media/ajax", ajax_params: {media_formats: args["formats"], dimension: args["dimension"] }, callback: (modal)->
221
243
  if args["selected"]
222
244
  window["callback_media_uploader"] = args["selected"]
223
245
  modal.css("z-index", args["zindex"] || 99999).children(".modal-dialog").css("width", "90%")
224
246
  })
247
+
248
+ window['cama_humanFileSize'] = (size)->
249
+ units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
250
+ i = 0;
251
+ while(size >= 1024)
252
+ size /= 1024;
253
+ ++i;
254
+ return size.toFixed(1) + ' ' + units[i];
@@ -14,44 +14,37 @@ jQuery(function ($) {
14
14
 
15
15
  // on success photo crop
16
16
  function onSuccess() {
17
- $("#cp_photo").parent("a").find("span").html("Choose another photo");
18
- var img = $("#cp_target").find("#crop_image")
17
+ var form = $("#cp_crop");
18
+ var img = form.find("#crop_image");
19
19
  if (img.length === 1) {
20
- $("#cp_img_path").val(img.attr("src"));
21
-
20
+ form.find("[name='cp_img_path']").val(img.attr("src"));
22
21
  img.cropper({
23
22
  aspectRatio: 1,
23
+ minWidth: 100,
24
+ minHeight: 100,
25
+ maxWidth: 200,
26
+ maxHeight: 200,
24
27
  done: function (data) {
25
- $("#ic_x").val(data.x);
26
- $("#ic_y").val(data.y);
27
- $("#ic_h").val(data.height);
28
- $("#ic_w").val(data.width);
28
+ form.find("[name='ic_x']").val(data.x);
29
+ form.find("[name='ic_y']").val(data.y);
30
+ form.find("[name='ic_h']").val(data.height);
31
+ form.find("[name='ic_w']").val(data.width);
29
32
  }
30
33
  });
31
34
 
32
- $("#cp_accept").prop("disabled", false).removeClass("disabled");
33
- $("#cp_crop").css({"width": "400px", "margin": "0px auto"});
34
- $("#cp_crop").find('.modal-body').css({"max-height": "400px", "overflow": "auto"});
35
- $("#cp_accept").unbind("click").on("click", function () {
36
- //$("#user_image").html('<img src="/assets/loader.gif"/>');
35
+ $("#cp_accept").prop("disabled", false).unbind("click").on("click", function () {
37
36
  $("#modal_change_photo").modal("hide");
38
- $("#cp_crop").ajaxForm({
39
- beforeSend: function () {
40
- showLoading();
41
- }, success: function (res) {
42
- hideLoading();
43
- if (res != "") $("#modal_change_password .modal-body").flash_message(res);
44
- $("#user_image").html('<img class="img-thumbnail" src="' + res + '?r=' + Math.random() + '"/>');
45
- hideLoading();
46
- },
47
- error: function(){
48
- $.fn.alert({type: 'error', content: 'Internal Error', title: "Error"})
49
- }
50
- }).submit();
51
- $("#cp_target").html("Use form below to upload file. Only image files.");
52
- $("#cp_photo").val("").parent("a").find("span").html("Select file");
53
- $("#cp_accept").prop("disabled", true).addClass("disabled");
37
+ showLoading();
38
+ $.post(form.attr('action'), form.serialize(), function(res){
39
+ hideLoading();
40
+ $("#user_image").html('<img class="img-thumbnail" src="' + res + '?r=' + Math.random() + '"/>');
41
+ }).error(function(){
42
+ $.fn.alert({type: 'error', content: 'Internal Error', title: "Error"})
43
+ });
44
+ $("#cp_accept").prop("disabled", true);
54
45
  $("#cp_img_path").val("");
46
+ $("#cp_target").html("");
47
+ return false;
55
48
  });
56
49
  }
57
50
  }
@@ -65,6 +58,7 @@ jQuery(function ($) {
65
58
  },
66
59
  user_pwd: '<%= current_user_pwd %>'
67
60
  });
61
+ return false;
68
62
  });
69
63
 
70
64
  });
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Bootstrap-select v1.10.0 (http://silviomoreto.github.io/bootstrap-select)
3
+ *
4
+ * Copyright 2013-2016 bootstrap-select
5
+ * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
6
+ */select.bs-select-hidden,select.selectpicker{display:none!important}.bootstrap-select{width:220px\9}.bootstrap-select>.dropdown-toggle{width:100%;padding-right:25px;z-index:1}.bootstrap-select>select{position:absolute!important;bottom:0;left:50%;display:block!important;width:.5px!important;height:100%!important;padding:0!important;opacity:0!important;border:none}.bootstrap-select>select.mobile-device{top:0;left:0;display:block!important;width:100%!important;z-index:2}.error .bootstrap-select .dropdown-toggle,.has-error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .dropdown-toggle:focus{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none}.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.form-control.input-group-btn{z-index:auto}.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.btn-group.dropdown-menu-right,.bootstrap-select.btn-group[class*=col-].dropdown-menu-right,.row .bootstrap-select.btn-group[class*=col-].dropdown-menu-right{float:right}.form-group .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group{margin-bottom:0}.form-group-lg .bootstrap-select.btn-group.form-control,.form-group-sm .bootstrap-select.btn-group.form-control{padding:0}.form-inline .bootstrap-select.btn-group .form-control{width:100%}.bootstrap-select.btn-group.disabled,.bootstrap-select.btn-group>.disabled{cursor:not-allowed}.bootstrap-select.btn-group.disabled:focus,.bootstrap-select.btn-group>.disabled:focus{outline:0!important}.bootstrap-select.btn-group.bs-container{position:absolute}.bootstrap-select.btn-group.bs-container .dropdown-menu{z-index:1060}.bootstrap-select.btn-group .dropdown-toggle .filter-option{display:inline-block;overflow:hidden;width:100%;text-align:left}.bootstrap-select.btn-group .dropdown-toggle .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group[class*=col-] .dropdown-toggle{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;float:none;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li.active small{color:#fff}.bootstrap-select.btn-group .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select.btn-group .dropdown-menu li a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bootstrap-select.btn-group .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select.btn-group .dropdown-menu li a span.check-mark{display:none}.bootstrap-select.btn-group .dropdown-menu li a span.text{display:inline-block}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px;white-space:nowrap}.bootstrap-select.btn-group.fit-width .dropdown-toggle .filter-option{position:static}.bootstrap-select.btn-group.fit-width .dropdown-toggle .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{position:absolute;display:inline-block;right:15px;margin-top:5px}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle{z-index:1061}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid rgba(204,204,204,.2);border-bottom:0}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before{display:block}.bs-actionsbox,.bs-donebutton,.bs-searchbox{padding:4px 8px}.bs-actionsbox{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-donebutton{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-donebutton .btn-group button{width:100%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox .form-control{margin-bottom:0;width:100%;float:none}
@@ -15,13 +15,12 @@
15
15
  *= require ./lte/skins/skin-blue
16
16
  *= require ./_custom_admin
17
17
 
18
- *= require ./bootstrap-datepicker
18
+ *= require ./_bootstrap-datepicker
19
19
  *= require ./introjs/_introjs.min
20
20
  *= require ./tageditor/_jquery.tag-editor
21
21
 
22
22
  *= require ./uploader/_uploadfile
23
-
24
-
23
+ *= require ./_bootstrap-select
25
24
 
26
25
  // post
27
26
  *= require ./_jquery.tagsinput
@@ -54,14 +54,15 @@
54
54
  display: none;
55
55
  }
56
56
  .colorpicker {
57
- top: 0;
58
- left: 0;
59
- padding: 4px;
60
- min-width: 120px;
61
- margin-top: 1px;
62
- -moz-border-radius: 3px;
63
- -webkit-border-radius: 3px;
64
- border-radius: 3px;
57
+ top: 0;
58
+ left: 0;
59
+ padding: 4px;
60
+ min-width: 120px;
61
+ margin-top: 1px;
62
+ -moz-border-radius: 3px;
63
+ -webkit-border-radius: 3px;
64
+ border-radius: 3px;
65
+ z-index: 99999;
65
66
  }
66
67
  .colorpicker.dropdown-menu {
67
68
  margin-top: 8px;
@@ -231,6 +231,7 @@ margin: 5px 10px 5px 0px;
231
231
  .ajax-upload-dragdrop{
232
232
  width: 100% !important;
233
233
  min-height: 200px;
234
+ padding-top: 65px;
234
235
  &.state-hover{
235
236
  background-color: #ccc;
236
237
  }
@@ -240,16 +241,4 @@ margin: 5px 10px 5px 0px;
240
241
  width: 100% !important;
241
242
  }
242
243
  }
243
-
244
- .media_folder_breadcrumb{
245
- left: 0;
246
- position: absolute;
247
- top: 0;
248
- width: 100%;
249
- }
250
- .add_folder{
251
- position: absolute;
252
- right: 17px;
253
- top: 5px;
254
- }
255
244
  }
@@ -9,116 +9,132 @@
9
9
  class CamaleonCms::Admin::Appearances::NavMenusController < CamaleonCms::AdminController
10
10
  add_breadcrumb I18n.t("camaleon_cms.admin.sidebar.appearance")
11
11
  add_breadcrumb I18n.t("camaleon_cms.admin.sidebar.menus")
12
- def menu
13
- authorize! :manager, :menu
14
- unless params[:new].present?
15
- if params[:id].present?
16
- @nav_menu = current_site.nav_menus.find_by_id(params[:id])
17
- if request.delete? && @nav_menu.present?
18
- @nav_menu.destroy
19
- flash[:notice] = t('camaleon_cms.admin.menus.message.deleted')
20
- redirect_to action: :menu
21
- return
22
- end
23
- end
24
-
25
- unless @nav_menu.present?
26
- if params[:slug].present?
27
- @nav_menu = current_site.nav_menus.where({slug: params[:slug]}).first
28
- else
29
- @nav_menu = current_site.nav_menus.last
30
- end
31
- end
32
-
33
- end
34
- @nav_menu = current_site.nav_menus.new unless @nav_menu.present?
35
- items = []
36
- unless @nav_menu.new_record?
37
- items = get_nav_items(@nav_menu.children)
12
+ before_action :check_menu_permission
13
+ def index
14
+ if params[:id].present?
15
+ @nav_menu = current_site.nav_menus.find_by_id(params[:id])
16
+ elsif params[:slug].present?
17
+ @nav_menu = current_site.nav_menus.find_by_slug(params[:slug])
18
+ else
19
+ @nav_menu = current_site.nav_menus.first
38
20
  end
39
- @items = items
40
-
41
- @nav_menus = current_site.nav_menus.all
42
21
  @post_types = current_site.post_types
43
22
  add_asset_library("nav_menu")
44
23
  render "index"
45
24
  end
46
25
 
47
- # save changes of the menu
48
- def save
49
- authorize! :manager, :menu
50
- unless params[:nav_menu][:id].present? # new
51
- menu_data = params[:nav_menu]
52
- @nav_menu = current_site.nav_menus.new(menu_data)
53
- if @nav_menu.save
54
- flash[:notice] = t('camaleon_cms.admin.menus.message.created')
55
- render json: {new: 1, nav_menu: @nav_menu, redirect: cama_admin_appearances_nav_menus_menu_path({id: @nav_menu.id})}
56
- else
57
- render json: {error: t('camaleon_cms.admin.menus.message.error_menu')}
58
- end
59
- else
60
- @nav_menu = current_site.nav_menus.find(params[:nav_menu][:id])
61
- if @nav_menu.update(params[:nav_menu])
62
- @nav_menu.add_menu_items(params[:menu_data])
26
+ def new
27
+ @nav_menu = current_site.nav_menus.new
28
+ render partial: 'form'
29
+ end
63
30
 
64
- if params[:nav_menu_location].present?
65
- params[:nav_menu_location].each do |location|
66
- current_site.set_option("_nav_menu_#{location}", @nav_menu.id)
67
- end
68
- end
69
- render json: {update: 1, nav_menu: @nav_menu}
70
- else
71
- render json: {error: t('camaleon_cms.admin.menus.message.error_menu')}
72
- end
73
- end
31
+ def create
32
+ nav_menu = current_site.nav_menus.new(params[:nav_menu])
33
+ nav_menu.save
34
+ flash[:notice] = t('.created_menu', default: 'Created Menu')
35
+ redirect_to action: :index, id: nav_menu.id
74
36
  end
75
37
 
76
- # show external menu form
77
- def form
78
- if params[:custom_fields].present?
79
- if params[:item_id] == 'undefined'
80
- @nav_menu = current_site.nav_menus.find_by_id(params[:menu_id])
81
- else
82
- @nav_menu = current_site.nav_menu_items.find_by_id(params[:item_id])
83
- end
84
- render "_custom_fields", layout: "camaleon_cms/admin/_ajax"
85
- else
86
- render "_external_menu", layout: false, locals: {submit: true}
87
- end
38
+ def update
39
+ nav_menu = current_site.nav_menus.find(params[:id])
40
+ nav_menu.update(params[:nav_menu])
41
+ flash[:notice] = t('.updated_menu', default: 'Menu updated')
42
+ redirect_to action: :index, id: nav_menu.id
88
43
  end
89
44
 
90
- private
45
+ def edit
46
+ @nav_menu = current_site.nav_menus.find(params[:id])
47
+ render partial: 'form'
48
+ end
91
49
 
92
- def get_nav_items(menu_items, parent_id = 0)
50
+ def destroy
51
+ current_site.nav_menus.find(params[:id]).destroy
52
+ flash[:notice] = t('.deleted_menu', default: 'Menu destroyed')
53
+ redirect_to action: :index
54
+ end
55
+
56
+ def custom_settings
57
+ @nav_menu = current_site.nav_menus.find(params[:nav_menu_id])
58
+ @nav_menu_item = current_site.nav_menu_items.find(params[:id])
59
+ render "_custom_fields", layout: "camaleon_cms/admin/_ajax"
60
+ end
61
+
62
+ def save_custom_settings
63
+ @nav_menu_item = current_site.nav_menu_items.find(params[:id])
64
+ @nav_menu_item.set_field_values(params[:field_options])
65
+ render nothing: true
66
+ end
67
+
68
+ # render edit external menu item
69
+ def edit_menu_item
70
+ render "_external_menu", layout: false, locals: {nav_menu: current_site.nav_menus.find(params[:nav_menu_id]), menu_item: current_site.nav_menu_items.find(params[:id])}
71
+ end
72
+
73
+ # update an external menu item
74
+ def update_menu_item
75
+ @nav_menu = current_site.nav_menus.find(params[:nav_menu_id])
76
+ item = current_site.nav_menu_items.find(params[:id])
77
+ item.update_menu_item({label: params[:external_label], link: params[:external_url]})
78
+ item.set_options(params[:options]) if params[:options].present?
79
+ render partial: 'menu_items', locals: {items: [item], nav_menu: @nav_menu}
80
+ end
81
+
82
+ def delete_menu_item
83
+ # @nav_menu = current_site.nav_menus.find(params[:nav_menu_id])
84
+ current_site.nav_menu_items.find(params[:id]).destroy
85
+ render nothing: true
86
+ end
87
+
88
+ # update the reorder of items
89
+ def reorder_items(items = nil, parent_id = nil, is_root = true)
90
+ items = params[:items] if items.nil?
91
+ parent_id = params[:nav_menu_id] if parent_id.nil?
92
+ items.each do |index, _item|
93
+ item = current_site.nav_menu_items.find(_item['id'])
94
+ item.update_column(:parent_id, parent_id)
95
+ reorder_items(_item['children'], _item['id'], false) if _item['children'].present?
96
+ end
97
+ render(inline: '') if is_root
98
+ end
99
+
100
+ # add items to specific nav-menu
101
+ def add_items
93
102
  items = []
94
- menu_items.eager_load(:metas).each do |nav_item|
95
- object = _get_object_nav_menu(nav_item)
96
- if object.present?
97
- items << {id: nav_item.id, label: object[:name], link: nav_item.options[:object_id], url_edit: object[:url_edit], type: nav_item.options[:type], parent: parent_id.to_i, fields: "#{nav_item.get_field_values_hash(true).to_json}"}
98
- items += get_nav_items(nav_item.children, nav_item.id)
103
+ @nav_menu = current_site.nav_menus.find(params[:nav_menu_id])
104
+ if params[:external].present?
105
+ item = @nav_menu.append_menu_item({label: params[:external][:external_label], link: params[:external][:external_url], type: "external"})
106
+ item.set_options(params[:external][:options]) if params[:external][:options].present?
107
+ items << item
108
+ end
109
+
110
+ if params[:items].present?
111
+ params[:items].each do |index, item|
112
+ item = @nav_menu.append_menu_item({label: 'auto', link: item['id'], type: item['kind']})
113
+ items << item
99
114
  end
100
115
  end
101
- return items
116
+ render partial: 'menu_items', locals: {items: items, nav_menu: @nav_menu}
102
117
  end
103
118
 
104
- def _get_object_nav_menu(nav_menu_item)
119
+ private
120
+ def parse_menu_item(nav_menu_item)
105
121
  begin
106
122
  case nav_menu_item.get_option('type')
107
123
  when 'post'
108
124
  post = CamaleonCms::Post.find(nav_menu_item.get_option('object_id')).decorate
109
125
  return false unless post.status == 'published'
110
- {link: post.the_url, name: post.the_title, url_edit: post.the_edit_url }
126
+ {name: post.the_title(locale: @frontend_locale), url_edit: post.the_edit_url }
111
127
  when 'category'
112
128
  category = CamaleonCms::Category.find(nav_menu_item.get_option('object_id')).decorate
113
- {link: category.the_url, name: category.the_title, url_edit: category.the_edit_url}
129
+ {name: category.the_title, url_edit: category.the_edit_url}
114
130
  when 'post_tag'
115
131
  post_tag = CamaleonCms::PostTag.find(nav_menu_item.get_option('object_id')).decorate
116
- {link: post_tag.the_url, name: post_tag.the_title, url_edit: post_tag.the_edit_url}
132
+ {name: post_tag.the_title, url_edit: post_tag.the_edit_url}
117
133
  when 'post_type'
118
134
  post_type = CamaleonCms::PostType.find(nav_menu_item.get_option('object_id')).decorate
119
- {link: post_type.the_url, name: post_type.the_title, url_edit: post_type.the_edit_url}
135
+ {name: post_type.the_title, url_edit: post_type.the_edit_url}
120
136
  when 'external'
121
- {link: nav_menu_item.get_option('object_id'), name: nav_menu_item.name.to_s}
137
+ {name: nav_menu_item.name.to_s}
122
138
  else
123
139
  false
124
140
  end
@@ -127,4 +143,9 @@ class CamaleonCms::Admin::Appearances::NavMenusController < CamaleonCms::AdminCo
127
143
  false
128
144
  end
129
145
  end
146
+ helper_method :parse_menu_item
147
+
148
+ def check_menu_permission
149
+ authorize! :manager, :menu
150
+ end
130
151
  end