camaleon_cms 2.9.0 → 2.9.2

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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -5
  3. data/app/apps/plugins/front_cache/admin_controller.rb +1 -0
  4. data/app/apps/plugins/front_cache/front_cache_helper.rb +23 -14
  5. data/app/apps/plugins/visibility_post/visibility_post_helper.rb +1 -1
  6. data/app/apps/themes/default/views/category.html.erb +1 -1
  7. data/app/apps/themes/default/views/post_tag.html.erb +1 -1
  8. data/app/apps/themes/default/views/post_type.html.erb +1 -1
  9. data/app/apps/themes/default/views/search.html.erb +1 -1
  10. data/app/apps/themes/new/views/category.html.erb +1 -1
  11. data/app/apps/themes/new/views/post_tag.html.erb +1 -1
  12. data/app/apps/themes/new/views/post_type.html.erb +1 -1
  13. data/app/apps/themes/new/views/search.html.erb +1 -1
  14. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +22 -5
  15. data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +4 -2
  16. data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +3 -3
  17. data/app/controllers/camaleon_cms/admin/appearances/widgets/sidebar_controller.rb +2 -2
  18. data/app/controllers/camaleon_cms/admin/categories_controller.rb +9 -5
  19. data/app/controllers/camaleon_cms/admin/media_controller.rb +18 -5
  20. data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +7 -4
  21. data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +1 -1
  22. data/app/controllers/camaleon_cms/admin/posts_controller.rb +7 -4
  23. data/app/controllers/camaleon_cms/admin/sessions_controller.rb +2 -2
  24. data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +33 -11
  25. data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +13 -4
  26. data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +7 -4
  27. data/app/controllers/camaleon_cms/admin/settings_controller.rb +7 -4
  28. data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +2 -2
  29. data/app/controllers/camaleon_cms/admin/users_controller.rb +23 -14
  30. data/app/controllers/camaleon_cms/admin_controller.rb +8 -0
  31. data/app/controllers/camaleon_cms/apps/plugins_admin_controller.rb +5 -0
  32. data/app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb +29 -0
  33. data/app/decorators/camaleon_cms/post_decorator.rb +1 -1
  34. data/app/decorators/camaleon_cms/user_decorator.rb +1 -1
  35. data/app/helpers/camaleon_cms/admin/application_helper.rb +17 -17
  36. data/app/helpers/camaleon_cms/admin/post_type_helper.rb +25 -22
  37. data/app/helpers/camaleon_cms/comment_helper.rb +74 -40
  38. data/app/helpers/camaleon_cms/frontend/content_select_helper.rb +1 -1
  39. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +7 -7
  40. data/app/helpers/camaleon_cms/html_helper.rb +15 -1
  41. data/app/helpers/camaleon_cms/session_helper.rb +13 -1
  42. data/app/helpers/camaleon_cms/site_helper.rb +16 -3
  43. data/app/helpers/camaleon_cms/uploader_helper.rb +102 -51
  44. data/app/models/camaleon_cms/ability.rb +54 -102
  45. data/app/models/camaleon_cms/category.rb +2 -0
  46. data/app/models/camaleon_cms/custom_field.rb +14 -0
  47. data/app/models/camaleon_cms/custom_field_group.rb +38 -1
  48. data/app/models/camaleon_cms/custom_fields_relationship.rb +1 -1
  49. data/app/models/camaleon_cms/meta.rb +4 -0
  50. data/app/models/camaleon_cms/nav_menu.rb +2 -0
  51. data/app/models/camaleon_cms/nav_menu_item.rb +2 -0
  52. data/app/models/camaleon_cms/plugin.rb +2 -0
  53. data/app/models/camaleon_cms/post.rb +1 -1
  54. data/app/models/camaleon_cms/post_comment.rb +4 -0
  55. data/app/models/camaleon_cms/post_tag.rb +2 -0
  56. data/app/models/camaleon_cms/post_type.rb +3 -1
  57. data/app/models/camaleon_cms/site.rb +2 -0
  58. data/app/models/camaleon_cms/term_taxonomy.rb +1 -23
  59. data/app/models/camaleon_cms/theme.rb +2 -0
  60. data/app/models/camaleon_cms/user_role.rb +13 -0
  61. data/app/models/camaleon_cms/widget/main.rb +2 -0
  62. data/app/models/camaleon_cms/widget/sidebar.rb +2 -0
  63. data/app/models/camaleon_record.rb +40 -0
  64. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +7 -7
  65. data/app/models/concerns/camaleon_cms/metas.rb +10 -6
  66. data/app/models/concerns/camaleon_cms/normalize_attrs.rb +26 -0
  67. data/app/models/concerns/camaleon_cms/user_methods.rb +6 -2
  68. data/app/models/current_request.rb +16 -0
  69. data/app/uploaders/camaleon_cms_aws_uploader.rb +8 -1
  70. data/app/validators/camaleon_cms/post_uniq_validator.rb +21 -8
  71. data/app/views/camaleon_cms/admin/appearances/nav_menus/_left_menu_items.html.erb +2 -2
  72. data/app/views/camaleon_cms/admin/appearances/widgets/main/form.html.erb +1 -1
  73. data/app/views/camaleon_cms/admin/categories/index.html.erb +1 -1
  74. data/app/views/camaleon_cms/admin/comments/index.html.erb +2 -2
  75. data/app/views/camaleon_cms/admin/comments/list.html.erb +1 -1
  76. data/app/views/camaleon_cms/admin/post_tags/index.html.erb +1 -1
  77. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +1 -1
  78. data/app/views/camaleon_cms/admin/posts/index.html.erb +3 -3
  79. data/app/views/camaleon_cms/admin/search.html.erb +1 -1
  80. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +23 -2
  81. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb +1 -1
  82. data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +6 -5
  83. data/app/views/camaleon_cms/admin/settings/custom_fields/index.html.erb +1 -1
  84. data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -1
  85. data/app/views/camaleon_cms/admin/settings/sites/index.html.erb +1 -1
  86. data/app/views/camaleon_cms/admin/user_roles/form.html.erb +79 -5
  87. data/app/views/camaleon_cms/admin/user_roles/index.html.erb +1 -1
  88. data/app/views/camaleon_cms/admin/users/index.html.erb +1 -1
  89. data/app/views/layouts/camaleon_cms/admin/_flash_messages.html.erb +2 -2
  90. data/config/initializers/custom_initializers.rb +2 -2
  91. data/config/locales/camaleon_cms/admin/ar.yml +6 -2
  92. data/config/locales/camaleon_cms/admin/de.yml +6 -2
  93. data/config/locales/camaleon_cms/admin/en.yml +6 -2
  94. data/config/locales/camaleon_cms/admin/es.yml +6 -2
  95. data/config/locales/camaleon_cms/admin/fr.yml +6 -2
  96. data/config/locales/camaleon_cms/admin/it.yml +6 -2
  97. data/config/locales/camaleon_cms/admin/nl.yml +7 -2
  98. data/config/locales/camaleon_cms/admin/pt-BR.yml +6 -2
  99. data/config/locales/camaleon_cms/admin/pt.yml +6 -2
  100. data/config/locales/camaleon_cms/admin/ru.yml +6 -2
  101. data/config/locales/camaleon_cms/admin/uk.yml +6 -2
  102. data/config/locales/camaleon_cms/admin/zh-CH.yml +6 -2
  103. data/db/migrate/20150611161134_post_table_into_utf8.rb +14 -14
  104. data/db/migrate/20150926095310_rename_column_posts.rb +3 -3
  105. data/db/migrate/20151212095328_add_confirm_token_to_users.rb +3 -3
  106. data/db/migrate/20160504155652_add_feature_to_posts.rb +1 -1
  107. data/db/migrate/20160504155653_move_first_name_of_users.rb +2 -2
  108. data/db/migrate/20160609121449_add_group_to_custom_field_values.rb +1 -1
  109. data/db/migrate/20161215202255_drop_user_relationship_table.rb +1 -1
  110. data/db/migrate/20180124132318_create_media.rb +1 -1
  111. data/db/migrate/20180704211100_adjust_field_length.rb +1 -1
  112. data/lib/camaleon_cms/version.rb +1 -1
  113. data/lib/ext/string.rb +3 -3
  114. data/lib/plugin_routes.rb +6 -6
  115. data/lib/tasks/custom_fields_roles.rake +56 -0
  116. metadata +65 -8
