camaleon_cms 2.4.2 → 2.4.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of camaleon_cms might be problematic. Click here for more details.

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