camaleon_cms 2.9.1 → 2.9.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.
- checksums.yaml +4 -4
- data/README.md +29 -9
- data/Rakefile +3 -16
- data/app/apps/plugins/attack/admin_controller.rb +9 -6
- data/app/apps/plugins/attack/attack_helper.rb +35 -25
- data/app/apps/plugins/authoring_post/authoring_post_helper.rb +23 -16
- data/app/apps/plugins/front_cache/admin_controller.rb +16 -10
- data/app/apps/plugins/front_cache/config/initializer.rb +1 -1
- data/app/apps/plugins/front_cache/front_cache_helper.rb +57 -24
- data/app/apps/plugins/visibility_post/config/config.json +1 -0
- data/app/apps/plugins/visibility_post/config/routes_front.txt +1 -0
- data/app/apps/plugins/visibility_post/front_controller.rb +23 -0
- data/app/apps/plugins/visibility_post/visibility_post_helper.rb +141 -70
- data/app/apps/themes/camaleon_first/main_helper.rb +18 -12
- data/app/apps/themes/default/assets/css/style.css.scss +24 -0
- data/app/apps/themes/default/assets/genericons/genericons.css +3 -8
- data/app/apps/themes/default/default_helper.rb +2 -1
- data/app/apps/themes/default/views/category.html.erb +1 -1
- data/app/apps/themes/default/views/layouts/index.html.erb +3 -1
- data/app/apps/themes/default/views/post_tag.html.erb +1 -1
- data/app/apps/themes/default/views/post_type.html.erb +1 -1
- data/app/apps/themes/default/views/search.html.erb +1 -1
- data/app/apps/themes/new/assets/css/styles.css.scss +24 -0
- data/app/apps/themes/new/custom_helper.rb +5 -9
- data/app/apps/themes/new/views/category.html.erb +1 -1
- data/app/apps/themes/new/views/layouts/_header.html.erb +3 -1
- data/app/apps/themes/new/views/post_tag.html.erb +1 -1
- data/app/apps/themes/new/views/post_type.html.erb +1 -1
- data/app/apps/themes/new/views/search.html.erb +1 -1
- data/app/assets/javascripts/camaleon_cms/admin/_data.js +16 -0
- data/app/assets/javascripts/camaleon_cms/admin/_post.js +5 -2
- data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js +14 -3
- data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js +5 -0
- data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +29 -10
- data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +8 -5
- data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +9 -2
- data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +4 -3
- data/app/controllers/camaleon_cms/admin/appearances/widgets/sidebar_controller.rb +2 -2
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +27 -8
- data/app/controllers/camaleon_cms/admin/comments_controller.rb +0 -1
- data/app/controllers/camaleon_cms/admin/installers_controller.rb +32 -1
- data/app/controllers/camaleon_cms/admin/media_controller.rb +84 -19
- data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -3
- data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +15 -6
- data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +40 -11
- data/app/controllers/camaleon_cms/admin/posts_controller.rb +58 -22
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +238 -45
- data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +103 -18
- data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +17 -5
- data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +33 -7
- data/app/controllers/camaleon_cms/admin/settings_controller.rb +11 -6
- data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +9 -7
- data/app/controllers/camaleon_cms/admin/users_controller.rb +89 -18
- data/app/controllers/camaleon_cms/admin_controller.rb +144 -26
- data/app/controllers/camaleon_cms/apps/plugins_admin_controller.rb +5 -0
- data/app/controllers/camaleon_cms/camaleon_controller.rb +37 -92
- data/app/controllers/camaleon_cms/frontend_controller.rb +140 -70
- data/app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb +44 -0
- data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +46 -17
- data/app/controllers/concerns/camaleon_cms/frontend_visited_state_concern.rb +72 -0
- data/app/controllers/concerns/camaleon_cms/hook_lifecycle_concern.rb +104 -0
- data/app/controllers/concerns/camaleon_cms/request_context_concern.rb +113 -0
- data/app/controllers/concerns/camaleon_cms/runtime_admin_menu_concern.rb +237 -0
- data/app/controllers/concerns/camaleon_cms/runtime_captcha_image_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_html_content_concern.rb +143 -0
- data/app/controllers/concerns/camaleon_cms/runtime_shortcode_theme_concern.rb +246 -0
- data/app/controllers/concerns/camaleon_cms/runtime_state_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_uploader_concern.rb +54 -0
- data/app/controllers/concerns/camaleon_cms/session_captcha_runtime_concern.rb +19 -0
- data/app/controllers/concerns/camaleon_cms/session_runtime_concern.rb +40 -0
- data/app/decorators/camaleon_cms/application_decorator.rb +11 -8
- data/app/decorators/camaleon_cms/category_decorator.rb +3 -2
- data/app/decorators/camaleon_cms/post_comment_decorator.rb +13 -5
- data/app/decorators/camaleon_cms/post_decorator.rb +67 -51
- data/app/decorators/camaleon_cms/post_type_decorator.rb +1 -1
- data/app/decorators/camaleon_cms/site_decorator.rb +29 -23
- data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +21 -10
- data/app/decorators/camaleon_cms/theme_decorator.rb +3 -3
- data/app/decorators/camaleon_cms/user_decorator.rb +26 -5
- data/app/helpers/camaleon_cms/admin/application_helper.rb +21 -24
- data/app/helpers/camaleon_cms/admin/breadcrumb_helper.rb +1 -1
- data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +24 -23
- data/app/helpers/camaleon_cms/admin/menus_helper.rb +249 -139
- data/app/helpers/camaleon_cms/admin/post_type_helper.rb +51 -31
- data/app/helpers/camaleon_cms/camaleon_helper.rb +31 -39
- data/app/helpers/camaleon_cms/captcha_helper.rb +73 -53
- data/app/helpers/camaleon_cms/comment_helper.rb +87 -41
- data/app/helpers/camaleon_cms/content_helper.rb +13 -6
- data/app/helpers/camaleon_cms/email_helper.rb +7 -3
- data/app/helpers/camaleon_cms/frontend/content_select_helper.rb +34 -20
- data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +144 -67
- data/app/helpers/camaleon_cms/frontend/seo_helper.rb +39 -28
- data/app/helpers/camaleon_cms/frontend/site_helper.rb +32 -12
- data/app/helpers/camaleon_cms/hooks_helper.rb +14 -4
- data/app/helpers/camaleon_cms/html_helper.rb +73 -38
- data/app/helpers/camaleon_cms/plugins_helper.rb +23 -24
- data/app/helpers/camaleon_cms/session_helper.rb +195 -39
- data/app/helpers/camaleon_cms/short_code_helper.rb +181 -85
- data/app/helpers/camaleon_cms/site_helper.rb +43 -9
- data/app/helpers/camaleon_cms/theme_helper.rb +35 -19
- data/app/helpers/camaleon_cms/uploader_helper.rb +19 -422
- data/app/helpers/camaleon_cms/user_roles_helper.rb +5 -4
- data/app/mailers/camaleon_cms/html_mailer.rb +4 -4
- data/app/models/camaleon_cms/ability.rb +65 -105
- data/app/models/camaleon_cms/category.rb +7 -5
- data/app/models/camaleon_cms/custom_field.rb +29 -6
- data/app/models/camaleon_cms/custom_field_group.rb +75 -21
- data/app/models/camaleon_cms/custom_fields_relationship.rb +133 -2
- data/app/models/camaleon_cms/media.rb +8 -2
- data/app/models/camaleon_cms/meta.rb +2 -2
- data/app/models/camaleon_cms/nav_menu.rb +6 -2
- data/app/models/camaleon_cms/nav_menu_item.rb +18 -8
- data/app/models/camaleon_cms/plugin.rb +4 -3
- data/app/models/camaleon_cms/post.rb +113 -27
- data/app/models/camaleon_cms/post_comment.rb +10 -6
- data/app/models/camaleon_cms/post_default.rb +42 -12
- data/app/models/camaleon_cms/post_relationship.rb +6 -4
- data/app/models/camaleon_cms/post_tag.rb +4 -3
- data/app/models/camaleon_cms/post_type.rb +22 -12
- data/app/models/camaleon_cms/site.rb +40 -28
- data/app/models/camaleon_cms/term_relationship.rb +10 -7
- data/app/models/camaleon_cms/term_taxonomy.rb +51 -5
- data/app/models/camaleon_cms/theme.rb +3 -3
- data/app/models/camaleon_cms/user.rb +17 -5
- data/app/models/camaleon_cms/user_role.rb +77 -4
- data/app/models/camaleon_cms/widget/assigned.rb +11 -6
- data/app/models/camaleon_cms/widget/main.rb +13 -7
- data/app/models/camaleon_cms/widget/sidebar.rb +3 -6
- data/app/models/camaleon_record.rb +123 -5
- data/app/models/concerns/camaleon_cms/categories_tags_for_posts.rb +20 -38
- data/app/models/concerns/camaleon_cms/common_relationships.rb +18 -5
- data/app/models/concerns/camaleon_cms/custom_fields_read.rb +115 -58
- data/app/models/concerns/camaleon_cms/metas.rb +32 -7
- data/app/models/concerns/camaleon_cms/normalize_attrs.rb +2 -8
- data/app/models/concerns/camaleon_cms/site_default_settings.rb +120 -16
- data/app/models/concerns/camaleon_cms/user_methods.rb +44 -19
- data/app/models/current_request.rb +23 -0
- data/app/uploaders/camaleon_cms_aws_uploader.rb +39 -11
- data/app/uploaders/camaleon_cms_local_uploader.rb +76 -19
- data/app/uploaders/camaleon_cms_uploader.rb +23 -10
- data/app/validators/camaleon_cms/post_uniq_validator.rb +21 -8
- data/app/validators/camaleon_cms/uniq_validator.rb +1 -1
- data/app/validators/camaleon_cms/user_url_validator.rb +215 -36
- data/app/views/camaleon_cms/admin/appearances/nav_menus/_left_menu_items.html.erb +2 -2
- data/app/views/camaleon_cms/admin/appearances/widgets/main/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/categories/index.html.erb +3 -3
- data/app/views/camaleon_cms/admin/comments/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/comments/list.html.erb +1 -1
- data/app/views/camaleon_cms/admin/installers/form.html.erb +5 -0
- data/app/views/camaleon_cms/admin/installers/welcome.html.erb +30 -6
- data/app/views/camaleon_cms/admin/plugins/_plugins_list.html.erb +2 -2
- data/app/views/camaleon_cms/admin/post_tags/index.html.erb +3 -3
- data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +2 -2
- data/app/views/camaleon_cms/admin/posts/form.html.erb +3 -2
- data/app/views/camaleon_cms/admin/posts/index.html.erb +6 -6
- data/app/views/camaleon_cms/admin/search.html.erb +1 -1
- data/app/views/camaleon_cms/admin/sessions/back_to_parent.html.erb +39 -0
- data/app/views/camaleon_cms/admin/sessions/logout_confirm.html.erb +27 -0
- data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +4 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +42 -6
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render_category_simple.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +5 -4
- data/app/views/camaleon_cms/admin/settings/custom_fields/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/shortcodes.html.erb +4 -4
- data/app/views/camaleon_cms/admin/settings/site.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/user_roles/form.html.erb +102 -7
- data/app/views/camaleon_cms/admin/user_roles/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/users/form.html.erb +8 -4
- data/app/views/camaleon_cms/admin/users/index.html.erb +2 -2
- data/app/views/camaleon_cms/default_theme/partials/_render_custom_field.html.erb +8 -2
- data/app/views/camaleon_cms/default_theme/sitemap.html.erb +1 -1
- data/app/views/camaleon_cms/default_theme/sitemap.xml.builder +1 -1
- data/app/views/layouts/camaleon_cms/admin/_flash_messages.html.erb +2 -2
- data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
- data/config/initializers/action_view.rb +42 -5
- data/config/initializers/active_record_extension.rb +13 -27
- data/config/initializers/assets.rb +52 -23
- data/config/initializers/custom_initializers.rb +3 -3
- data/config/locales/camaleon_cms/admin/ar.yml +7 -2
- data/config/locales/camaleon_cms/admin/de.yml +7 -2
- data/config/locales/camaleon_cms/admin/en.yml +39 -2
- data/config/locales/camaleon_cms/admin/es.yml +7 -2
- data/config/locales/camaleon_cms/admin/fr.yml +7 -2
- data/config/locales/camaleon_cms/admin/it.yml +7 -2
- data/config/locales/camaleon_cms/admin/nl.yml +8 -2
- data/config/locales/camaleon_cms/admin/pt-BR.yml +7 -2
- data/config/locales/camaleon_cms/admin/pt.yml +7 -2
- data/config/locales/camaleon_cms/admin/ru.yml +7 -2
- data/config/locales/camaleon_cms/admin/uk.yml +7 -2
- data/config/locales/camaleon_cms/admin/zh-CH.yml +7 -2
- data/config/routes/admin.rb +33 -15
- data/config/routes/frontend.rb +21 -15
- data/db/migrate/20150611161134_post_table_into_utf8.rb +14 -14
- data/db/migrate/20150926095310_rename_column_posts.rb +3 -3
- data/db/migrate/20151212095328_add_confirm_token_to_users.rb +3 -3
- data/db/migrate/20160504155652_add_feature_to_posts.rb +1 -1
- data/db/migrate/20160504155653_move_first_name_of_users.rb +2 -2
- data/db/migrate/20160609121449_add_group_to_custom_field_values.rb +1 -1
- data/db/migrate/20161215202255_drop_user_relationship_table.rb +1 -1
- data/db/migrate/20180124132318_create_media.rb +1 -1
- data/db/migrate/20180704211100_adjust_field_length.rb +1 -1
- data/lib/camaleon_cms/assets_precompile.rb +86 -0
- data/lib/camaleon_cms/captcha_image_generation.rb +65 -0
- data/lib/camaleon_cms/content_security.rb +158 -0
- data/lib/camaleon_cms/engine.rb +47 -9
- data/lib/camaleon_cms/media_security_headers.rb +27 -0
- data/lib/camaleon_cms/setup_token.rb +69 -0
- data/lib/camaleon_cms/svg_content_checker.rb +123 -0
- data/lib/camaleon_cms/task_reporter.rb +14 -0
- data/lib/camaleon_cms/unsafe_markup.rb +207 -0
- data/lib/camaleon_cms/uploader_content_security.rb +248 -0
- data/lib/camaleon_cms/uploader_image_processing.rb +166 -0
- data/lib/camaleon_cms/uploader_path_security.rb +146 -0
- data/lib/camaleon_cms/uploader_pipeline.rb +350 -0
- data/lib/camaleon_cms/uploader_support.rb +86 -0
- data/lib/camaleon_cms/version.rb +1 -1
- data/lib/camaleon_cms.rb +11 -0
- data/lib/ext/hash.rb +28 -2
- data/lib/ext/string.rb +13 -8
- data/lib/ext/translator.rb +10 -2
- data/lib/generators/camaleon_cms/gem_plugin_template/app/controllers/plugins/my_plugin/admin_controller.rb +5 -1
- data/lib/generators/camaleon_cms/install_generator.rb +7 -4
- data/lib/generators/camaleon_cms/install_template/plugin_routes.rb +5 -12
- data/lib/generators/camaleon_cms/theme_generator.rb +5 -10
- data/lib/generators/camaleon_cms/theme_template/views/layouts/index.html.erb +3 -1
- data/lib/plugin_routes.rb +412 -368
- data/lib/tasks/camaleon_cms/camaleon_tasks.rake +2 -1
- data/lib/tasks/cross_site_field_groups.rake +74 -0
- data/lib/tasks/custom_fields_roles.rake +58 -0
- data/lib/tasks/orphaned_comments.rake +42 -0
- data/lib/tasks/private_upload_acls.rake +31 -0
- data/lib/tasks/site_custom_field_groups.rake +36 -0
- data/lib/tasks/unsafe_stored_content.rake +42 -0
- data/lib/tasks/unsafe_stored_uploads.rake +70 -0
- data/lib/tasks/user_field_groups.rake +27 -0
- metadata +185 -7
|
@@ -2,31 +2,19 @@ module CamaleonCms
|
|
|
2
2
|
module Admin
|
|
3
3
|
module CustomFieldsHelper
|
|
4
4
|
def cama_custom_field_elements
|
|
5
|
-
return
|
|
5
|
+
return CurrentRequest.custom_field_elements if CurrentRequest.custom_field_elements.present?
|
|
6
6
|
|
|
7
7
|
items = {}
|
|
8
8
|
items[:text_box] = {
|
|
9
9
|
key: 'text_box',
|
|
10
10
|
label: t('camaleon_cms.admin.custom_field.fields.text_box'),
|
|
11
|
-
options: {
|
|
12
|
-
required: true,
|
|
13
|
-
multiple: true,
|
|
14
|
-
translate: true,
|
|
15
|
-
default_value: '',
|
|
16
|
-
show_frontend: true
|
|
17
|
-
}
|
|
11
|
+
options: { required: true, multiple: true, translate: true, default_value: '', show_frontend: true }
|
|
18
12
|
}
|
|
19
13
|
|
|
20
14
|
items[:text_area] = {
|
|
21
15
|
key: 'text_area',
|
|
22
16
|
label: t('camaleon_cms.admin.custom_field.fields.text_area'),
|
|
23
|
-
options: {
|
|
24
|
-
required: true,
|
|
25
|
-
multiple: true,
|
|
26
|
-
translate: true,
|
|
27
|
-
default_value: '',
|
|
28
|
-
show_frontend: true
|
|
29
|
-
}
|
|
17
|
+
options: { required: true, multiple: true, translate: true, default_value: '', show_frontend: true }
|
|
30
18
|
}
|
|
31
19
|
items[:select] = {
|
|
32
20
|
key: 'select',
|
|
@@ -35,10 +23,7 @@ module CamaleonCms
|
|
|
35
23
|
required: true,
|
|
36
24
|
multiple: true,
|
|
37
25
|
translate: true,
|
|
38
|
-
multiple_options: {
|
|
39
|
-
label: t('camaleon_cms.admin.settings.options_select'),
|
|
40
|
-
default: 'radio'
|
|
41
|
-
},
|
|
26
|
+
multiple_options: { label: t('camaleon_cms.admin.settings.options_select'), default: 'radio' },
|
|
42
27
|
show_frontend: true
|
|
43
28
|
}
|
|
44
29
|
}
|
|
@@ -298,7 +283,8 @@ module CamaleonCms
|
|
|
298
283
|
}
|
|
299
284
|
|
|
300
285
|
# evaluate the content of command value on listing
|
|
301
|
-
# sample command:
|
|
286
|
+
# sample command:
|
|
287
|
+
# options_from_collection_for_select(current_site.the_posts("commerce").decorate, :id, :the_title)
|
|
302
288
|
items[:select_eval] = {
|
|
303
289
|
key: 'select_eval',
|
|
304
290
|
label: t('camaleon_cms.admin.custom_field.fields.select_eval'),
|
|
@@ -344,17 +330,32 @@ module CamaleonCms
|
|
|
344
330
|
}
|
|
345
331
|
r = { fields: items }
|
|
346
332
|
hooks_run('extra_custom_fields', r)
|
|
347
|
-
|
|
333
|
+
CurrentRequest.custom_field_elements = r[:fields]
|
|
348
334
|
end
|
|
349
335
|
|
|
350
336
|
# add your model class into custom fields editor
|
|
351
337
|
# Note: to use custom fields on your model, you need the following:
|
|
352
|
-
# - add: belongs_to :site (in your model)
|
|
338
|
+
# - add: belongs_to :site (in your model)
|
|
339
|
+
# //don't forget multi site support, i.e.: you need site_id attribute in your table
|
|
353
340
|
# - add: include CamaleonCms::CustomFieldsRead (in your model)
|
|
354
341
|
# ==> With this, you can manage your model like a plugin. Check api -> custom fields section into docs)
|
|
355
342
|
# model_class: class name (Product)
|
|
356
343
|
def cf_add_model(model_class)
|
|
357
|
-
|
|
344
|
+
CurrentRequest.extra_models_for_fields ||= []
|
|
345
|
+
CurrentRequest.extra_models_for_fields << model_class
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# Models offered in the field-group placement dropdown: those registered via cf_add_model plus any
|
|
349
|
+
# a custom_field_custom_models hook appends. Seeded from the legacy @_extra_models_for_fields ivar
|
|
350
|
+
# so a controller still assigning it keeps working. The dropdown used to read that ivar while
|
|
351
|
+
# cf_add_model wrote CurrentRequest, so registered models never appeared. Regression M18.
|
|
352
|
+
# The seed and the hook payload are copies: hook appends must reach only this read, not
|
|
353
|
+
# accumulate in the request store or leak into the controller ivar.
|
|
354
|
+
def cf_extra_models_for_fields
|
|
355
|
+
CurrentRequest.extra_models_for_fields ||= (instance_variable_get(:@_extra_models_for_fields) || []).dup
|
|
356
|
+
f_args = { models: CurrentRequest.extra_models_for_fields.dup }
|
|
357
|
+
hooks_run('custom_field_custom_models', f_args)
|
|
358
|
+
f_args[:models]
|
|
358
359
|
end
|
|
359
360
|
end
|
|
360
361
|
end
|
|
@@ -1,34 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module CamaleonCms
|
|
2
4
|
module Admin
|
|
3
5
|
module MenusHelper
|
|
4
6
|
include CamaleonCms::Admin::BreadcrumbHelper
|
|
7
|
+
include ActionView::Helpers::TagHelper
|
|
8
|
+
include ActionView::Helpers::OutputSafetyHelper
|
|
5
9
|
|
|
6
10
|
def admin_menus_add_commons
|
|
7
|
-
admin_menu_add_menu(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
admin_menu_add_menu(
|
|
12
|
+
'dashboard',
|
|
13
|
+
{ icon: 'dashboard', title: t('camaleon_cms.admin.sidebar.dashboard'), url: cama_admin_dashboard_path }
|
|
14
|
+
)
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
items = []
|
|
17
|
+
current_site.post_types.eager_load(:metas).visible_menu.find_each do |pt|
|
|
13
18
|
pt = pt.decorate
|
|
14
19
|
items_i = []
|
|
15
|
-
if can? :posts,
|
|
16
|
-
pt
|
|
20
|
+
if can? :posts, pt
|
|
17
21
|
items_i << { icon: 'list', title: t('camaleon_cms.admin.post_type.all').to_s,
|
|
18
22
|
url: cama_admin_post_type_posts_path(pt.id) }
|
|
19
23
|
end
|
|
20
|
-
if can? :create_post,
|
|
21
|
-
pt
|
|
24
|
+
if can? :create_post, pt
|
|
22
25
|
items_i << { icon: 'plus', title: t('camaleon_cms.admin.post_type.add_new', type_title: pt.the_title).to_s,
|
|
23
26
|
url: new_cama_admin_post_type_post_path(pt.id) }
|
|
24
27
|
end
|
|
25
|
-
if pt.manage_categories? && (can? :categories,
|
|
26
|
-
pt)
|
|
28
|
+
if pt.manage_categories? && (can? :categories, pt)
|
|
27
29
|
items_i << { icon: 'folder-open', title: t('camaleon_cms.admin.post_type.categories'),
|
|
28
30
|
url: cama_admin_post_type_categories_path(pt.id) }
|
|
29
31
|
end
|
|
30
|
-
if pt.manage_tags? && (can? :post_tags,
|
|
31
|
-
pt)
|
|
32
|
+
if pt.manage_tags? && (can? :post_tags, pt)
|
|
32
33
|
items_i << { icon: 'tags', title: t('camaleon_cms.admin.post_type.tags'),
|
|
33
34
|
url: cama_admin_post_type_post_tags_path(pt.id) }
|
|
34
35
|
end
|
|
@@ -36,58 +37,93 @@ module CamaleonCms
|
|
|
36
37
|
items << { icon: pt.get_option('icon', 'copy'), title: pt.the_title, url: '', items: items_i }
|
|
37
38
|
end
|
|
38
39
|
end
|
|
40
|
+
|
|
39
41
|
if items.present?
|
|
40
|
-
admin_menu_add_menu(
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
admin_menu_add_menu(
|
|
43
|
+
'content',
|
|
44
|
+
{
|
|
45
|
+
icon: 'database', title: t('camaleon_cms.admin.sidebar.contents'), url: '', items: items,
|
|
46
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.content')}' data-position='right' data-wait='600'"
|
|
47
|
+
}
|
|
48
|
+
)
|
|
43
49
|
end
|
|
44
50
|
# end
|
|
45
51
|
|
|
46
|
-
if can? :manage,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
if can? :manage, :media
|
|
53
|
+
admin_menu_add_menu(
|
|
54
|
+
'media',
|
|
55
|
+
{
|
|
56
|
+
icon: 'picture-o', title: t('camaleon_cms.admin.sidebar.media'), url: cama_admin_media_path,
|
|
57
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.media')}' data-position='right'"
|
|
58
|
+
}
|
|
59
|
+
)
|
|
51
60
|
end
|
|
52
|
-
if can? :manage,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
if can? :manage, :comments
|
|
62
|
+
admin_menu_add_menu(
|
|
63
|
+
'comments',
|
|
64
|
+
{
|
|
65
|
+
icon: 'comments', title: t('camaleon_cms.admin.sidebar.comments'), url: cama_admin_comments_path,
|
|
66
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.comments')}' data-position='right'"
|
|
67
|
+
}
|
|
68
|
+
)
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
items = []
|
|
60
|
-
if can? :manage,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
if can? :manage, :themes
|
|
73
|
+
items << {
|
|
74
|
+
icon: 'desktop', title: t('camaleon_cms.admin.sidebar.themes'), url: cama_admin_appearances_themes_path,
|
|
75
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.themes')}' data-position='right'"
|
|
76
|
+
}
|
|
64
77
|
end
|
|
65
|
-
if can? :manage,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
if can? :manage, :widgets
|
|
79
|
+
items << {
|
|
80
|
+
icon: 'archive', title: t('camaleon_cms.admin.sidebar.widgets'),
|
|
81
|
+
url: cama_admin_appearances_widgets_main_index_path,
|
|
82
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.widgets')}' data-position='right'"
|
|
83
|
+
}
|
|
69
84
|
end
|
|
70
|
-
if can? :manage,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
85
|
+
if can? :manage, :nav_menu
|
|
86
|
+
intro_menus_data =
|
|
87
|
+
t('camaleon_cms.admin.intro.menus', image: view_context.asset_path('camaleon_cms/admin/intro/menus.png'))
|
|
88
|
+
items << {
|
|
89
|
+
icon: 'list', title: t('camaleon_cms.admin.sidebar.menus'), url: cama_admin_appearances_nav_menus_path,
|
|
90
|
+
datas: "data-intro='#{intro_menus_data}' data-position='right'"
|
|
91
|
+
}
|
|
74
92
|
end
|
|
75
|
-
if can? :manage,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
if can? :manage, :shortcodes
|
|
94
|
+
items << {
|
|
95
|
+
icon: 'code', title: t('camaleon_cms.admin.sidebar.shortcodes', default: 'Shortcodes'),
|
|
96
|
+
url: cama_admin_settings_shortcodes_path,
|
|
97
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.shortcodes')}' data-position='right'"
|
|
98
|
+
}
|
|
79
99
|
end
|
|
80
100
|
if items.present?
|
|
81
|
-
admin_menu_add_menu(
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
admin_menu_add_menu(
|
|
102
|
+
'appearance',
|
|
103
|
+
{
|
|
104
|
+
icon: 'paint-brush', title: t('camaleon_cms.admin.sidebar.appearance'), url: '', items: items,
|
|
105
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.appearance')}' data-position='right' data-wait='500'"
|
|
106
|
+
}
|
|
107
|
+
)
|
|
84
108
|
end
|
|
85
109
|
|
|
86
|
-
if can? :manage,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
if can? :manage, :plugins
|
|
111
|
+
plugin_count = PluginRoutes.all_plugins.count do |plugin|
|
|
112
|
+
!(plugin[:domain].present? && !plugin[:domain].split(',').include?(current_site.the_slug))
|
|
113
|
+
end
|
|
114
|
+
admin_menu_add_menu(
|
|
115
|
+
'plugins',
|
|
116
|
+
{
|
|
117
|
+
icon: 'plug',
|
|
118
|
+
title: safe_join([
|
|
119
|
+
t('camaleon_cms.admin.sidebar.plugins'),
|
|
120
|
+
' ',
|
|
121
|
+
content_tag(:small, plugin_count, class: 'label label-primary')
|
|
122
|
+
]),
|
|
123
|
+
url: cama_admin_plugins_path,
|
|
124
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.plugins')}' data-position='right'"
|
|
125
|
+
}
|
|
126
|
+
)
|
|
91
127
|
end
|
|
92
128
|
|
|
93
129
|
if can? :manage, :users
|
|
@@ -95,117 +131,154 @@ module CamaleonCms
|
|
|
95
131
|
items << { icon: 'list', title: t('camaleon_cms.admin.users.all_users'), url: cama_admin_users_path }
|
|
96
132
|
items << { icon: 'plus', title: t('camaleon_cms.admin.users.add_user'), url: new_cama_admin_user_path }
|
|
97
133
|
items << { icon: 'group', title: t('camaleon_cms.admin.users.user_roles'), url: cama_admin_user_roles_path }
|
|
98
|
-
admin_menu_add_menu(
|
|
99
|
-
|
|
100
|
-
|
|
134
|
+
admin_menu_add_menu(
|
|
135
|
+
'users',
|
|
136
|
+
{
|
|
137
|
+
icon: 'users', title: t('camaleon_cms.admin.sidebar.users'), url: '', items: items,
|
|
138
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.users')}' data-position='right' data-wait='500'"
|
|
139
|
+
}
|
|
140
|
+
)
|
|
101
141
|
end
|
|
102
142
|
|
|
103
143
|
items = []
|
|
104
144
|
if can? :manage, :settings
|
|
105
|
-
items << {
|
|
106
|
-
|
|
145
|
+
items << {
|
|
146
|
+
icon: 'desktop', title: t('camaleon_cms.admin.sidebar.general_site'),
|
|
147
|
+
url: cama_admin_settings_site_path,
|
|
148
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.gral_site')}' data-position='right'"
|
|
149
|
+
}
|
|
107
150
|
if current_site.manage_sites?
|
|
108
|
-
items << {
|
|
109
|
-
|
|
151
|
+
items << {
|
|
152
|
+
icon: 'cog', title: t('camaleon_cms.admin.sidebar.sites'),
|
|
153
|
+
url: cama_admin_settings_sites_path,
|
|
154
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.sites')}' data-position='right'"
|
|
155
|
+
}
|
|
110
156
|
end
|
|
111
|
-
items << {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
157
|
+
items << {
|
|
158
|
+
icon: 'files-o', title: t('camaleon_cms.admin.sidebar.content_groups'),
|
|
159
|
+
url: cama_admin_settings_post_types_path,
|
|
160
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.post_type')}' data-position='right'"
|
|
161
|
+
}
|
|
162
|
+
items << {
|
|
163
|
+
icon: 'cog', title: t('camaleon_cms.admin.sidebar.custom_fields'),
|
|
164
|
+
url: cama_admin_settings_custom_fields_path,
|
|
165
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.custom_fields')}' data-position='right'"
|
|
166
|
+
}
|
|
167
|
+
items << {
|
|
168
|
+
icon: 'language', title: t('camaleon_cms.admin.sidebar.languages'),
|
|
169
|
+
url: cama_admin_settings_languages_path,
|
|
170
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.languages')}' data-position='right'"
|
|
171
|
+
}
|
|
117
172
|
end
|
|
118
173
|
|
|
119
|
-
if can? :manage,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
174
|
+
if can? :manage, :theme_settings
|
|
175
|
+
items << {
|
|
176
|
+
icon: 'windows', title: t('camaleon_cms.admin.settings.theme_setting', default: 'Theme Settings'),
|
|
177
|
+
url: cama_admin_settings_theme_path
|
|
178
|
+
}
|
|
123
179
|
end
|
|
124
|
-
return
|
|
180
|
+
return if items.blank?
|
|
125
181
|
|
|
126
|
-
admin_menu_add_menu(
|
|
127
|
-
|
|
128
|
-
|
|
182
|
+
admin_menu_add_menu(
|
|
183
|
+
'settings',
|
|
184
|
+
{
|
|
185
|
+
icon: 'cogs', title: t('camaleon_cms.admin.sidebar.settings'), url: '', items: items,
|
|
186
|
+
datas: "data-intro='#{t('camaleon_cms.admin.intro.settings')}' data-position='right' data-wait='500'"
|
|
187
|
+
}
|
|
188
|
+
)
|
|
129
189
|
end
|
|
130
190
|
|
|
131
|
-
# add menu item to
|
|
132
|
-
# key: key for menu
|
|
133
|
-
# menu: is hash like this: {icon: "dashboard", title: "My title", url: my_path, items: [sub menus]}
|
|
191
|
+
# add a menu item to the menu at the end
|
|
192
|
+
# key: key for the menu
|
|
193
|
+
# menu: is hash like this: { icon: "dashboard", title: "My title", url: my_path, items: [sub menus] }
|
|
134
194
|
# - icon: font-awesome icon (it is already included "fa fa-")
|
|
135
195
|
# - title: title for the menu
|
|
136
196
|
# - url: url for the menu
|
|
137
|
-
# - items: is
|
|
138
|
-
# - datas:
|
|
197
|
+
# - items: is a recursive array of the menus without a key
|
|
198
|
+
# - datas: HTML data text for this menu item
|
|
139
199
|
def admin_menu_add_menu(key, menu)
|
|
140
|
-
|
|
200
|
+
CurrentRequest.admin_menu_items ||= {}
|
|
201
|
+
CurrentRequest.admin_menu_items[key] = menu
|
|
141
202
|
end
|
|
142
203
|
|
|
143
|
-
# append sub menu to menu with key = key
|
|
204
|
+
# append sub menu to menu with a key = key
|
|
144
205
|
# menu: is hash like this: {icon: "dashboard", title: "My title", url: my_path, items: [sub menus]}
|
|
145
206
|
def admin_menu_append_menu_item(key, menu)
|
|
146
|
-
|
|
207
|
+
CurrentRequest.admin_menu_items ||= {}
|
|
208
|
+
return if CurrentRequest.admin_menu_items[key].blank?
|
|
147
209
|
|
|
148
|
-
|
|
149
|
-
|
|
210
|
+
CurrentRequest.admin_menu_items[key][:items] = [] unless CurrentRequest.admin_menu_items[key].key?(:items)
|
|
211
|
+
CurrentRequest.admin_menu_items[key][:items] << menu
|
|
150
212
|
end
|
|
151
213
|
|
|
152
|
-
# prepend
|
|
153
|
-
# menu: is hash like this: {icon: "dashboard", title: "My title", url: my_path, items: [sub menus]}
|
|
214
|
+
# prepend submenu to menu with key = key
|
|
215
|
+
# menu: is hash like this: { icon: "dashboard", title: "My title", url: my_path, items: [sub menus] }
|
|
154
216
|
def admin_menu_prepend_menu_item(key, menu)
|
|
155
|
-
|
|
217
|
+
CurrentRequest.admin_menu_items ||= {}
|
|
218
|
+
return if CurrentRequest.admin_menu_items[key].blank?
|
|
156
219
|
|
|
157
|
-
|
|
158
|
-
|
|
220
|
+
CurrentRequest.admin_menu_items[key][:items] = [] unless CurrentRequest.admin_menu_items[key].key?(:items)
|
|
221
|
+
CurrentRequest.admin_menu_items[key][:items] = [menu] + CurrentRequest.admin_menu_items[key][:items]
|
|
159
222
|
end
|
|
160
223
|
|
|
161
|
-
# add menu before menu with key = key_target
|
|
224
|
+
# add the menu before the menu with key = key_target
|
|
162
225
|
# key_menu: key for menu
|
|
163
|
-
# menu: is hash like this: {icon: "dashboard", title: "My title", url: my_path, items: [sub menus]}
|
|
226
|
+
# menu: is hash like this: { icon: "dashboard", title: "My title", url: my_path, items: [sub menus] }
|
|
164
227
|
def admin_menu_insert_menu_before(key_target, key_menu, menu)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
228
|
+
CurrentRequest.admin_menu_items ||= {}
|
|
229
|
+
res = CurrentRequest.admin_menu_items.each_with_object({}) do |(key, val), hsh|
|
|
230
|
+
hsh[key_menu] = menu if key == key_target
|
|
231
|
+
hsh[key] = val
|
|
169
232
|
end
|
|
170
|
-
@_admin_menus
|
|
233
|
+
CurrentRequest.admin_menu_items.replace(res) # mutate in place so @_admin_menus stays a live alias (M19)
|
|
171
234
|
end
|
|
172
235
|
|
|
173
236
|
# add menu after menu with key = key_target
|
|
174
237
|
# key_menu: key for menu
|
|
175
238
|
# menu: is hash like this: {icon: "dashboard", title: "My title", url: my_path, items: [sub menus]}
|
|
176
239
|
def admin_menu_insert_menu_after(key_target, key_menu, menu)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
240
|
+
CurrentRequest.admin_menu_items ||= {}
|
|
241
|
+
res = CurrentRequest.admin_menu_items.each_with_object({}) do |(key, val), hsh|
|
|
242
|
+
hsh[key] = val
|
|
243
|
+
hsh[key_menu] = menu if key == key_target
|
|
181
244
|
end
|
|
182
|
-
@_admin_menus
|
|
245
|
+
CurrentRequest.admin_menu_items.replace(res) # mutate in place so @_admin_menus stays a live alias (M19)
|
|
183
246
|
end
|
|
184
247
|
|
|
185
248
|
# draw admin menu as html
|
|
186
249
|
def admin_menu_draw
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
menus = _get_url_current
|
|
190
|
-
menus.
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
250
|
+
CurrentRequest.admin_menu_items ||= {}
|
|
251
|
+
menu_parents = []
|
|
252
|
+
menus = _get_url_current(CurrentRequest.admin_menu_items, menu_parents)
|
|
253
|
+
safe_join(menus.map do |menu|
|
|
254
|
+
css_class = +''
|
|
255
|
+
css_class << 'treeview ' if menu.key?(:items)
|
|
256
|
+
css_class << 'active' if is_active_menu(menu[:key], menu_parents)
|
|
257
|
+
css_class.strip!
|
|
258
|
+
data_attrs = parse_datas(menu[:datas])
|
|
259
|
+
content_tag(
|
|
260
|
+
:li, ''.html_safe,
|
|
261
|
+
class: css_class.presence, data: { key: menu[:key] }.merge!(data_attrs.presence || {})
|
|
262
|
+
) do
|
|
263
|
+
safe_join([
|
|
264
|
+
content_tag(:a, href: menu[:url]) do
|
|
265
|
+
safe_join([
|
|
266
|
+
content_tag(:i, nil, class: "fa fa-#{menu[:icon]}"),
|
|
267
|
+
' ',
|
|
268
|
+
content_tag(:span, cama_admin_menu_title(menu[:title])),
|
|
269
|
+
(content_tag(:i, nil, class: 'fa fa-angle-left pull-right') if menu.key?(:items))
|
|
270
|
+
].compact)
|
|
271
|
+
end,
|
|
272
|
+
(_admin_menu_draw(menu[:items], menu_parents) if menu.key?(:items))
|
|
273
|
+
].compact)
|
|
274
|
+
end
|
|
275
|
+
end)
|
|
203
276
|
end
|
|
204
277
|
|
|
205
278
|
private
|
|
206
279
|
|
|
207
|
-
def _get_url_current
|
|
208
|
-
menus =
|
|
280
|
+
def _get_url_current(menus, menu_parents)
|
|
281
|
+
menus = menus.map do |key, menu|
|
|
209
282
|
menu[:key] = key
|
|
210
283
|
menu
|
|
211
284
|
end
|
|
@@ -213,7 +286,7 @@ module CamaleonCms
|
|
|
213
286
|
current_path_array = current_path.split('/')
|
|
214
287
|
a_size = current_path_array.size
|
|
215
288
|
(0..a_size).each do |i|
|
|
216
|
-
resp = _search_in_menus(menus, current_path_array[0..a_size - i].join('/'))
|
|
289
|
+
resp = _search_in_menus(menus, current_path_array[0..a_size - i].join('/'), 0, menu_parents)
|
|
217
290
|
bool = resp[:bool]
|
|
218
291
|
menus = resp[:menus]
|
|
219
292
|
break if bool
|
|
@@ -221,11 +294,11 @@ module CamaleonCms
|
|
|
221
294
|
menus
|
|
222
295
|
end
|
|
223
296
|
|
|
224
|
-
def is_active_menu(key)
|
|
225
|
-
|
|
297
|
+
def is_active_menu(key, menu_parents)
|
|
298
|
+
menu_parents.map { |item| item[:key] == key }.include?(true)
|
|
226
299
|
end
|
|
227
300
|
|
|
228
|
-
def _search_in_menus(menus, _url, parent_index = 0)
|
|
301
|
+
def _search_in_menus(menus, _url, parent_index = 0, menu_parents = [])
|
|
229
302
|
bool = false
|
|
230
303
|
menus.each_with_index do |menu, _index_menu|
|
|
231
304
|
menu[:key] = "#{parent_index}__#{rand(999...99_999)}" if menu[:key].nil?
|
|
@@ -235,38 +308,75 @@ module CamaleonCms
|
|
|
235
308
|
bool = url_path.to_s == _url.to_s && url_path.present?
|
|
236
309
|
# params compare
|
|
237
310
|
if url_query.present?
|
|
238
|
-
|
|
311
|
+
menu_params = Rack::Utils.parse_nested_query(url_query.to_s)
|
|
312
|
+
current_params = Rack::Utils.parse_nested_query(URI(site_current_url).query.to_s)
|
|
313
|
+
bool &&= menu_params == current_params
|
|
239
314
|
end
|
|
240
315
|
if menu.key?(:items)
|
|
241
|
-
resp = _search_in_menus(menu[:items], _url, parent_index + 1)
|
|
316
|
+
resp = _search_in_menus(menu[:items], _url, parent_index + 1, menu_parents)
|
|
242
317
|
bool ||= resp[:bool]
|
|
243
318
|
menu[:items] = resp[:menus]
|
|
244
319
|
end
|
|
245
320
|
if bool
|
|
246
|
-
|
|
321
|
+
menu_parents[parent_index] = { url: menu[:url], title: menu[:title], key: menu[:key] }
|
|
247
322
|
break
|
|
248
323
|
end
|
|
249
324
|
end
|
|
250
325
|
{ menus: menus, bool: bool }
|
|
251
326
|
end
|
|
252
327
|
|
|
253
|
-
def _admin_menu_draw(items)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
328
|
+
def _admin_menu_draw(items, menu_parents)
|
|
329
|
+
return ''.html_safe if items.blank?
|
|
330
|
+
|
|
331
|
+
content_tag(:ul, class: 'treeview-menu') do
|
|
332
|
+
safe_join(items.each_with_index.map do |item, index|
|
|
333
|
+
css_class = +"item_#{index + 1} "
|
|
334
|
+
css_class << 'xn-openable ' if item.key?(:items)
|
|
335
|
+
css_class << 'active ' if is_active_menu(item[:key], menu_parents)
|
|
336
|
+
css_class.strip!
|
|
337
|
+
data_attrs = parse_datas(item[:datas])
|
|
338
|
+
content_tag(
|
|
339
|
+
:li, ''.html_safe,
|
|
340
|
+
class: css_class.presence,
|
|
341
|
+
data: { key: item[:key] }.merge!(data_attrs.presence || {})
|
|
342
|
+
) do
|
|
343
|
+
safe_join([
|
|
344
|
+
content_tag(:a, href: item[:url]) do
|
|
345
|
+
safe_join([
|
|
346
|
+
content_tag(:i, nil, class: "fa fa-#{item[:icon]}"),
|
|
347
|
+
' ',
|
|
348
|
+
cama_admin_menu_title(item[:title]),
|
|
349
|
+
(content_tag(:i, nil, class: 'fa fa-angle-left pull-right') if item.key?(:items))
|
|
350
|
+
].compact)
|
|
351
|
+
end,
|
|
352
|
+
(item.key?(:items) ? _admin_menu_draw(item[:items], menu_parents) : nil)
|
|
353
|
+
].compact)
|
|
354
|
+
end
|
|
355
|
+
end)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# Menu titles may carry inline formatting (e.g. camaleon-ecommerce's count badge). Core builds its
|
|
360
|
+
# titles as SafeBuffers via safe_join/content_tag and those pass through untouched; a plain-String
|
|
361
|
+
# title from a plugin is sanitized to a safe inline subset — the badge renders, scripts and event
|
|
362
|
+
# handlers are stripped — rather than escaped whole. Regression M22.
|
|
363
|
+
def cama_admin_menu_title(title)
|
|
364
|
+
return title if title.is_a?(ActiveSupport::SafeBuffer)
|
|
365
|
+
|
|
366
|
+
sanitize(title.to_s, tags: %w[span small i b strong em], attributes: %w[class])
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def parse_datas(datas_string)
|
|
370
|
+
return {} if datas_string.blank?
|
|
371
|
+
|
|
372
|
+
result = {}
|
|
373
|
+
# Match single- or double-quoted values so a value may contain the other quote character. The
|
|
374
|
+
# old /['"]([^'"]*)['"]/ stopped at the first quote of either kind, truncating data-intro
|
|
375
|
+
# strings that carry HTML (e.g. the Menus tooltip's <img ... style="...">). Regression M22.
|
|
376
|
+
datas_string.scan(/data-([\w-]+)=(?:'([^']*)'|"([^"]*)")/).each do |key, single, double|
|
|
377
|
+
result[key.to_sym] = single || double
|
|
267
378
|
end
|
|
268
|
-
|
|
269
|
-
res.join
|
|
379
|
+
result
|
|
270
380
|
end
|
|
271
381
|
end
|
|
272
382
|
end
|