@@ -4,6 +4,7 @@ module CamaleonCms
4
4
  class PostTypesController < CamaleonCms::Admin::SettingsController
5
5
  before_action :set_post_type, only: %i[show edit update destroy]
6
6
  before_action :set_data_term, only: %i[create update]
7
+
7
8
  add_breadcrumb I18n.t('camaleon_cms.admin.sidebar.content_groups'), :cama_admin_settings_post_types_path
8
9
 
9
10
  def index
@@ -20,7 +21,7 @@ module CamaleonCms
20
21
 
21
22
  def update
22
23
  if @post_type.update(@data_term)
23
- @post_type.set_field_values(params.require(:field_options).permit!) if params[:field_options].present?
24
+ @post_type.set_field_values(cama_permitted_field_options('PostType')) if params[:field_options].present?
24
25
  hooks_run('updated_post_type', { post_type: @post_type })
25
26
  flash[:notice] = t('camaleon_cms.admin.post_type.message.updated')
26
27
  redirect_to action: :index
@@ -32,7 +33,7 @@ module CamaleonCms
32
33
  def create
33
34
  @post_type = current_site.post_types.new(@data_term)
34
35
  if @post_type.save
35
- @post_type.set_field_values(params.require(:field_options).permit!) if params[:field_options].present?
36
+ @post_type.set_field_values(cama_permitted_field_options('PostType')) if params[:field_options].present?
36
37
  hooks_run('created_post_type', { post_type: @post_type })
37
38
  flash[:notice] = t('camaleon_cms.admin.post_type.message.created')
38
39
  redirect_to action: :index
@@ -49,11 +50,19 @@ module CamaleonCms
49
50
  private
50
51
 
51
52
  def set_data_term
