camaleon_cms 2.4.2 → 2.4.3

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/app/apps/plugins/visibility_post/assets/js/form.js +2 -2
  3. data/app/assets/javascripts/camaleon_cms/admin/_i18n.js +3 -7
  4. data/app/assets/javascripts/camaleon_cms/admin/_post.js +1 -1
  5. data/app/assets/javascripts/camaleon_cms/admin/admin-manifest.js +0 -3
  6. data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js.coffee +1 -1
  7. data/app/assets/javascripts/camaleon_cms/admin/{form/cropper.min.js → uploader/_cropper.min.js} +0 -0
  8. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +3 -2
  9. data/app/assets/javascripts/camaleon_cms/admin/uploader/uploader_manifest.js +3 -1
  10. data/app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css +1 -2
  11. data/app/assets/stylesheets/camaleon_cms/admin/{cropper/cropper.min.css → uploader/_cropper.min.css} +0 -0
  12. data/app/assets/stylesheets/camaleon_cms/admin/uploader/uploader_manifest.css +4 -0
  13. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +2 -29
  14. data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +5 -4
  15. data/app/decorators/camaleon_cms/category_decorator.rb +3 -3
  16. data/app/decorators/camaleon_cms/post_decorator.rb +7 -13
  17. data/app/decorators/camaleon_cms/post_tag_decorator.rb +4 -2
  18. data/app/decorators/camaleon_cms/post_type_decorator.rb +3 -3
  19. data/app/decorators/camaleon_cms/user_decorator.rb +1 -0
  20. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +42 -27
  21. data/app/helpers/camaleon_cms/hooks_helper.rb +1 -1
  22. data/app/helpers/camaleon_cms/site_helper.rb +1 -1
  23. data/app/mailers/camaleon_cms/html_mailer.rb +2 -2
  24. data/app/models/camaleon_cms/nav_menu_item.rb +1 -0
  25. data/app/models/camaleon_cms/post.rb +1 -1
  26. data/app/models/camaleon_cms/post_comment.rb +1 -1
  27. data/app/models/camaleon_cms/post_tag.rb +1 -1
  28. data/app/models/camaleon_cms/post_type.rb +1 -1
  29. data/app/models/camaleon_cms/term_taxonomy.rb +1 -1
  30. data/app/models/camaleon_cms/user.rb +9 -4
  31. data/app/models/camaleon_cms/widget/main.rb +1 -1
  32. data/app/models/concerns/camaleon_cms/user_methods.rb +11 -35
  33. data/app/views/camaleon_cms/admin/appearances/nav_menus/_custom_menus.html.erb +3 -3
  34. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_items.html.erb +3 -2
  35. data/app/views/camaleon_cms/admin/plugins/_plugins_list.html.erb +1 -1
  36. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +1 -1
  37. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_image.html.erb +1 -1
  38. data/app/views/camaleon_cms/default_theme/partials/_comments.html.erb +1 -1
  39. data/config/routes/frontend.rb +10 -17
  40. data/lib/camaleon_cms/version.rb +1 -1
  41. data/lib/ext/string.rb +7 -0
  42. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +5 -1
  43. data/lib/generators/camaleon_cms/gem_plugin_template/app/controllers/plugins/my_plugin/admin_controller.rb +12 -2
  44. data/lib/generators/camaleon_cms/gem_plugin_template/app/helpers/plugins/my_plugin/main_helper.rb +7 -0
  45. data/lib/generators/camaleon_cms/gem_plugin_template/app/views/plugins/my_plugin/admin/settings.html.erb +21 -0
  46. data/lib/generators/camaleon_cms/gem_plugin_template/config/camaleon_plugin.json +3 -6
  47. data/lib/plugin_routes.rb +1 -1
  48. data/spec/dummy/db/test.sqlite3 +0 -0
  49. metadata +8 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc0c0bfe97ca32699104dd35f9bfd703ec8ff7d4
4
- data.tar.gz: 5c23a7dc2ffd16ab5ddb78e4ea00df6277f02111
3
+ metadata.gz: 205446e9210d677532d7361988a9383be938b8cb
4
+ data.tar.gz: 79bd3290fcc54bc2fe42c2d624c78f6b76287420
5
5
  SHA512:
6
- metadata.gz: a3b634f003d4e7b5c099cc5970ff0ea3b14c2707015442b307eb44971a0e66ce10519ea6542127d76d558a2f629d28176ecb83dde8e9cc0fa8fa17f4fae8c56f
7
- data.tar.gz: 460cb36ffd415cfc8ccfc75516057398771ae93e2c9550d09c549a8d2cc91ec2de7c4c5438a1dfa3370301c985404fac7e01747978e943bf58c8e23065595165
6
+ metadata.gz: dd2007e5c789b1fbd6470ef61ec9af7bd04b7e976d5bc8b790ea1814d20d51988bd40f2e9ef5259f2739bca67f602730c0a86272642b8afa8beb6f81ce7ad160
7
+ data.tar.gz: 9ec35495f3dda62745d76822a2857842ad18c11e94b0f2e103615a0124fea1be0b183962c32e8d60a13c17800d09a70ac6fd31af5d1b5fb851efdc8a37c14f79
@@ -1,12 +1,12 @@
1
1
  jQuery(function($){
2
2
  var panel = $("#panel-post-visibility");
3
3
  var link_edit = panel.find(".edit-visibility").click(function(){
4
- panel.find(".panel-options").removeClass("hidden").show();
4
+ panel.find(".panel-options").removeClass("hidden").show().find('input[name="post_private_groups[]"]:first').addClass('required data-error-place-parent');
5
5
  link_edit.hide();
6
6
  return false;
7
7
  });
8
8
  panel.find(".lnk_hide").click(function(){
9
- panel.find(".panel-options").hide();
9
+ panel.find(".panel-options").hide().find('input[name="post_private_groups[]"]:first').removeClass('required');
10
10
  link_edit.show();
11
11
  return false;
12
12
  });
@@ -9,17 +9,13 @@
9
9
  // if default_val is empty, will be returned the last key titleized
10
10
  // data: (hash) replacement values in the value, sample: {title: 'my title'}
11
11
  var I18n = function(key, default_val, data){
12
- try {
13
- var res = eval("I18n_data." + key);
14
- if (!res) res = default_val ? default_val : ("" + key.split(".").pop()).titleize();
15
- }catch(e){
16
- var res = (""+key.split(".").pop()).titleize();
17
- }
12
+ var res = '';
13
+ try { res = eval("I18n_data." + key); }catch(e){}
14
+ if (!res) res = default_val ? default_val : ("" + key.split(".").pop()).titleize();
18
15
 
19
16
  // replacements
20
17
  data = data || {}
21
18
  for(key in data){
22
- console.log(key, data[key])
23
19
  res = res.replace("%{"+key+"}", data[key])
24
20
  }
25
21
  return res;
@@ -140,7 +140,7 @@ function cama_init_post(obj) {
140
140
  var $btn = $(this);
141
141
  var $btn_edit = $('<a href="#" class="btn btn-default btn-xs btn-edit">' + I18n("button.accept") + '</a> &nbsp; <a href="#" class="btn-cancel">' + I18n("button.cancel") + '</a>');
142
142
  var $label = $link.find('.sl-url');
143
- var $input = $("<input type='text' />");
143
+ var $input = $("<input type='text' />").keyup(function(e){ if(e.keyCode == 13){ $btn_edit.filter('.btn-edit').click(); return false; } });
144
144
  $label.hide().after($input);
145
145
  $btn.hide().after($btn_edit);
146
146
  $input.val($label.text());
@@ -33,11 +33,8 @@
33
33
  //= require ./_actions
34
34
  //= require ./introjs/_intro.min
35
35
 
36
-
37
36
  // uploader
38
- //= require ./_modal
39
37
  //= require ./uploader/uploader_manifest
40
- //= require ./form/cropper.min
41
38
 
42
39
  //= require ./tageditor/_jquery.caret.min
43
40
  //= require ./tageditor/_jquery.tag-editor
@@ -48,7 +48,7 @@ $ ->
48
48
  flag =false
49
49
  $(this).closest('.panel').find('input:checkbox:checked').each(->
50
50
  flag = true
51
- data['custom_items'].push({url: $(this).val(), label: $(this).attr('data-label')})
51
+ data['custom_items'].push({url: $(this).val(), kind: $(this).attr('data-kind'), label: $(this).attr('data-label')})
52
52
  ).prop('checked', false)
53
53
 
54
54
  unless flag
@@ -313,8 +313,9 @@ window["cama_init_media"] = (media_panel) ->
313
313
  unless field_height.attr("readonly")
314
314
  field_height.val(Math.round(e.height))
315
315
  , built: ()->
316
- if modal.find('.cropper-canvas img').attr('crossorigin')
316
+ $.get(data['url']).error(->
317
317
  modal.find('.modal-body').html('<div class="alert alert-danger">'+I18n('msg.cors_error', 'Please verify the following: <ul><li>If the image exist: %{url_img}</li> <li>Check if cors configuration are defined well, only for external images: S3, cloudfront(if you are using cloudfront).</li></ul><br> More information about CORS: <a href="%{url_blog}" target="_blank">here.</a>', {url_img: data['url'], url_blog: 'http://blog.celingest.com/en/2014/10/02/tutorial-using-cors-with-cloudfront-and-s3/'})+'</div>')
318
+ )
318
319
  }
319
320
 
320
321
  if media_panel.attr("data-dimension") # TODO: control dimensions
@@ -334,7 +335,7 @@ window["cama_init_media"] = (media_panel) ->
334
335
  else
335
336
  field_height.prop('readonly', true)
336
337
  if dim[0] && dim[0].search(/\?/) == -1 && dim[1] && dim[1].search(/\?/) == -1
337
- cropper_data['cropBoxResizable'] = false
338
+ cropper_data['aspectRatio'] = cropper_data['data']['width']/cropper_data['data']['height']
338
339
 
339
340
  cropper = modal.find('img.editable').cropper(cropper_data)
340
341
  hideLoading()
@@ -1,3 +1,5 @@
1
1
  //= require ./_jquery.form
2
2
  //= require ./_jquery.uploadfile.min
3
- //= require ./_media_manager
3
+ //= require ./_media_manager
4
+ //= require ./_cropper.min
5
+ //= require ../_modal
@@ -19,8 +19,7 @@
19
19
  *= require ./introjs/_introjs.min
20
20
  *= require ./tageditor/_jquery.tag-editor
21
21
 
22
- *= require ./uploader/_uploadfile
23
- *= require ./cropper/cropper.min
22
+ *= require ./uploader/uploader_manifest
24
23
  *= require ./_bootstrap-select
25
24
 
26
25
  // post
@@ -0,0 +1,4 @@
1
+ /*
2
+ *= require ./_cropper.min
3
+ *= require ./_uploadfile
4
+ */
@@ -1,4 +1,5 @@
1
1
  class CamaleonCms::Admin::Appearances::NavMenusController < CamaleonCms::AdminController
2
+ include CamaleonCms::Frontend::NavMenuHelper
2
3
  add_breadcrumb I18n.t("camaleon_cms.admin.sidebar.appearance")
3
4
  add_breadcrumb I18n.t("camaleon_cms.admin.sidebar.menus")
4
5
  before_action :check_menu_permission
@@ -101,7 +102,7 @@ class CamaleonCms::Admin::Appearances::NavMenusController < CamaleonCms::AdminCo
101
102
 
102
103
  if params[:custom_items].present? # custom menu items
103
104
  params[:custom_items].each do |index, item|
104
- item = @nav_menu.append_menu_item({label: item['label'], link: item['url'], type: 'external'})
105
+ item = @nav_menu.append_menu_item({label: item['label'], link: item['url'], type: item['kind'] || 'external'})
105
106
  items << item
106
107
  end
107
108
  end
@@ -116,34 +117,6 @@ class CamaleonCms::Admin::Appearances::NavMenusController < CamaleonCms::AdminCo
116
117
  end
117
118
 
118
119
  private
119
- def parse_menu_item(nav_menu_item)
120
- begin
121
- case nav_menu_item.kind
122
- when 'post'
123
- post = CamaleonCms::Post.find(nav_menu_item.url).decorate
124
- return false unless post.status == 'published'
125
- {name: post.the_title(locale: @frontend_locale), url_edit: post.the_edit_url }
126
- when 'category'
127
- category = CamaleonCms::Category.find(nav_menu_item.url).decorate
128
- {name: category.the_title, url_edit: category.the_edit_url}
129
- when 'post_tag'
130
- post_tag = CamaleonCms::PostTag.find(nav_menu_item.url).decorate
131
- {name: post_tag.the_title, url_edit: post_tag.the_edit_url}
132
- when 'post_type'
133
- post_type = CamaleonCms::PostType.find(nav_menu_item.url).decorate
134
- {name: post_type.the_title, url_edit: post_type.the_edit_url}
135
- when 'external'
136
- {name: nav_menu_item.name.to_s}
137
- else
138
- false
139
- end
140
- rescue => e
141
- Rails.logger.error "Camaleon CMS - Menu Item Not Found => Skipped menu for: #{e.message} (#{nav_menu_item})"
142
- false
143
- end
144
- end
145
- helper_method :parse_menu_item
146
-
147
120
  def check_menu_permission
148
121
  authorize! :manage, :nav_menu
149
122
  end
@@ -27,6 +27,7 @@ module CamaleonCms::FrontendConcern extend ActiveSupport::Concern
27
27
 
28
28
  # save comment from a post
29
29
  def save_comment
30
+ flash[:comment_submit] = {}
30
31
  @post = current_site.posts.find_by_id(params[:post_id]).decorate
31
32
  user = cama_current_user
32
33
  comment_data = {}
@@ -49,13 +50,13 @@ module CamaleonCms::FrontendConcern extend ActiveSupport::Concern
49
50
  comment_data[:content] = params[:post_comment][:content]
50
51
  @comment = params[:post_comment][:parent_id].present? ? @post.comments.find_by_id(params[:post_comment][:parent_id]).children.new(comment_data) : @post.comments.main.new(comment_data)
51
52
  if @comment.save
52
- flash[:notice] = t('camaleon_cms.admin.comments.message.created')
53
+ flash[:comment_submit][:notice] = t('camaleon_cms.admin.comments.message.created')
53
54
  else
54
- flash[:error] = "#{t('camaleon_cms.common.comment_error', default: 'An error was occurred on save comment')}:<br> #{@comment.errors.full_messages.join(', ')}"
55
+ flash[:comment_submit][:error] = "#{t('camaleon_cms.common.comment_error', default: 'An error was occurred on save comment')}:<br> #{@comment.errors.full_messages.join(', ')}"
55
56
  end
56
57
  else
57
- flash[:error] = t('camaleon_cms.admin.message.unauthorized')
58
+ flash[:comment_submit][:error] = t('camaleon_cms.admin.message.unauthorized')
58
59
  end
59
- params[:format] == 'json' ? render(json: flash.discard.to_hash) : redirect_to(:back)
60
+ params[:format] == 'json' ? render(json: flash.discard(:comment_submit).to_hash) : redirect_to(:back)
60
61
  end
61
62
  end
@@ -5,12 +5,12 @@ class CamaleonCms::CategoryDecorator < CamaleonCms::TermTaxonomyDecorator
5
5
  def the_url(*args)
6
6
  args = args.extract_options!
7
7
  args[:category_id] = the_id
8
- args[:title] = the_title.parameterize || the_slug
9
- args[:title] = the_slug unless args[:title].present?
8
+ args[:label] = I18n.t("routes.category", default: "category")
9
+ args[:title] = the_title.parameterize.presence || the_slug
10
10
  args[:locale] = @_deco_locale unless args.include?(:locale)
11
11
  args[:format] = args[:format] || "html"
12
12
  as_path = args.delete(:as_path)
13
- h.cama_url_to_fixed("cama_category#{_calc_locale(args[:locale])}_#{as_path.present? ? "path" : "url"}", args)
13
+ h.cama_url_to_fixed("cama_category_#{as_path.present? ? "path" : "url"}", args)
14
14
  end
15
15
 
16
16
  # return edit url for this category
@@ -67,47 +67,41 @@ class CamaleonCms::PostDecorator < CamaleonCms::ApplicationDecorator
67
67
  p_url_format = "hierarchy_post" if ptype.manage_hierarchy?
68
68
  case p_url_format
69
69
  when "post_of_post_type"
70
+ args[:label] = I18n.t('routes.group', default: 'group')
70
71
  args[:post_type_id] = ptype.id
71
- args[:title] = ptype.the_title(args[:locale]).parameterize
72
- args[:title] = ptype.the_slug unless args[:title].present?
72
+ args[:title] = ptype.the_title(args[:locale]).parameterize.presence || ptype.the_slug
73
73
  when "post_of_category"
74
74
  if ptype.manage_categories?
75
75
  cat = object.categories.first.decorate rescue ptype.default_category.decorate
76
+ args[:label_cat] = I18n.t("routes.category", default: "category")
76
77
  args[:category_id] = cat.id
77
78
  args[:title] = cat.the_title(args[:locale]).parameterize
78
79
  args[:title] = cat.the_slug unless args[:title].present?
79
80
  else
80
81
  p_url_format = "post"
81
- l = ""
82
82
  end
83
83
  when "post_of_posttype"
84
- args[:post_type_title] = ptype.the_title(args[:locale]).parameterize
85
- args[:post_type_title] = ptype.the_slug unless args[:post_type_title].present?
86
- l = ""
84
+ args[:post_type_title] = ptype.the_title(args[:locale]).parameterize.presence || ptype.the_slug
87
85
  when "post_of_category_post_type"
88
86
  if ptype.manage_categories?
89
87
  cat = object.categories.first.decorate rescue ptype.default_category.decorate
90
- args[:post_type_title] = ptype.the_title(args[:locale]).parameterize
91
- args[:post_type_title] = ptype.the_slug unless args[:post_type_title].present?
88
+ args[:label_cat] = I18n.t("routes.category", default: "category")
89
+ args[:post_type_title] = ptype.the_title(args[:locale]).parameterize.presence || ptype.the_slug
92
90
  args[:category_id] = cat.id
93
91
  args[:title] = cat.the_title(args[:locale]).parameterize
94
92
  args[:title] = cat.the_slug unless args[:title].present?
95
93
  else
96
94
  p_url_format = "post"
97
- l = ""
98
95
  end
99
96
  when 'hierarchy_post'
100
- l = ""
101
97
  if object.post_parent.present?
102
98
  slugs = ([args[:slug]]+object.parents.map{|parent| parent.decorate.the_slug(args[:locale]) }).reverse
103
99
  args[:slug], args[:parent_title] = slugs.slice(1..-1).join("/"), slugs.first
104
100
  else
105
101
  p_url_format = "post"
106
102
  end
107
- else
108
- l = ""
109
103
  end
110
- h.cama_url_to_fixed("cama_#{p_url_format}#{l}_#{p}", args)
104
+ h.cama_url_to_fixed("cama_#{p_url_format}_#{p}", args)
111
105
  end
112
106
 
113
107
  # return a hash of frontend urls for this post
@@ -4,22 +4,24 @@ class CamaleonCms::PostTagDecorator < CamaleonCms::TermTaxonomyDecorator
4
4
  # return the public url for this post tag, sample: # return basic in this format: http://localhost:3000/tag/31-mytag-title.html
5
5
  def the_url(*args)
6
6
  args = args.extract_options!
7
+ args[:label] = I18n.t('routes.tag', default: 'tag')
7
8
  args[:post_tag_id] = the_id
8
9
  args[:title] = the_title.parameterize.presence || the_slug
9
10
  args[:locale] = get_locale unless args.include?(:locale)
10
11
  args[:format] = args[:format] || "html"
11
12
  as_path = args.delete(:as_path)
12
- h.cama_url_to_fixed("cama_post_tag#{_calc_locale(args[:locale])}_#{as_path.present? ? "path" : "url"}", args)
13
+ h.cama_url_to_fixed("cama_post_tag_#{as_path.present? ? "path" : "url"}", args)
13
14
  end
14
15
 
15
16
  # return basic url in this format: http://localhost:3000/tag/mytag.html
16
17
  def the_basic_url(*args)
17
18
  args = args.extract_options!
19
+ args[:label] = I18n.t('routes.tag', default: 'tag')
18
20
  args[:post_tag_slug] = the_slug
19
21
  args[:locale] = get_locale unless args.include?(:locale)
20
22
  args[:format] = args[:format] || "html"
21
23
  as_path = args.delete(:as_path)
22
- h.cama_url_to_fixed("cama_post_tag_simple#{_calc_locale(args[:locale])}_#{as_path.present? ? "path" : "url"}", args)
24
+ h.cama_url_to_fixed("cama_post_tag_simple_#{as_path.present? ? "path" : "url"}", args)
23
25
  end
24
26
 
25
27
  # return edit url for this post
@@ -17,13 +17,13 @@ class CamaleonCms::PostTypeDecorator < CamaleonCms::TermTaxonomyDecorator
17
17
  # Sample: http://localhost/group/10-my-group.html
18
18
  def the_group_url(*args)
19
19
  args = args.extract_options!
20
+ args[:label] = I18n.t('routes.group', default: 'group')
20
21
  args[:post_type_id] = the_id
21
- args[:title] = the_title.parameterize
22
- args[:title] = the_slug unless args[:title].present?
22
+ args[:title] = the_title.parameterize.presence ||the_slug
23
23
  args[:locale] = get_locale unless args.include?(:locale)
24
24
  args[:format] = args[:format] || "html"
25
25
  as_path = args.delete(:as_path)
26
- h.cama_url_to_fixed("cama_post_type#{_calc_locale(args[:locale])}_#{as_path.present? ? "path" : "url"}", args)
26
+ h.cama_url_to_fixed("cama_post_type_#{as_path.present? ? "path" : "url"}", args)
27
27
  end
28
28
 
29
29
  # return edit url for this post type
@@ -30,6 +30,7 @@ class CamaleonCms::UserDecorator < CamaleonCms::ApplicationDecorator
30
30
  # return front url for this user
31
31
  def the_url(*args)
32
32
  args = args.extract_options!
33
+ args[:label] = I18n.t("routes.profile", default: "profile")
33
34
  args[:user_id] = the_id
34
35
  args[:user_name] = the_name.parameterize
35
36
  args[:user_name] = the_username unless args[:user_name].present?
@@ -65,7 +65,7 @@ module CamaleonCms::Frontend::NavMenuHelper
65
65
  index = 0
66
66
  nav_menu.eager_load(:metas).each do |nav_menu_item|
67
67
  _args = args.dup
68
- data_nav_item = _get_link_nav_menu(nav_menu_item)
68
+ data_nav_item = cama_parse_menu_item(nav_menu_item)
69
69
  next if data_nav_item == false
70
70
  _is_current = data_nav_item[:current] || site_current_path == data_nav_item[:link] || site_current_path == data_nav_item[:link].sub(".html", "")
71
71
  has_children = nav_menu_item.have_children? && (args[:levels] == -1 || (args[:levels] != -1 && level <= args[:levels]))
@@ -111,7 +111,7 @@ module CamaleonCms::Frontend::NavMenuHelper
111
111
  def cama_menu_parse_items(items, max_levels=-1, internal_level=0)
112
112
  res, is_current_parent, levels = [], false, [0]
113
113
  items.reorder(:term_order).each_with_index do |nav_menu_item, index|
114
- data_nav_item = _get_link_nav_menu(nav_menu_item)
114
+ data_nav_item = cama_parse_menu_item(nav_menu_item)
115
115
  next if data_nav_item == false
116
116
  _is_current = data_nav_item[:current] || site_current_path == data_nav_item[:link] || site_current_path == data_nav_item[:link].sub(".html", "")
117
117
  has_children = nav_menu_item.have_children?
@@ -174,48 +174,63 @@ module CamaleonCms::Frontend::NavMenuHelper
174
174
  end
175
175
 
176
176
 
177
- private
178
- def _get_link_nav_menu(nav_menu_item)
179
- type_menu, r = nav_menu_item.kind, false
177
+ def cama_parse_menu_item(nav_menu_item, is_from_backend = false)
178
+ type_menu, result = nav_menu_item.kind, false
180
179
  begin
181
180
  case type_menu
182
181
  when 'post'
183
182
  post = CamaleonCms::Post.find(nav_menu_item.url).decorate
184
- r = {link: post.the_url(as_path: true), name: post.the_title, type_menu: type_menu, current: @cama_visited_post.present? && @cama_visited_post.id == post.id} if post.can_visit?
183
+ if is_from_backend || post.can_visit?
184
+ result = {link: post.the_url(as_path: true), name: post.the_title, type_menu: type_menu, url_edit: post.the_edit_url}
185
+ result[:current] = @cama_visited_post.present? && @cama_visited_post.id == post.id unless is_from_backend
186
+ end
185
187
  when 'category'
186
188
  category = CamaleonCms::Category.find(nav_menu_item.url).decorate
187
- r = {link: category.the_url(as_path: true), name: category.the_title, type_menu: type_menu, current: @cama_visited_category.present? && @cama_visited_category.id == category.id}
189
+ result = {link: category.the_url(as_path: true), name: category.the_title, url_edit: category.the_edit_url}
190
+ result[:current] = @cama_visited_category.present? && @cama_visited_category.id == category.id unless is_from_backend
188
191
  when 'post_tag'
189
192
  post_tag = CamaleonCms::PostTag.find(nav_menu_item.url).decorate
190
- r = {link: post_tag.the_url(as_path: true), name: post_tag.the_title, type_menu: type_menu, current: @cama_visited_tag.present? && @cama_visited_tag.id == post_tag.id}
193
+ result = {link: post_tag.the_url(as_path: true), name: post_tag.the_title, url_edit: post_tag.the_edit_url}
194
+ result[:current] = @cama_visited_tag.present? && @cama_visited_tag.id == post_tag.id unless is_from_backend
191
195
  when 'post_type'
192
196
  post_type = CamaleonCms::PostType.find(nav_menu_item.url).decorate
193
- r = {link: post_type.the_url(as_path: true), name: post_type.the_title, type_menu: type_menu, current: @cama_visited_post_type.present? && @cama_visited_post_type.id == post_type.id}
197
+ result = {link: post_type.the_url(as_path: true), name: post_type.the_title, url_edit: post_type.the_edit_url}
198
+ result[:current] = @cama_visited_post_type.present? && @cama_visited_post_type.id == post_type.id unless is_from_backend
194
199
  when 'external'
195
- r = {link: nav_menu_item.url.to_s.translate, name: nav_menu_item.name.to_s.translate, type_menu: type_menu, current: false}
196
- r[:link] = cama_root_path if r[:link] == "root_url"
197
- r[:link] = site_current_path if site_current_path == "#{current_site.the_path}#{r[:link]}"
198
- r[:current] = r[:link] == site_current_url || r[:link] == site_current_path
199
-
200
+ result = {link: nav_menu_item.url.to_s.translate, name: nav_menu_item.name.to_s.translate, current: false}
200
201
  # permit to customize or mark as current menu
201
202
  # _args: (HASH) {menu_item: Model Menu Item, parsed_menu: Parsed Menu }
202
- # Sample parsed_menu: {link: "url of the link", name: "Text of the menu", type_menu: 'external', current: Boolean (true => is current menu, false => not current menu item)}
203
- _args = {menu_item: nav_menu_item, parsed_menu: r}; hooks_run("on_external_menu", _args)
204
- r = _args[:parsed_menu]
203
+ # Sample parsed_menu: {link: "url of the link", name: "Text of the menu", current: Boolean (true => is current menu, false => not current menu item)}
204
+ unless is_from_backend
205
+ result[:link] = cama_root_path if result[:link] == "root_url"
206
+ result[:link] = site_current_path if site_current_path == "#{current_site.the_path}#{result[:link]}"
207
+ result[:current] = result[:link] == site_current_url || result[:link] == site_current_path
208
+ _args = {menu_item: nav_menu_item, parsed_menu: result}; hooks_run("on_external_menu", _args)
209
+ result = _args[:parsed_menu]
210
+ end
211
+ else
212
+ # permit to build custom menu items registered as Custom Menu by hook "nav_menu_custom"
213
+ # sample: def my_parse_custom_menu_item_listener(args);
214
+ # if args[:menu_item].kind == 'MyModelClass'
215
+ # my_model = MyModelClass.find(args[:menu_item].url)
216
+ # res = {name: my_model.name, url_edit: my_model_edit_url(id: my_model.id), link: my_model_public_url(id: my_model.id)}
217
+ # res[:current] = site_current_path == my_model_public_url(id: my_model.id) unless args[:is_from_backend]
218
+ # args[:parsed_menu] = res
219
+ # end
220
+ # end
221
+ hook_args={menu_item: nav_menu_item, parsed_menu: false, is_from_backend: is_from_backend}; hooks_run('parse_custom_menu_item', hook_args)
222
+ result = hook_args[:parsed_menu]
205
223
  end
206
224
  rescue => e
207
- Rails.logger.error "Camaleon CMS - Menu Item Not Found => Skipped menu for: #{e.message} (#{nav_menu_item})"
225
+ Rails.logger.error "Camaleon CMS - Menu Item Not Found => Skipped menu for: #{e.message} (#{nav_menu_item.inspect})".cama_log_style(:red)
208
226
  end
209
227
 
210
- if r != false
211
- # permit to mark as a current menu custom paths
212
- # sample: @cama_current_menu_path = '/my_section'
213
- # sample2: @cama_current_menu_path = ['/my_section', '/mi_seccion'] # multi language support
214
- r[:current] = true if @cama_current_menu_path.present? && !r[:current] && (@cama_current_menu_path.is_a?(String) ? @cama_current_menu_path == r[:link] : @cama_current_menu_path.include?(r[:link]))
228
+ # permit to customize data, like: current, title, ... of parsed menu item or skip menu item by assigning false into :parsed_menu
229
+ unless is_from_backend
230
+ _args = {menu_item: nav_menu_item, parsed_menu: result}; hooks_run("on_render_front_menu_item", _args)
231
+ _args[:parsed_menu]
232
+ else
233
+ result
215
234
  end
216
-
217
- # permit to customize data of parsed menu item or skip menu item by assigning false into :parsed_menu
218
- _args = {menu_item: nav_menu_item, parsed_menu: r}; hooks_run("on_render_front_menu_item", _args)
219
- _args[:parsed_menu]
220
235
  end
221
236
  end
@@ -38,7 +38,7 @@ module CamaleonCms::HooksHelper
38
38
  else
39
39
  send(hook, params)
40
40
  end
41
- Rails.logger.debug "Camaleon CMS - Hook \"#{hook_key}\" executed from dependency #{plugin['key'] rescue ''}"
41
+ Rails.logger.debug "Camaleon CMS - Hook \"#{hook_key}\" executed from dependency #{plugin['key'] rescue ''}".cama_log_style(:light_blue)
42
42
  rescue
43
43
  plugin_load_helpers(plugin)
44
44
  if params.nil?
@@ -13,7 +13,7 @@ module CamaleonCms::SiteHelper
13
13
  end
14
14
  r = {site: site, request: request};
15
15
  cama_current_site_helper(r) rescue nil
16
- Rails.logger.error 'Camaleon CMS - Please define your current site: $current_site = CamaleonCms::Site.first.decorate or map your domains: http://camaleon.tuzitio.com/documentation/category/139779-examples/how.html' if !r[:site].present?
16
+ Rails.logger.error 'Camaleon CMS - Please define your current site: $current_site = CamaleonCms::Site.first.decorate or map your domains: http://camaleon.tuzitio.com/documentation/category/139779-examples/how.html'.cama_log_style(:red) if !r[:site].present?
17
17
  @current_site = r[:site]
18
18
  end
19
19
 
@@ -58,11 +58,11 @@ class CamaleonCms::HtmlMailer < ActionMailer::Base
58
58
  lookup_context.prefixes.prepend("themes/#{theme.slug}") if theme.settings["gem_mode"]
59
59
  lookup_context.prefixes.prepend("themes/#{theme.slug}/views") unless theme.settings["gem_mode"]
60
60
  lookup_context.use_camaleon_partial_prefixes = true
61
- (data[:files] || data[:attachments] || []).each{ |attach|
61
+ ((data[:files] || []) + (data[:attachments] || [])).each{ |attach|
62
62
  if File.exist?(attach) && !File.directory?(attach)
63
63
  attachments["#{File.basename(attach)}"] = File.open(attach, 'rb') { |f| f.read }
64
64
  else
65
- Rails.logger.error "Camaleon CMS - File attached in the email doesn't exist: #{attach}"
65
+ Rails.logger.error "Camaleon CMS - File attached in the email doesn't exist: #{attach}".cama_log_style(:red)
66
66
  end
67
67
  }
68
68
 
@@ -43,6 +43,7 @@ class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
43
43
 
44
44
  # overwrite skip uniq slug validation
45
45
  def skip_slug_validation?; true end
46
+ def before_validating; end
46
47
 
47
48
  private
48
49
  def update_count
@@ -40,7 +40,7 @@ class CamaleonCms::Post < CamaleonCms::PostDefault
40
40
  has_many :drafts, ->{where(status: 'draft')}, class_name: "CamaleonCms::Post", foreign_key: :post_parent, dependent: :destroy
41
41
  has_many :children, class_name: "CamaleonCms::Post", foreign_key: :post_parent, dependent: :destroy, primary_key: :id
42
42
 
43
- belongs_to :owner, class_name: "CamaleonCms::User", foreign_key: :user_id
43
+ belongs_to :owner, class_name: PluginRoutes.static_system_info['user_model'].presence || 'CamaleonCms::User', foreign_key: :user_id
44
44
  belongs_to :parent, class_name: "CamaleonCms::Post", foreign_key: :post_parent
45
45
  belongs_to :post_type, class_name: "CamaleonCms::PostType", foreign_key: :taxonomy_id, inverse_of: :posts
46
46
 
@@ -11,7 +11,7 @@ class CamaleonCms::PostComment < ActiveRecord::Base
11
11
  has_many :children, class_name: "CamaleonCms::PostComment", foreign_key: :comment_parent, dependent: :destroy
12
12
  belongs_to :post, class_name: "CamaleonCms::Post", foreign_key: :post_id
13
13
  belongs_to :parent, class_name: "CamaleonCms::PostComment", foreign_key: :comment_parent
14
- belongs_to :user, class_name: "CamaleonCms::User", foreign_key: :user_id
14
+ belongs_to :user, class_name: PluginRoutes.static_system_info['user_model'].presence || 'CamaleonCms::User', foreign_key: :user_id
15
15
 
16
16
  default_scope {order("#{CamaleonCms::PostComment.table_name}.created_at DESC")}
17
17
 
@@ -3,5 +3,5 @@ class CamaleonCms::PostTag < CamaleonCms::TermTaxonomy
3
3
  has_many :metas, ->{ where(object_class: 'PostTag')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
4
4
  has_many :posts, foreign_key: :objectid, through: :term_relationships, :source => :objects
5
5
  belongs_to :post_type, class_name: "CamaleonCms::PostType", foreign_key: :parent_id, inverse_of: :post_tags
6
- belongs_to :owner, class_name: "CamaleonCms::User", foreign_key: :user_id
6
+ belongs_to :owner, class_name: PluginRoutes.static_system_info['user_model'].presence || 'CamaleonCms::User', foreign_key: :user_id
7
7
  end
@@ -10,7 +10,7 @@ class CamaleonCms::PostType < CamaleonCms::TermTaxonomy
10
10
  has_many :posts_draft, class_name: "CamaleonCms::Post", foreign_key: :taxonomy_id, dependent: :destroy, source: :drafts, inverse_of: :post_type
11
11
  has_many :field_group_taxonomy, -> {where("object_class LIKE ?","PostType_%")}, :class_name => "CamaleonCms::CustomField", foreign_key: :objectid, dependent: :destroy
12
12
 
13
- belongs_to :owner, class_name: "CamaleonCms::User", foreign_key: :user_id
13
+ belongs_to :owner, class_name: PluginRoutes.static_system_info['user_model'].presence || 'CamaleonCms::User', foreign_key: :user_id
14
14
  belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
15
15
 
16
16
  scope :visible_menu, -> {where(term_group: nil)}
@@ -25,7 +25,7 @@ class CamaleonCms::TermTaxonomy < ActiveRecord::Base
25
25
  has_many :term_relationships, :class_name => "CamaleonCms::TermRelationship", :foreign_key => :term_taxonomy_id, dependent: :destroy
26
26
  has_many :posts, foreign_key: :objectid, through: :term_relationships, :source => :objects
27
27
  belongs_to :parent, class_name: "CamaleonCms::TermTaxonomy", foreign_key: :parent_id
28
- belongs_to :owner, class_name: "CamaleonCms::User", foreign_key: :user_id
28
+ belongs_to :owner, class_name: PluginRoutes.static_system_info['user_model'].presence || 'CamaleonCms::User', foreign_key: :user_id
29
29
 
30
30
  # return all children taxonomy
31
31
  # sample: sub categories of a category
@@ -2,12 +2,17 @@ unless PluginRoutes.static_system_info['user_model'].present?
2
2
  class CamaleonCms::User < ActiveRecord::Base
3
3
  include CamaleonCms::UserMethods
4
4
  self.table_name = PluginRoutes.static_system_info["cama_users_db_table"] || "#{PluginRoutes.static_system_info["db_prefix"]}users"
5
- # attr_accessible :username, :role, :email, :parent_id, :last_login_at, :site_id, :password, :password_confirmation, :first_name, :last_name #, :profile_attributes
6
- # attr_accessible :is_valid_email
7
-
8
5
  default_scope {order(role: :asc)}
9
6
  validates :username, :presence => true
10
7
  validates :email, :presence => true, :format => { :with => /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i } #, :unless => Proc.new { |a| a.auth_social.present? }
11
- has_secure_password #validations: :auth_social.nil?
8
+ has_secure_password
9
+
10
+ def self.by_email(email)
11
+ where(['lower(email) = ?', email.to_s.downcase])
12
+ end
13
+
14
+ def self.by_username(username)
15
+ where(['lower(username) = ?', username.to_s.downcase])
16
+ end
12
17
  end
13
18
  end
@@ -9,7 +9,7 @@ class CamaleonCms::Widget::Main < CamaleonCms::TermTaxonomy
9
9
  # renderer: string (path to the template for render this widget)
10
10
 
11
11
  has_many :metas, ->{ where(object_class: 'Widget::Main')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
12
- belongs_to :owner, class_name: "CamaleonCms::User", foreign_key: :user_id
12
+ belongs_to :owner, class_name: PluginRoutes.static_system_info['user_model'].presence || 'CamaleonCms::User', foreign_key: :user_id
13
13
  belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
14
14
 
15
15
  has_many :assigned, class_name: "CamaleonCms::Widget::Assigned", foreign_key: :visibility, dependent: :destroy
@@ -1,31 +1,17 @@
1
- class CamaleonCms::UniqValidatorUser < ActiveModel::Validator
2
- def validate(record)
3
- users = CamaleonCms::User.all
4
- users = CamaleonCms::User.where(site_id: record.site_id) unless PluginRoutes.system_info["users_share_sites"]
5
- if record.persisted?
6
- users = users.where.not(id: record.id)
7
- end
8
- if users.by_username(record.username).size > 0
9
- record.errors[:base] << "#{I18n.t('camaleon_cms.admin.users.message.requires_different_username')}"
10
- end
11
- if users.by_email(record.email).size > 0
12
- record.errors[:base] << "#{I18n.t('camaleon_cms.admin.users.message.requires_different_email')}"
13
- end
14
- end
15
- end
16
-
17
1
  module CamaleonCms::UserMethods extend ActiveSupport::Concern
18
2
  included do
19
3
  include CamaleonCms::Metas
20
4
  include CamaleonCms::CustomFieldsRead
21
5
 
22
- validates_with CamaleonCms::UniqValidatorUser
6
+ validates_uniqueness_of :username, scope: [:site_id], case_sensitive: false, message: I18n.t('camaleon_cms.admin.users.message.requires_different_username', default: 'Requires different username')
7
+ validates_uniqueness_of :email, scope: [:site_id], case_sensitive: false, message: I18n.t('camaleon_cms.admin.users.message.requires_different_email', default: 'Requires different email')
23
8
 
24
- before_create { generate_token(:auth_token) }
9
+ # callbacks
25
10
  before_validation :cama_before_validation
26
11
  before_destroy :reassign_posts
27
- # relations
12
+ before_create { generate_token(:auth_token) }
28
13
 
14
+ # relations
29
15
  has_many :metas, ->{ where(object_class: 'User')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
30
16
  has_many :all_posts, class_name: "CamaleonCms::Post"
31
17
 
@@ -37,15 +23,9 @@ module CamaleonCms::UserMethods extend ActiveSupport::Concern
37
23
  #vars
38
24
  STATUS = {0 => 'Active', 1=>'Not Active'}
39
25
  ROLE = { 'admin'=>'Administrator', 'client' => 'Client'}
40
- end
41
-
42
- class_methods do
43
- def by_email(email)
44
- where(['lower(email) = ?', email.to_s.downcase])
45
- end
46
-
47
- def by_username(username)
48
- where(['lower(username) = ?', username.to_s.downcase])
26
+
27
+ def self.decorator_class
28
+ 'CamaleonCms::UserDecorator'.constantize
49
29
  end
50
30
  end
51
31
 
@@ -110,17 +90,13 @@ module CamaleonCms::UserMethods extend ActiveSupport::Concern
110
90
  self.confirm_email_sent_at = Time.zone.now
111
91
  save!
112
92
  end
113
-
114
- def decorator_class
115
- 'CamaleonCms::UserDecorator'.constantize
116
- end
93
+ # end auth
117
94
 
118
95
  private
119
96
  def cama_before_validation
120
97
  self.role = PluginRoutes.system_info["default_user_role"] if self.role.blank?
121
- if self.email
122
- self.email = self.email.downcase
123
- end
98
+ self.email = self.email.downcase if self.email.present?
99
+ self.username = self.username.downcase if self.username.present?
124
100
  end
125
101
 
126
102
  # deprecated
@@ -18,12 +18,12 @@ r = {custom_menus: {}, menu: @nav_menu}; hooks_run("nav_menu_custom", r) %>
18
18
  </div>
19
19
  <div class="panel-body">
20
20
  <div class="tab-pane active class_type">
21
- <ul class="">
21
+ <ul class="list-unstyled">
22
22
  <% r[:custom_menus].each do |k, item| %>
23
23
  <% if item[:link].present? %>
24
24
  <li>
25
- <label class="class_slug">
26
- <input type="checkbox" value="<%= item[:link] %>" data-label="<%= item[:title] %>"> <%= item[:title] %>
25
+ <label class="class_slug" data-post_link_edit="<%= item[:edit_link] %>">
26
+ <input type="checkbox" value="<%= item[:id] || item[:link] %>" data-kind="<%= item[:kind] %>" data-label="<%= item[:title] %>"> <%= item[:title] %>
27
27
  </label>
28
28
  </li>
29
29
  <% else %>
@@ -1,14 +1,15 @@
1
1
  <% custom_fields = nav_menu.get_field_groups.any? %>
2
2
  <ol class="dd-list">
3
3
  <% items.each do |item|
4
- item_data = parse_menu_item(item)
4
+ item_data = cama_parse_menu_item(item, true)
5
+ item_data[:url_edit] = url_for(action: :edit_menu_item, nav_menu_id: nav_menu.id, id: item.id) if item.kind == 'external'
5
6
  next unless item_data.present?
6
7
  %>
7
8
  <li class="dd-item" data-id="<%= item.id %>">
8
9
  <div class="dd-handle dd3-handle"></div>
9
10
  <div class="dd3-content"><span><%= item_data[:name] %></span>
10
11
  <span class="label label-default"><%= item.kind %></span>
11
- <%= link_to('<i class="fa fa-edit"></i>'.html_safe, item_data[:url_edit] || url_for(action: :edit_menu_item, nav_menu_id: nav_menu.id, id: item.id), target: '_blank', title: t('.edit_menu_item', default: 'Edit Menu Item'), class: "item_#{item.kind}") %>
12
+ <%= link_to('<i class="fa fa-edit"></i>'.html_safe, item_data[:url_edit], target: '_blank', title: t('.edit_menu_item', default: 'Edit Menu Item'), class: "item_#{item.kind}") if item_data[:url_edit].present? %>
12
13
  <%= link_to('<i class="fa fa-cog"></i>'.html_safe, {action: :custom_settings, nav_menu_id: nav_menu.id, id: item.id, cama_skip_breadcrumb: true}, class: 'custom_settings_link', title: t('.edit_custom_settings', default: 'Edit Configurations')) if custom_fields %>
13
14
  <%= link_to('<i class="fa fa-times-circle"></i>'.html_safe, url_for(action: :delete_menu_item, nav_menu_id: nav_menu.id, id: item.id), class: 'delete_menu_item') %>
14
15
  </div>
@@ -13,7 +13,7 @@
13
13
  </tr>
14
14
  </thead>
15
15
  <tbody>
16
- <% plugins.each do |plugin| status = enabled_plugins.include?(plugin); r = {links: ["Version: #{plugin["version"]}"]}; %>
16
+ <% plugins.each do |plugin| status = enabled_plugins.include?(plugin); r = {links: ["Version: #{plugin["version"]}"], plugin: plugin}; %>
17
17
  <tr>
18
18
  <td>
19
19
  <b><%= plugin["title"] %></b>
@@ -33,7 +33,7 @@
33
33
  <%= begin
34
34
  render(field.get_option('render') || (cama_custom_field_elements[field.get_option('field_key').to_sym][:render] rescue nil) || "camaleon_cms/admin/settings/custom_fields/fields/#{field.options[:field_key]}", field: field, values: nil, is_disabled: is_disabled, default_use: default_use, field_name: field_name)
35
35
  rescue => e
36
- Rails.logger.error "Camaleon CMS - Render Custom Fields Error: Custom field template was not found => #{e.message}"
36
+ Rails.logger.error "Camaleon CMS - Render Custom Fields Error: Custom field template was not found => #{e.message}".cama_log_style(:red)
37
37
  end %>
38
38
  </div>
39
39
  </div>
@@ -8,7 +8,7 @@
8
8
  type="url"
9
9
  name="<%= field_name %>[<%= field.slug %>][values][]"
10
10
  class="data-error-place-parent form-control input-value <%= "required" if field.options[:required].to_s.to_bool %>" />
11
- <span class="input-group-addon btn_upload" onclick="load_upload_image_field($(this).prev());">
11
+ <span class="input-group-addon btn_upload" onclick="load_upload_image_field($(this).prev());" style="cursor: pointer;">
12
12
  <i class="fa fa-upload"></i>
13
13
  <%= t('camaleon_cms.admin.button.upload_image')%> <%= "(#{field.get_option('dimension')})" if field.get_option('dimension').present? %>
14
14
  </span>
@@ -15,7 +15,7 @@
15
15
  <h3><%= ct('comment_new', default: 'New Comment')%></h3>
16
16
  <% if signin? %>
17
17
  <%= form_for post, url:{action: :save_comment, post_id: post.id}, html: {method: "post", class: "form-comment"} do |f|%>
18
- <%= render partial: "camaleon_cms/flash_messages" %>
18
+ <%= render partial: "camaleon_cms/flash_messages", locals:{ flash: (flash[:comment_submit] || {}).with_indifferent_access } %>
19
19
  <div class="form-group">
20
20
  <textarea id="textarea_comments" name="post_comment[content]" class="form-control counted" placeholder="<%= ct('comment', default: 'Here your comment')%>"></textarea>
21
21
  </div>
@@ -13,24 +13,17 @@ Rails.application.routes.draw do
13
13
  root 'camaleon_cms/frontend#index', as: 'root'
14
14
 
15
15
  controller "camaleon_cms/frontend" do
16
- PluginRoutes.all_locales.split("|").each do |_l|
17
- get "#{I18n.t("routes.group", default: "group", locale: _l)}/:post_type_id-:title" => :post_type, as: "post_type_#{_l}", constraints: {post_type_id: /[0-9]+/}
18
- get "#{I18n.t("routes.group", default: "group", locale: _l)}/:post_type_id-:title/:slug" => :post, as: "post_of_post_type_#{_l}", constraints: {post_type_id: /[0-9]+/}
16
+ get ":label/:post_type_id-:title" => :post_type, as: "post_type", constraints: {post_type_id: /[0-9]+/, label: /(#{PluginRoutes.all_translations('routes.group', default: 'group').join('|')})/}
17
+ get ":label/:post_type_id-:title/:slug" => :post, as: "post_of_post_type", constraints: {post_type_id: /[0-9]+/, label: /(#{PluginRoutes.all_translations('routes.group', default: 'group').join('|')})/}
18
+ get ":label/:category_id-:title" => :category, as: "category", constraints: {category_id: /[0-9]+/, label: /(#{PluginRoutes.all_translations('routes.category', default: 'category').join('|')})/}
19
+ get ":label_cat/:category_id-:title/:slug" => :post, as: "post_of_category", constraints: {category_id: /[0-9]+/, label_cat: /(#{PluginRoutes.all_translations('routes.category', default: 'category').join('|')})/}
20
+ get ":post_type_title/:label_cat/:category_id-:title/:slug" => :post, as: "post_of_category_post_type", constraints:{ post_type_title: /(?!(#{PluginRoutes.all_locales}))[\w\.\-]+/, category_id: /[0-9]+/, label_cat: /(#{PluginRoutes.all_translations('routes.category', default: 'category').join('|')})/ }
21
+ get ":label/:post_tag_id-:title" => :post_tag, as: "post_tag", constraints: {post_tag_id: /[0-9]+/, label: /(#{PluginRoutes.all_translations('routes.tag', default: 'tag').join('|')})/}
22
+ get ":label/:post_tag_id-:title/:slug" => :post, as: "post_of_tag", constraints: {post_tag_id: /[0-9]+/, label: /(#{PluginRoutes.all_translations('routes.tag', default: 'tag').join('|')})/}
23
+ get ":label/:post_tag_slug" => :post_tag, as: "post_tag_simple", constraints: {post_tag_slug: /[a-zA-Z0-9_=\s\-\/]+/, label: /(#{PluginRoutes.all_translations('routes.tag', default: 'tag').join('|')})/}
24
+ get ":label/:user_id-:user_name" => :profile, as: :profile, defaults:{label: 'profile'}, constraints: {user_id: /[0-9]+/, label: /(#{PluginRoutes.all_translations('routes.profile', default: 'profile').join('|')})/}
25
+ get ":label" => :search, as: :search, defaults:{label: 'search'}, constraints: {label: /(#{PluginRoutes.all_translations('routes.search', default: 'search').join('|')})/}
19
26
 
20
- get "#{I18n.t("routes.category", default: "category", locale: _l)}/:category_id-:title" => :category, as: "category_#{_l}", constraints: {category_id: /[0-9]+/}
21
- get "#{I18n.t("routes.category", default: "category", locale: _l)}/:category_id-:title/:slug" => :post, as: "post_of_category_#{_l}", constraints: {category_id: /[0-9]+/}
22
- get ":post_type_title/#{I18n.t("routes.category", default: "category", locale: _l)}/:category_id-:title/:slug" => :post, as: "post_of_category_post_type_#{_l}", constraints:{ post_type_title: /(?!(#{PluginRoutes.all_locales}))[\w\.\-]+/, category_id: /[0-9]+/ }
23
-
24
- get "#{I18n.t("routes.tag", default: "tag", locale: _l)}/:post_tag_id-:title" => :post_tag, as: "post_tag_#{_l}", constraints: {post_tag_id: /[0-9]+/}
25
- get "#{I18n.t("routes.tag", default: "tag", locale: _l)}/:post_tag_id-:title/:slug" => :post, as: "post_of_tag_#{_l}", constraints: {post_tag_id: /[0-9]+/}
26
- get "#{I18n.t("routes.tag", default: "tag", locale: _l)}/:post_tag_slug" => :post_tag, as: "post_tag_simple_#{_l}", constraints: {post_tag_slug: /[a-zA-Z0-9_=\s\-\/]+/}
27
-
28
- get "#{I18n.t("routes.profile", default: "profile", locale: _l)}/:user_id-:user_name" => :profile, constraints: {user_id: /[0-9]+/}, as: "profile_#{_l}"
29
- get "#{I18n.t("routes.search", default: "search", locale: _l)}" => :search, as: "search_#{_l}"
30
- end
31
-
32
- get "profile/:user_id-:user_name" => :profile, as: :profile, constraints: {user_id: /[0-9]+/}
33
- get 'search' => :search, as: :search
34
27
  get ':post_type_title/:slug' => :post, as: :post_of_posttype, constraints:{ post_type_title: /(?!(#{PluginRoutes.all_locales}))[\w\.\-]+/ }
35
28
 
36
29
  post 'save_comment/:post_id' => :save_comment, as: :save_comment
@@ -1,3 +1,3 @@
1
1
  module CamaleonCms
2
- VERSION = '2.4.2'
2
+ VERSION = '2.4.3'
3
3
  end
@@ -136,4 +136,11 @@ class String
136
136
  rescue
137
137
  false
138
138
  end
139
+
140
+ # Colorized Ruby output
141
+ # color: (:red, :green, :blue, :pink, :light_blue, :yellow)
142
+ def cama_log_style(color = :red)
143
+ colors = {red: 31, green: 32, blue: 34, pink: 35, light_blue: 36, yellow: 33}
144
+ "\e[#{colors[color]}m#{self}\e[0m"
145
+ end
139
146
  end
@@ -74,7 +74,11 @@ module CamaleonCms
74
74
  scope :admin, as: 'admin', path: PluginRoutes.system_info['admin_path_name'] do
75
75
  namespace 'plugins' do
76
76
  namespace '#{get_plugin_name}' do
77
- get 'index' => 'admin#index'
77
+ controller :admin do
78
+ get :index
79
+ get :settings
80
+ post :save_settings
81
+ end
78
82
  end
79
83
  end
80
84
  end
@@ -1,8 +1,18 @@
1
1
  class Plugins::PluginClass::AdminController < CamaleonCms::Apps::PluginsAdminController
2
2
  include Plugins::PluginClass::MainHelper
3
3
  def index
4
- # actions for admin panel
5
4
  end
6
5
 
7
- # add custom methods below
6
+ # show settings form
7
+ def settings
8
+ end
9
+
10
+ # save values from settings form
11
+ def save_settings
12
+ @plugin.set_options(params[:options]) if params[:options].present? # save option values
13
+ @plugin.set_metas(params[:metas]) if params[:metas].present? # save meta values
14
+ @plugin.set_field_values(params[:field_options]) if params[:field_options].present? # save custom field values
15
+ redirect_to url_for(action: :settings), notice: 'Settings Saved Successfully'
16
+ end
17
+ # add custom methods below ....
8
18
  end
@@ -19,4 +19,11 @@ module Plugins::PluginClass::MainHelper
19
19
  # plugin: plugin model
20
20
  def pluginKey_on_upgrade(plugin)
21
21
  end
22
+
23
+ # hook listener to add settings link below the title of current plugin (if it is installed)
24
+ # args: {plugin (Hash), links (Array)}
25
+ # permit to add unlimmited of links...
26
+ def pluginKey_on_plugin_options(args)
27
+ args[:links] << link_to('Settings', admin_plugins_pluginKey_settings_path)
28
+ end
22
29
  end
@@ -0,0 +1,21 @@
1
+ <div class="panel panel-default">
2
+ <div class="panel-heading">
3
+ <h4>My Plugin Settings</h4>
4
+ </div>
5
+ <div class="panel-body">
6
+ <%= form_tag(url_for(action: :save_settings), class: 'validate') do %>
7
+ <div class="form-group">
8
+ <label>My Option Setting</label>
9
+ <%= text_field_tag 'options[my_setting]', @plugin.get_option('my_setting'), class: 'form-control required' %>
10
+ </div>
11
+ <div class="form-group">
12
+ <label>My Meta Setting</label>
13
+ <%= text_field_tag 'metas[my_setting]', @plugin.get_meta('my_setting'), class: 'form-control required' %>
14
+ </div>
15
+ <%= render partial: "camaleon_cms/admin/settings/custom_fields/render", locals: {record: @plugin, field_groups: @plugin.get_field_groups} %>
16
+ <div class="form-group text-right">
17
+ <%= submit_tag 'Save Settings', class: 'btn btn-primary' %>
18
+ </div>
19
+ <% end %>
20
+ </div>
21
+ </div>
@@ -6,12 +6,9 @@
6
6
  "Plugins::PluginClass::MainHelper"
7
7
  ],
8
8
  "hooks": {
9
- "on_active": [
10
- "pluginKey_on_active"
11
- ],
12
- "on_inactive": [
13
- "pluginKey_on_inactive"
14
- ]
9
+ "on_active": ["pluginKey_on_active"],
10
+ "on_inactive": ["pluginKey_on_inactive"],
11
+ "plugin_options": ["pluginKey_on_plugin_options"]
15
12
  //here you can add all your hooks (read documentation)
16
13
  }
17
14
  }
@@ -246,7 +246,7 @@ class PluginRoutes
246
246
  # return all translations for all languages, sample: ['Sample', 'Ejemplo', '....']
247
247
  def self.all_translations(key, *args)
248
248
  args = args.extract_options!
249
- all_locales.split('|').map{|_l| I18n.t(args.merge({locale: _l})) }
249
+ all_locales.split('|').map{|_l| I18n.t(key, args.merge({locale: _l})) }.uniq
250
250
  end
251
251
 
252
252
  # return all locales for translated routes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camaleon_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 2.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Owen Peredo Diaz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-21 00:00:00.000000000 Z
11
+ date: 2017-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcrypt
@@ -533,7 +533,6 @@ files:
533
533
  - app/assets/javascripts/camaleon_cms/admin/admin-manifest.js
534
534
  - app/assets/javascripts/camaleon_cms/admin/bootstrap-colorpicker.js
535
535
  - app/assets/javascripts/camaleon_cms/admin/custom_fields_form.js
536
- - app/assets/javascripts/camaleon_cms/admin/form/cropper.min.js
537
536
  - app/assets/javascripts/camaleon_cms/admin/introjs/_intro.min.js
538
537
  - app/assets/javascripts/camaleon_cms/admin/jquery-sieve.js
539
538
  - app/assets/javascripts/camaleon_cms/admin/jquery.nestable.js
@@ -575,6 +574,7 @@ files:
575
574
  - app/assets/javascripts/camaleon_cms/admin/tinymce/langs/ru.js
576
575
  - app/assets/javascripts/camaleon_cms/admin/tinymce/langs/zh-CN.js
577
576
  - app/assets/javascripts/camaleon_cms/admin/tinymce/plugins/filemanager/plugin.min.js
577
+ - app/assets/javascripts/camaleon_cms/admin/uploader/_cropper.min.js
578
578
  - app/assets/javascripts/camaleon_cms/admin/uploader/_jquery.form.js
579
579
  - app/assets/javascripts/camaleon_cms/admin/uploader/_jquery.uploadfile.min.js
580
580
  - app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee
@@ -588,7 +588,6 @@ files:
588
588
  - app/assets/stylesheets/camaleon_cms/admin/admin-basic-manifest.css
589
589
  - app/assets/stylesheets/camaleon_cms/admin/admin-manifest.css
590
590
  - app/assets/stylesheets/camaleon_cms/admin/colorpicker.css.scss
591
- - app/assets/stylesheets/camaleon_cms/admin/cropper/cropper.min.css
592
591
  - app/assets/stylesheets/camaleon_cms/admin/img/bg.png
593
592
  - app/assets/stylesheets/camaleon_cms/admin/img/colorpicker/alpha.png
594
593
  - app/assets/stylesheets/camaleon_cms/admin/img/colorpicker/hue.png
@@ -631,7 +630,9 @@ files:
631
630
  - app/assets/stylesheets/camaleon_cms/admin/lte/skins/skin-yellow.css
632
631
  - app/assets/stylesheets/camaleon_cms/admin/nestable/jquery.nestable.css
633
632
  - app/assets/stylesheets/camaleon_cms/admin/tageditor/_jquery.tag-editor.css.scss
633
+ - app/assets/stylesheets/camaleon_cms/admin/uploader/_cropper.min.css
634
634
  - app/assets/stylesheets/camaleon_cms/admin/uploader/_uploadfile.css.scss
635
+ - app/assets/stylesheets/camaleon_cms/admin/uploader/uploader_manifest.css
635
636
  - app/assets/stylesheets/camaleon_cms/admin/widgets.css.scss
636
637
  - app/assets/stylesheets/camaleon_cms/bootstrap.min.css.scss
637
638
  - app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb
@@ -989,6 +990,7 @@ files:
989
990
  - lib/generators/camaleon_cms/gem_plugin_template/app/helpers/plugins/my_plugin/main_helper.rb
990
991
  - lib/generators/camaleon_cms/gem_plugin_template/app/models/plugins/my_plugin/my_plugin.rb
991
992
  - lib/generators/camaleon_cms/gem_plugin_template/app/views/plugins/my_plugin/admin/index.html.erb
993
+ - lib/generators/camaleon_cms/gem_plugin_template/app/views/plugins/my_plugin/admin/settings.html.erb
992
994
  - lib/generators/camaleon_cms/gem_plugin_template/app/views/plugins/my_plugin/front/index.html.erb
993
995
  - lib/generators/camaleon_cms/gem_plugin_template/app/views/plugins/my_plugin/layouts/readme.txt
994
996
  - lib/generators/camaleon_cms/gem_plugin_template/config/camaleon_plugin.json
@@ -1042,6 +1044,7 @@ files:
1042
1044
  - spec/dummy/config/routes.rb
1043
1045
  - spec/dummy/config/secrets.yml
1044
1046
  - spec/dummy/db/schema.rb
1047
+ - spec/dummy/db/test.sqlite3
1045
1048
  - spec/features/categories_spec.rb
1046
1049
  - spec/features/comments_spec.rb
1047
1050
  - spec/features/contact_form_spec.rb
@@ -1131,6 +1134,7 @@ test_files:
1131
1134
  - spec/dummy/config/secrets.yml
1132
1135
  - spec/dummy/config.ru
1133
1136
  - spec/dummy/db/schema.rb
1137
+ - spec/dummy/db/test.sqlite3
1134
1138
  - spec/dummy/Rakefile
1135
1139
  - spec/dummy/README.rdoc
1136
1140
  - spec/features/categories_spec.rb