52
- data_term = params.require(:post_type).permit!
53
- data_term[:data_options] = params.require(:meta).permit!
53
+ data_term = params.require(:post_type).permit(:name, :slug, :description, :parent_id)
54
+ data_term[:data_options] = params[:meta].present? ? post_type_meta_params : {}
54
55
  @data_term = data_term
55
56
  end
56
57
 
58
+ def post_type_meta_params
59
+ params.require(:meta).permit(:icon, :has_layout, :default_layout, :has_template, :default_template,
60
+ :has_category, :has_single_category, :has_tags, :has_content, :has_summary,
61
+ :has_comments, :has_featured, :has_seo, :has_parent_structure, :has_picture,
62
+ :posts_image_dimension, :posts_thumb_versions, :posts_thumb_size,
63
+ :is_required_picture, :contents_route_format, :default_thumb)
64
+ end
65
+
57
66
  def set_post_type
58
67
  @post_type = current_site.post_types.find_by_id(params[:id])
59
68
  rescue StandardError
@@ -23,11 +23,11 @@ module CamaleonCms
23
23
 
24
24
  def update
25
25
  tmp = @site.slug
26
- if @site.update(params.require(:site).permit!)
26
+ if @site.update(site_params)
27
27
  save_metas(@site)
28
28
  flash[:notice] = t('camaleon_cms.admin.sites.message.updated')
29
29
  if @site.id == Cama::Site.main_site.id && tmp != @site.slug
30
- redirect_to @site.the_admin_url
30
+ redirect_to(cama_admin_path)
31
31
  else
32
32
  redirect_to action: :index
33
33
  end
@@ -43,8 +43,7 @@ module CamaleonCms
43
43
  end
44
44
 
45
45
  def create
46
- site_data = params.require(:site).permit!
47
- @site = CamaleonCms::Site.new(site_data)
46
+ @site = CamaleonCms::Site.new(site_params)
48
47
  if @site.save
49
48
  save_metas(@site)
50
49
  site_after_install(@site, @site.get_theme_slug)
@@ -84,6 +83,10 @@ module CamaleonCms
84
83
  flash[:error] = t('camaleon_cms.admin.sites.message.unauthorized')
85
84
  redirect_to cama_admin_path
86
85
  end
86
+
87
+ def site_params
88
+ params.require(:site).permit(:name, :slug, :description)
89
+ end
87
90
  end
88
91
  end
89
92
  end
@@ -1,8 +1,11 @@
1
1
  module CamaleonCms
2
2
  module Admin
3
3
  class SettingsController < CamaleonCms::AdminController
4
+ include CamaleonCms::Admin::CustomFieldsConcern
5
+
4
6
  before_action :validate_role, except: %i[theme save_theme]
5
7
  before_action :validate_role_theme, only: %i[theme save_theme]
8
+
6
9
  add_breadcrumb I18n.t('camaleon_cms.admin.sidebar.settings')
7
10
 
8
11
  def index
@@ -19,10 +22,10 @@ module CamaleonCms
19
22
  def site_saved
20
23
  @site = current_site
21
24
  cache_slug = @site.slug
22
- if @site.update(params.require(:site).permit!)
25
+ if @site.update(params.require(:site).permit(:name, :slug, :description))
23
26
  @site.set_options(params[:options]) if params[:options].present?
24
27
  @site.set_metas(params[:metas]) if params[:metas].present?
25
- @site.set_field_values(params[:field_options])
28
+ @site.set_field_values(cama_permitted_field_options('Site'))
26
29
  flash[:notice] = t('camaleon_cms.admin.settings.message.site_updated')
27
30
  args = { action: :site }
28
31
  args[:host], args[:port] = @site.get_domain.to_s.split(':') if cache_slug != @site.slug
@@ -62,7 +65,7 @@ module CamaleonCms
62
65
  current_theme.set_field_values(params[:theme_fields]) if params[:theme_fields].present?
63
66
  current_theme.set_options(params[:theme_option]) if params[:theme_option].present?
64
67
  current_theme.set_metas(params[:theme_meta]) if params[:theme_meta].present?
65
- current_theme.set_field_values(params[:field_options])
68
+ current_theme.set_field_values(cama_permitted_field_options('Theme'))
66
69
  hook_run(current_theme.settings, 'on_theme_settings', current_theme) # permit to save extra/custom values by this hook
67
70
  flash[:notice] = t('camaleon_cms.admin.message.updated_success', default: 'Theme updated successfully')
68
71
  redirect_to action: :theme
@@ -74,7 +77,7 @@ module CamaleonCms
74
77
  CamaleonCms::HtmlMailer.sender(params[:email], 'Test', data).deliver_now
75
78
  head :ok
76
79
  rescue StandardError => e
77
- render inline: e.message, status: 502
80
+ render plain: e.message, status: 502
78
81
  end
79
82
 
80
83
  private
@@ -20,7 +20,7 @@ module CamaleonCms
20
20
  end
21
21
 
22
22
  def create
23
- user_role_data = params.require(:user_role).permit!
23
+ user_role_data = params.require(:user_role).permit(:name, :slug, :description)
24
24
  @user_role = current_site.user_roles.new(user_role_data)
25
25
  if @user_role.save
26
26
  @user_role.set_meta("_post_type_#{current_site.id}",
@@ -40,7 +40,7 @@ module CamaleonCms
40
40
  end
41
41
 
42
42
  def update
43
- if @user_role.update(params.require(:user_role).permit!)
43
+ if @user_role.update(params.require(:user_role).permit(:name, :slug, :description))
44
44
  if @user_role.editable?
45
45
  @user_role.set_meta("_post_type_#{current_site.id}",
46
46
  defined?(params[:rol_values][:post_type]) ? params[:rol_values][:post_type] : {})
@@ -1,8 +1,12 @@
1
1
  module CamaleonCms
2
2
  module Admin
3
3
  class UsersController < CamaleonCms::AdminController
4
+ include CamaleonCms::Admin::CustomFieldsConcern
5
+
4
6
  before_action :validate_role, except: %i[profile profile_edit]
7
+
5
8
  add_breadcrumb I18n.t('camaleon_cms.admin.sidebar.users'), :cama_admin_users_url
9
+
6
10
  before_action :set_user, only: %i[show edit update destroy impersonate]
7
11
 
8
12
  def index
@@ -31,8 +35,8 @@ module CamaleonCms
31
35
  r = { user: @user }
32
36
  hooks_run('user_update', r)
33
37
  if @user.update(user_params)
34
- @user.set_metas(params[:meta]) if params[:meta].present?
35
- @user.set_field_values(params[:field_options])
38
+ @user.set_metas(user_meta_params) if params[:meta].present?
39
+ @user.set_field_values(cama_permitted_field_options('User')) if params[:field_options].present?
36
40
  r = { user: @user, message: t('camaleon_cms.admin.users.message.updated'), params: params }
37
41
  hooks_run('user_after_edited', r)
38
42
  flash[:notice] = r[:message]
@@ -52,10 +56,15 @@ module CamaleonCms
52
56
  def updated_ajax
53
57
  @user = current_site.users.find(params[:user_id])
54
58
  update_session = current_user_is?(@user)
55
- @user.update(params.require(:password).permit!)
56
- render inline: @user.errors.full_messages.join(', ')
59
+ attrs = params.require(:password).permit(%i[password password_confirmation])
60
+ @user.update(password: attrs.require(:password), password_confirmation: attrs.require(:password_confirmation))
61
+
62
+ return render inline: @user.errors.full_messages.join(', '), status: :unprocessable_entity if @user.errors.any?
63
+
57
64
  # keep user logged in when changing their own password
58
65
  update_auth_token_in_cookie @user.auth_token if update_session && @user.saved_change_to_password_digest?
66
+ rescue ActionController::ParameterMissing => e
67
+ render inline: "ERROR: #{e.class.name}, #{e.message}", status: :bad_request
59
68
  end
60
69
 
61
70
  def update_auth_token_in_cookie(token)
@@ -88,13 +97,12 @@ module CamaleonCms
88
97
  end
89
98
 
90
99
  def create
91
- user_data = params.require(:user).permit!
92
- @user = current_site.users.new(user_data)
100
+ @user = current_site.users.new(user_params)
93
101
  r = { user: @user }
94
102
  hooks_run('user_create', r)
95
103
  if @user.save
96
- @user.set_metas(params[:meta]) if params[:meta].present?
97
- @user.set_field_values(params[:field_options])
104
+ @user.set_metas(user_meta_params) if params[:meta].present?
105
+ @user.set_field_values(cama_permitted_field_options('User')) if params[:field_options].present?
98
106
  r = { user: @user }
99
107
  hooks_run('user_created', r)
100
108
  flash[:notice] = t('camaleon_cms.admin.users.message.created')
@@ -133,12 +141,13 @@ module CamaleonCms
133
141
  end
134
142
 
135
143
  def user_params
136
- parameters = params.require(:user)
137
- if cama_current_user.role_grantor?(@user)
138
- parameters.permit(:username, :email, :role, :first_name, :last_name)
139
- else
140
- parameters.permit(:username, :email, :first_name, :last_name)
141
- end
144
+ p = params.require(:user).permit(:username, :email, :first_name, :last_name, :password, :password_confirmation)
145
+ p[:role] = params[:user][:role] if cama_current_user.role_grantor?(@user) && params[:user][:role].present?
146
+ p
147
+ end
148
+
149
+ def user_meta_params
150
+ params.require(:meta).permit(:avatar, :slogan)
142
151
  end
143
152
 
144
153
  def set_user
@@ -7,6 +7,7 @@ module CamaleonCms
7
7
  include CamaleonCms::Admin::ApplicationHelper
8
8
  # layout 'camaleon_cms/admin'
9
9
  before_action :cama_authenticate
10
+ before_action :keep_request_attrs
10
11
  before_action :admin_init_actions
11
12
  before_action :admin_logged_actions
12
13
  before_action :admin_before_hooks
@@ -83,6 +84,13 @@ module CamaleonCms
83
84
  hooks_run('admin_before_load')
84
85
  end
85
86
 
87
+ # Set cama_current_user and current_site in CurrentRequest so models can access the current context.
88
+ # CurrentRequest is an ActiveSupport::CurrentAttributes subclass that auto-resets per request.
89
+ def keep_request_attrs
90
+ CurrentRequest.user = cama_current_user
91
+ CurrentRequest.site = current_site
92
+ end
93
+
86
94
  # trigger hooks for admin panel after admin load
87
95
  def admin_after_hooks
88
96
  hooks_run('admin_after_load')
@@ -2,6 +2,7 @@ module CamaleonCms
2
2
  module Apps
3
3
  class PluginsAdminController < CamaleonCms::AdminController
4
4
  before_action :init_plugin
5
+ before_action :authorize_plugin
5
6
 
6
7
  private
7
8
 
@@ -21,6 +22,10 @@ module CamaleonCms
21
22
  lookup_context.prefixes.prepend(params[:controller].sub("plugins/#{plugin_name}",
22
23
  "plugins/#{plugin_name}/views"))
23
24
  end
25
+
26
+ def authorize_plugin
27
+ authorize! :manage, :plugins
28
+ end
24
29
  end
25
30
  end
26
31
  end
@@ -0,0 +1,29 @@
1
+ module CamaleonCms
2
+ module Admin
3
+ module CustomFieldsConcern
4
+ extend ActiveSupport::Concern
5
+
6
+ private
7
+
8
+ # Only permit field_options that match registered custom field slugs
9
+ def cama_permitted_field_options(object_class)
10
+ return {} unless params[:field_options].present?
11
+
12
+ allowed_keys = cama_custom_field_allowed_slugs(object_class)
13
+ return {} if allowed_keys.blank?
14
+
15
+ field_options = params.require(:field_options)
16
+ field_options.permit(field_options.keys.select { |k| k.to_s =~ /\A\d+\z/ }.index_with do
17
+ allowed_keys.index_with { [:id, :group_number, { values: {} }] }
18
+ end).to_h
19
+ end
20
+
21
+ def cama_custom_field_allowed_slugs(object_class)
22
+ CamaleonCms::CustomField.where(
23
+ parent_id: CamaleonCms::CustomField.where(object_class: object_class).select(:id),
24
+ object_class: '_fields'
25
+ ).pluck(:slug).uniq
26
+ end
27
+ end
28
+ end
29
+ end
@@ -4,7 +4,7 @@ module CamaleonCms
4
4
  delegate_all
5
5
 
6
6
  def the_title(locale = nil)
7
- r = { title: object.title.to_s.translate(get_locale(locale)), post: object }
7
+ r = { title: h.h(object.title.to_s.translate(get_locale(locale))), post: object }
8
8
  h.hooks_run('post_the_title', r)
9
9
  r[:title]
10
10
  end
@@ -53,7 +53,7 @@ module CamaleonCms
53
53
  end
54
54
 
55
55
  def role_grantor?(other_user)
56
- h.can?(:manage, :users) && id != other_user.id
56
+ h.can?(:manage, :users) && (other_user.nil? || id != other_user.id)
57
57
  end
58
58
 
59
59
  def self.object_class_name
@@ -9,27 +9,27 @@ module CamaleonCms
9
9
 
10
10
  # render pagination for current items
11
11
  # items is a will pagination object
12
- # sample: <%= raw cama_do_pagination(@posts) %>
12
+ # sample: <%= cama_do_pagination(@posts) %>
13
13
  def cama_do_pagination(items, *will_paginate_options)
14
14
  will_paginate_options = will_paginate_options.extract_options!
15
- custom_class = will_paginate_options[:panel_class]
16
- will_paginate_options.delete(:panel_class)
17
- "<div class='row #{custom_class} pagination_panel cama_ajax_request'>
18
- <div class='col-md-10'>
19
- #{begin
15
+ custom_class = will_paginate_options.delete(:panel_class)
16
+ content_tag(:div, class: "row #{custom_class} pagination_panel cama_ajax_request") do
17
+ concat(content_tag(:div, class: 'col-md-10') do
20
18
  will_paginate(items, will_paginate_options)
21
19
  rescue StandardError
22
20
  ''
23
- end}
24
- </div>
25
- <div class='col-md-2 text-right total-items'>
26
- <strong>#{I18n.t('camaleon_cms.admin.table.total', default: 'Total')}: #{begin
27
- items.total_entries
28
- rescue StandardError
29
- items.count
30
- end} </strong>
31
- </div>
32
- </div>"
21
+ end)
22
+ concat(content_tag(:div, class: 'col-md-2 text-right total-items') do
23
+ content_tag(:strong) do
24
+ total = begin
25
+ items.total_entries
26
+ rescue StandardError
27
+ items.count
28
+ end
29
+ "#{I18n.t('camaleon_cms.admin.table.total', default: 'Total')}: #{total}"
30
+ end
31
+ end)
32
+ end
33
33
  end
34
34
 
35
35
  # return the locale for frontend translations initialized in admin controller
@@ -41,7 +41,7 @@ module CamaleonCms
41
41
 
42
42
  # print code with auto copy
43
43
  def cama_shortcode_print(code)
44
- "<input onmousedown=\"this.clicked = 1;\" readonly onfocus=\"if (!this.clicked) this.select(); else this.clicked = 2;\" onclick=\"if (this.clicked == 2) this.select(); this.clicked = 0;\" class='code_style' tabindex='-1' value=\"#{code}\">"
44
+ content_tag(:input, nil, class: 'code_style', readonly: true, onmousedown: 'this.clicked = 1;', onfocus: 'if (!this.clicked) this.select(); else this.clicked = 2;', onclick: 'if (this.clicked == 2) this.select(); this.clicked = 0;', tabindex: '-1', value: code)
45
45
  end
46
46
  end
47
47
  end
@@ -11,17 +11,16 @@ module CamaleonCms
11
11
  end
12
12
 
13
13
  def post_type_status(status, color = 'default')
14
- "<span class='label label-#{color} label-form'>#{status}</span>"
14
+ content_tag(:span, status, class: "label label-#{color} label-form")
15
15
  end
16
16
 
17
17
  # taxonomies -> (categories || post_tags)
18
18
  def post_type_list_taxonomy(taxonomies, color = 'primary')
19
- html = ''
20
- taxonomies.decorate.each do |f|
21
- html += "<a class='cama_ajax_request' href='#{cama_admin_post_type_taxonomy_posts_path(@post_type.id,
22
- f.taxonomy, f.id)}'><span class='label label-#{color} label-form'>#{f.the_title}</span></a> "
23
- end
24
- html
19
+ taxonomies.decorate.map do |f|
20
+ link_to(cama_admin_post_type_taxonomy_posts_path(@post_type.id, f.taxonomy, f.id), class: 'cama_ajax_request') do
21
+ content_tag(:span, f.the_title, class: "label label-#{color} label-form")
22
+ end
23
+ end.join(' ').html_safe
25
24
  end
26
25
 
27
26
  # sort array of posts to build post's tree
@@ -54,23 +53,27 @@ module CamaleonCms
54
53
  values = [], class_cat = '', required = false)
55
54
  if categories.count < 1
56
55
  return t('camaleon_cms.admin.post_type.message.no_created_html',
57
- taxonomy: taxonomy == 'categories' ? t('camaleon_cms.admin.table.categories') : t('camaleon_cms.admin.table.tags')).to_s
58
- end
59
-
60
- html = "<ul class='#{class_cat}'>"
61
- categories.decorate.each do |f|
62
- html += '<li>'
63
- html += "<label class='class_slug' data-post_link_edit='#{f.the_edit_url}'> "
64
- html += "<input data-error-place='#validation_error_list_#{name}' type='#{type}' name='#{name}[]' #{values.to_i.include?(f.id) ? 'checked' : ''} value='#{f.id}' class = '#{if required
65
- 'required'
66
- end}' />"
67
- html += "#{f.the_title} </label> "
68
- html += post_type_html_inputs(f, 'children', name, type, values, 'children') if f.children.present?
69
- html += '</li>'
56
+ taxonomy: taxonomy == 'categories' ? t('camaleon_cms.admin.table.categories') : t('camaleon_cms.admin.table.tags'))
70
57
  end
71
58
 
72
- html += "</ul><div id='validation_error_list_#{name}'></div>"
73
- html
59
+ content_tag(:ul, class: class_cat) do
60
+ categories.decorate.map do |f|
61
+ content_tag(:li) do
62
+ is_checked = Array(values).map(&:to_s).include?(f.id.to_s)
63
+ input_options = { class: (required ? 'required' : ''), data: { error_place: "#validation_error_list_#{name}" } }
64
+ input_tag = if type == 'radio'
65
+ radio_button_tag("#{name}[]", f.id, is_checked, input_options)
66
+ else
67
+ check_box_tag("#{name}[]", f.id, is_checked, input_options)
68
+ end
69
+ res = content_tag(:label, class: 'class_slug', data: { post_link_edit: f.the_edit_url }) do
70
+ "#{input_tag} #{f.the_title} ".html_safe
71
+ end
72
+ res << post_type_html_inputs(f, 'children', name, type, values, 'children') if f.children.present?
73
+ res
74
+ end
75
+ end.join.html_safe
76
+ end + content_tag(:div, '', id: "validation_error_list_#{name}")
74
77
  end
75
78
  end
76
79
  end
@@ -1,5 +1,7 @@
1
1
  module CamaleonCms
2
2
  module CommentHelper
3
+ LABELS = { 'approved' => 'success', 'pending' => 'warning', 'spam' => 'danger' }.freeze
4
+
3
5
  # return common data to save a new comment
4
6
  # user_id, author, aothor_email, author_ip, approved, :agent
5
7
  def cama_comments_get_common_data
@@ -16,47 +18,79 @@ module CamaleonCms
16
18
  # render as html content all comments recursively
17
19
  # comments: collection of comments
18
20
  def cama_comments_render_html(comments)
19
- res = ''
20
- labels = { 'approved' => 'success', 'pending' => 'warning', 'spam' => 'danger' }
21
- comments.decorate.each do |comment|
21
+ comments.decorate.map do |comment|
22
22
  author = comment.the_author
23
- res << "<div class='media'>
24
- <div class='media-left'>
25
- <a href='#{author.the_admin_profile_url}'>#{image_tag author.the_avatar, class: 'media-object',
26
- style: 'width: 64px; height: 64px;'}</a>
27
- </div>
28
- <div class='media-body'>
29
- <h4 class='media-heading'>#{author.the_name} <small>#{comment.the_created_at}</small> <span class='label label-#{labels[comment.approved]} pull-right'>#{t("camaleon_cms.admin.comments.message.#{comment.approved}")}</span></h4>
30
- <div class='comment_content'>#{sanitize comment.content}</div>
31
- <div class='comment_actions'>
32
- <div class='pull-left'>
33
- <a href='#{cama_admin_post_comment_answer_path(@post.id,
34
- comment.id)}' data-comment-id='#{comment.id}' title='#{t('camaleon_cms.admin.comments.tooltip.reply_comment')}' class='btn btn-info reply btn-xs ajax_modal'><span class='fa fa-mail-reply'></span></a>
35
- #{link_to raw('<i class="fa fa-trash-o"></i>'), { action: :destroy, id: comment.id },
36
- method: :delete, data: { confirm: t('camaleon_cms.admin.message.delete') }, class: 'btn btn-danger btn-xs cama_ajax_request', title: t('camaleon_cms.admin.comments.tooltip.delete_comment').to_s}
37
- </div>
38
- <div class='pull-right'>
39
- <a href='#{url_for({ action: :toggle_status, comment_id: comment.id,
40
- s: 'a' })}' title='#{t('camaleon_cms.admin.comments.tooltip.approved_comment')}' class='#{if comment.approved == 'approved'
41
- 'hidden'
42
- end} btn btn-success approve btn-xs cama_ajax_request'><span class='fa fa-thumbs-o-up'></span></a>
43
- <a href='#{url_for({ action: :toggle_status, comment_id: comment.id,
44
- s: 'p' })}' title='#{t('camaleon_cms.admin.comments.tooltip.comment_pending')}' class='#{if comment.approved == 'pending'
45
- 'hidden'
46
- end} btn btn-primary pending btn-xs cama_ajax_request'><span class='fa fa-warning'></span></a>
47
- <a href='#{url_for({ action: :toggle_status, comment_id: comment.id,
48
- s: 's' })}' title='#{t('camaleon_cms.admin.comments.tooltip.comment_spam')}' class='#{if comment.approved == 'spam'
49
- 'hidden'
50
- end} btn btn-danger spam btn-xs cama_ajax_request'><span class='fa fa-bug'></span></a>
51
- </div>
52
- </div>
53
- <hr>
54
- <div class='clearfix'></div>
55
- #{cama_comments_render_html comment.children}
56
- </div>
57
- </div>"
58
- end
59
- res
23
+ content_tag(:div, class: 'media') do
24
+ [
25
+ content_tag(:div, class: 'media-left') do
26
+ link_to(author.the_admin_profile_url) do
27
+ image_tag(author.the_avatar, class: 'media-object', style: 'width: 64px; height: 64px;')
28
+ end
29
+ end,
30
+ content_tag(:div, class: 'media-body') do
31
+ [
32
+ content_tag(:h4, class: 'media-heading') do
33
+ [
34
+ author.the_name,
35
+ ' ',
36
+ content_tag(:small, comment.the_created_at),
37
+ ' ',
38
+ content_tag(:span, t("camaleon_cms.admin.comments.message.#{comment.approved}"),
39
+ class: "label label-#{LABELS[comment.approved]} pull-right")
40
+ ].join.html_safe
41
+ end,
42
+ content_tag(:div, sanitize(comment.content), class: 'comment_content'),
43
+ content_tag(:div, class: 'comment_actions') do
44
+ [
45
+ content_tag(:div, class: 'pull-left') do
46
+ [
47
+ link_to(
48
+ cama_admin_post_comment_answer_path(@post.id, comment.id),
49
+ data: { comment_id: comment.id },
50
+ title: t('camaleon_cms.admin.comments.tooltip.reply_comment'),
51
+ class: 'btn btn-info reply btn-xs ajax_modal'
52
+ ) { content_tag(:span, '', class: 'fa fa-mail-reply') },
53
+ ' ',
54
+ link_to(
55
+ { action: :destroy, id: comment.id },
56
+ method: :delete,
57
+ data: { confirm: t('camaleon_cms.admin.message.delete') },
58
+ class: 'btn btn-danger btn-xs cama_ajax_request',
59
+ title: t('camaleon_cms.admin.comments.tooltip.delete_comment')
60
+ ) { content_tag(:i, '', class: 'fa fa-trash-o') }
61
+ ].join.html_safe
62
+ end,
63
+ content_tag(:div, class: 'pull-right') do
64
+ [
65
+ link_to(
66
+ url_for({ action: :toggle_status, comment_id: comment.id, s: 'a' }),
67
+ title: t('camaleon_cms.admin.comments.tooltip.approved_comment'),
68
+ class: "#{comment.approved == 'approved' ? 'hidden' : ''} btn btn-success approve btn-xs cama_ajax_request"
69
+ ) { content_tag(:span, '', class: 'fa fa-thumbs-o-up') },
70
+ ' ',
71
+ link_to(
72
+ url_for({ action: :toggle_status, comment_id: comment.id, s: 'p' }),
73
+ title: t('camaleon_cms.admin.comments.tooltip.comment_pending'),
74
+ class: "#{comment.approved == 'pending' ? 'hidden' : ''} btn btn-primary pending btn-xs cama_ajax_request"
75
+ ) { content_tag(:span, '', class: 'fa fa-warning') },
76
+ ' ',
77
+ link_to(
78
+ url_for({ action: :toggle_status, comment_id: comment.id, s: 's' }),
79
+ title: t('camaleon_cms.admin.comments.tooltip.comment_spam'),
80
+ class: "#{comment.approved == 'spam' ? 'hidden' : ''} btn btn-danger spam btn-xs cama_ajax_request"
81
+ ) { content_tag(:span, '', class: 'fa fa-bug') }
82
+ ].join.html_safe
83
+ end
84
+ ].join.html_safe
85
+ end,
86
+ content_tag(:hr),
87
+ content_tag(:div, '', class: 'clearfix'),
88
+ cama_comments_render_html(comment.children)
89
+ ].join.html_safe
90
+ end
91
+ ].join.html_safe
92
+ end
93
+ end.join('').html_safe
60
94
  end
61
95
  end
62
96
  end
@@ -68,7 +68,7 @@ module CamaleonCms
68
68
  # the_content
69
69
  # end
70
70
  def the_content
71
- @object.the_content.html_safe if @object.present?
71
+ sanitize(@object.the_content) if @object.present?
72
72
  end
73
73
 
74
74
  # select url of post
@@ -9,7 +9,7 @@ module CamaleonCms
9
9
  draw_menu({ menu_slug: key, container_class: class_name })
10
10
  end
11
11
 
12
- # draw menu as an html
12
+ # draw menu as html
13
13
  # default configurations is for bootstrap support
14
14
  def draw_menu(args = {})
15
15
  args_def = {
@@ -23,7 +23,7 @@ module CamaleonCms
23
23
  item_class_parent: 'dropdown', # class for all menu items that contain sub items
24
24
  sub_container: 'ul', # type of container for sub items
25
25
  sub_class: 'dropdown-menu', # class for sub container
26
- callback_item: ->(args) {}, # rubocop:disable Lint/ShadowingOuterLocalVariable
26
+ callback_item: ->(args) {},
27
27
  # callback executed for each item (args = { menu_item, link, level, settings, has_children, link_attrs = "", index}).
28
28
  # menu_item: (Object) Menu object
29
29
  # link: (Hash) link data: {link: '', name: ''}
@@ -33,7 +33,7 @@ module CamaleonCms
33
33
  # index: (Integer) Index Position of this menu
34
34
  # link_attrs: (String) Here you can add your custom attrs for current link, sample: id='my_id' data-title='#{args[:link][:name]}'
35
35
  # item_container_attrs: (String) Here you can add your custom attrs for link container.
36
- # In settings you can change the values for this item, like after, before, ..:
36
+ # In settings, you can change the values for this item, like after, before, ..:
37
37
  # sample: lambda{|args| args[:settings][:after] = "<span class='caret'></span>" if args[:has_children]; args[:link_attrs] = "id='#{menu_item.id}'"; }
38
38
  # sample: lambda{|args| args[:settings][:before] = "<i class='fa fa-home'></i>" if args[:level] == 0 && args[:index] == 0; }
39
39
  before: '', # content before link text
@@ -99,7 +99,7 @@ module CamaleonCms
99
99
  html += "<#{_args[:item_container]} #{r[:item_container_attrs]} class='#{_args[:item_class]} #{if has_children
100
100
  _args[:item_class_parent]
101
101
  end} #{if _is_current
102
- (_args[:item_current]).to_s
102
+ _args[:item_current].to_s
103
103
  end} #{if current_children
104
104
  'current-menu-ancestor'
105
105
  end}'>#{_args[:link_before]}
@@ -129,8 +129,8 @@ module CamaleonCms
129
129
 
130
130
  # filter and parse all menu items visible for current user and adding the flag for current_parent or current_item
131
131
  # max_levels: max levels to iterate
132
- # return an multidimensional array with all items until level 'max_levels'
133
- # internal_level: ingnore (managed by internal recursion)
132
+ # return a multidimensional array with all items until level 'max_levels'
133
+ # internal_level: ignore (managed by internal recursion)
134
134
  def cama_menu_parse_items(items, max_levels = -1, internal_level = 0)
135
135
  res = []
136
136
  is_current_parent = false
@@ -154,7 +154,7 @@ module CamaleonCms
154
154
  current_item: _is_current,
155
155
  current_parent: false,
156
156
  levels: 0
157
- }.merge(data_nav_item.except(:current, :name, :link))
157
+ }.merge!(data_nav_item.except(:current, :name, :link))
158
158
 
159
159
  if has_children
160
160
  r[:children], _is_current_parent, r[:levels] = cama_menu_parse_items(nav_menu_item.children, max_levels,