alchemy_cms 6.1.10 → 7.0.0.pre.a
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/.github/workflows/ci.yml +0 -3
- data/.gitignore +1 -6
- data/CHANGELOG.md +19 -44
- data/Gemfile +1 -1
- data/Rakefile +14 -9
- data/alchemy_cms.gemspec +2 -3
- data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +18 -32
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +27 -29
- data/app/assets/stylesheets/alchemy/elements.scss +16 -35
- data/app/assets/stylesheets/alchemy/forms.scss +0 -4
- data/app/assets/stylesheets/alchemy/node-select.scss +2 -2
- data/app/controllers/alchemy/admin/attachments_controller.rb +0 -1
- data/app/controllers/alchemy/admin/elements_controller.rb +7 -32
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pictures_controller.rb +1 -1
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -18
- data/app/controllers/alchemy/api/elements_controller.rb +0 -2
- data/app/controllers/alchemy/api/pages_controller.rb +8 -4
- data/app/controllers/alchemy/messages_controller.rb +9 -9
- data/app/controllers/alchemy/pages_controller.rb +23 -18
- data/app/decorators/alchemy/element_editor.rb +10 -30
- data/app/helpers/alchemy/admin/elements_helper.rb +0 -2
- data/app/helpers/alchemy/elements_block_helper.rb +5 -42
- data/app/helpers/alchemy/elements_helper.rb +3 -11
- data/app/helpers/alchemy/pages_helper.rb +0 -4
- data/app/models/alchemy/attachment.rb +6 -3
- data/app/models/alchemy/base_record.rb +2 -0
- data/app/models/alchemy/eager_loading.rb +0 -1
- data/app/models/alchemy/element/element_ingredients.rb +1 -8
- data/app/models/alchemy/element/presenters.rb +9 -25
- data/app/models/alchemy/element.rb +2 -18
- data/app/models/alchemy/ingredient.rb +17 -6
- data/app/models/alchemy/ingredients/audio.rb +2 -0
- data/app/models/alchemy/ingredients/datetime.rb +3 -1
- data/app/models/alchemy/ingredients/file.rb +7 -0
- data/app/models/alchemy/ingredients/headline.rb +6 -0
- data/app/models/alchemy/ingredients/link.rb +2 -0
- data/app/models/alchemy/ingredients/node.rb +2 -0
- data/app/models/alchemy/ingredients/page.rb +2 -0
- data/app/models/alchemy/ingredients/picture.rb +11 -0
- data/app/models/alchemy/ingredients/richtext.rb +6 -0
- data/app/models/alchemy/ingredients/select.rb +1 -0
- data/app/models/alchemy/ingredients/text.rb +8 -0
- data/app/models/alchemy/ingredients/video.rb +2 -0
- data/app/models/alchemy/node.rb +9 -6
- data/app/models/alchemy/page/page_elements.rb +5 -26
- data/app/models/alchemy/page/page_layouts.rb +0 -14
- data/app/models/alchemy/page/page_natures.rb +0 -10
- data/app/models/alchemy/page.rb +0 -10
- data/app/models/alchemy/picture/transformations.rb +0 -30
- data/app/models/alchemy/picture/url.rb +1 -1
- data/app/models/alchemy/picture.rb +14 -13
- data/app/models/alchemy/picture_thumb/create.rb +7 -18
- data/app/models/alchemy/picture_thumb/file_store.rb +33 -0
- data/app/models/alchemy/picture_thumb.rb +10 -10
- data/app/models/concerns/alchemy/picture_thumbnails.rb +2 -6
- data/app/serializers/alchemy/element_serializer.rb +1 -6
- data/app/services/alchemy/delete_elements.rb +1 -7
- data/app/services/alchemy/duplicate_element.rb +1 -6
- data/app/views/alchemy/admin/elements/_element.html.erb +5 -22
- data/app/views/alchemy/admin/elements/create.js.erb +1 -1
- data/app/views/alchemy/admin/elements/fold.js.erb +2 -2
- data/app/views/alchemy/admin/elements/order.js.erb +1 -1
- data/app/views/alchemy/admin/elements/update.js.erb +1 -2
- data/app/views/alchemy/admin/pages/_external_link.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_file_link.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_table.html.erb +0 -6
- data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +3 -6
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -3
- data/app/views/alchemy/admin/pictures/_infos.html.erb +4 -6
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
- data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_headline_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_html_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_node_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/_picture_editor.html.erb +4 -4
- data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -2
- data/app/views/alchemy/ingredients/_text_editor.html.erb +1 -1
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +3 -3
- data/app/views/alchemy/pages/_meta_data.html.erb +0 -1
- data/app/views/layouts/alchemy/admin.html.erb +5 -1
- data/config/alchemy/config.yml +6 -6
- data/config/brakeman.ignore +56 -57
- data/config/locales/alchemy.en.yml +99 -113
- data/config/routes.rb +1 -16
- data/db/migrate/20230121212637_alchemy_six_point_one.rb +248 -0
- data/lib/alchemy/cache_digests/template_tracker.rb +6 -7
- data/lib/alchemy/config.rb +2 -2
- data/lib/alchemy/deprecation.rb +1 -1
- data/lib/alchemy/errors.rb +0 -11
- data/lib/alchemy/hints.rb +10 -10
- data/lib/alchemy/permissions.rb +4 -17
- data/lib/alchemy/routing_constraints.rb +3 -3
- data/lib/alchemy/searchable_resource.rb +38 -0
- data/lib/alchemy/seeder.rb +2 -8
- data/lib/alchemy/tasks/tidy.rb +0 -38
- data/lib/alchemy/test_support/capybara_helpers.rb +69 -0
- data/lib/alchemy/test_support/factories/element_factory.rb +0 -6
- data/lib/alchemy/test_support/factories/ingredient_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/page_factory.rb +4 -2
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +0 -20
- data/lib/alchemy/test_support/shared_dom_ids_examples.rb +1 -1
- data/lib/alchemy/test_support/shared_ingredient_examples.rb +1 -1
- data/lib/alchemy/tinymce.rb +1 -18
- data/lib/alchemy/upgrader/seven_point_zero.rb +45 -0
- data/lib/alchemy/upgrader/tasks/.keep +0 -0
- data/lib/alchemy/upgrader.rb +8 -3
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy.rb +0 -19
- data/lib/alchemy_cms.rb +1 -2
- data/lib/generators/alchemy/elements/elements_generator.rb +0 -1
- data/lib/generators/alchemy/elements/templates/view.html.erb +1 -10
- data/lib/generators/alchemy/elements/templates/view.html.haml +1 -9
- data/lib/generators/alchemy/elements/templates/view.html.slim +1 -9
- data/lib/generators/alchemy/install/files/alchemy.en.yml +7 -8
- data/lib/generators/alchemy/install/files/application.html.erb +1 -1
- data/lib/generators/alchemy/install/install_generator.rb +18 -34
- data/lib/generators/alchemy/install/templates/elements.yml.tt +12 -12
- data/lib/non_stupid_digest_assets.rb +1 -1
- data/lib/tasks/alchemy/thumbnails.rake +2 -21
- data/lib/tasks/alchemy/tidy.rake +1 -12
- data/lib/tasks/alchemy/upgrade.rake +10 -47
- data/package/dist/admin.js +16 -0
- data/package/dist/admin.js.map +7 -0
- data/package.json +5 -3
- metadata +18 -147
- data/app/controllers/alchemy/admin/contents_controller.rb +0 -21
- data/app/controllers/alchemy/admin/essence_audios_controller.rb +0 -30
- data/app/controllers/alchemy/admin/essence_files_controller.rb +0 -31
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +0 -43
- data/app/controllers/alchemy/admin/essence_videos_controller.rb +0 -34
- data/app/controllers/alchemy/api/contents_controller.rb +0 -52
- data/app/decorators/alchemy/content_editor.rb +0 -119
- data/app/helpers/alchemy/admin/contents_helper.rb +0 -42
- data/app/helpers/alchemy/admin/essences_helper.rb +0 -31
- data/app/models/alchemy/content/factory.rb +0 -143
- data/app/models/alchemy/content.rb +0 -247
- data/app/models/alchemy/element/element_contents.rb +0 -200
- data/app/models/alchemy/element/element_essences.rb +0 -133
- data/app/models/alchemy/essence_audio.rb +0 -13
- data/app/models/alchemy/essence_boolean.rb +0 -20
- data/app/models/alchemy/essence_date.rb +0 -25
- data/app/models/alchemy/essence_file.rb +0 -49
- data/app/models/alchemy/essence_headline.rb +0 -41
- data/app/models/alchemy/essence_html.rb +0 -23
- data/app/models/alchemy/essence_link.rb +0 -21
- data/app/models/alchemy/essence_node.rb +0 -19
- data/app/models/alchemy/essence_page.rb +0 -17
- data/app/models/alchemy/essence_picture.rb +0 -67
- data/app/models/alchemy/essence_picture_view.rb +0 -90
- data/app/models/alchemy/essence_richtext.rb +0 -44
- data/app/models/alchemy/essence_select.rb +0 -19
- data/app/models/alchemy/essence_text.rb +0 -23
- data/app/models/alchemy/essence_video.rb +0 -13
- data/app/serializers/alchemy/content_serializer.rb +0 -17
- data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -10
- data/app/serializers/alchemy/essence_date_serializer.rb +0 -10
- data/app/serializers/alchemy/essence_file_serializer.rb +0 -13
- data/app/serializers/alchemy/essence_html_serializer.rb +0 -10
- data/app/serializers/alchemy/essence_link_serializer.rb +0 -13
- data/app/serializers/alchemy/essence_picture_serializer.rb +0 -28
- data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -11
- data/app/serializers/alchemy/essence_select_serializer.rb +0 -10
- data/app/serializers/alchemy/essence_text_serializer.rb +0 -22
- data/app/views/alchemy/admin/contents/create.js.erb +0 -21
- data/app/views/alchemy/admin/essence_audios/edit.html.erb +0 -7
- data/app/views/alchemy/admin/essence_files/edit.html.erb +0 -21
- data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -5
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +0 -30
- data/app/views/alchemy/admin/essence_pictures/save_link.js.erb +0 -3
- data/app/views/alchemy/admin/essence_pictures/update.js.erb +0 -8
- data/app/views/alchemy/admin/essence_videos/edit.html.erb +0 -12
- data/app/views/alchemy/essences/_essence_audio_editor.html.erb +0 -4
- data/app/views/alchemy/essences/_essence_audio_view.html.erb +0 -15
- data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +0 -11
- data/app/views/alchemy/essences/_essence_boolean_view.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_date_editor.html.erb +0 -16
- data/app/views/alchemy/essences/_essence_date_view.html.erb +0 -10
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +0 -54
- data/app/views/alchemy/essences/_essence_file_view.html.erb +0 -18
- data/app/views/alchemy/essences/_essence_headline_editor.html.erb +0 -36
- data/app/views/alchemy/essences/_essence_headline_view.html.erb +0 -10
- data/app/views/alchemy/essences/_essence_html_editor.html.erb +0 -10
- data/app/views/alchemy/essences/_essence_html_view.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +0 -30
- data/app/views/alchemy/essences/_essence_link_view.html.erb +0 -10
- data/app/views/alchemy/essences/_essence_node_editor.html.erb +0 -27
- data/app/views/alchemy/essences/_essence_node_view.html.erb +0 -1
- data/app/views/alchemy/essences/_essence_page_editor.html.erb +0 -26
- data/app/views/alchemy/essences/_essence_page_view.html.erb +0 -5
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +0 -59
- data/app/views/alchemy/essences/_essence_picture_view.html.erb +0 -6
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +0 -14
- data/app/views/alchemy/essences/_essence_richtext_view.html.erb +0 -4
- data/app/views/alchemy/essences/_essence_select_editor.html.erb +0 -28
- data/app/views/alchemy/essences/_essence_select_view.html.erb +0 -2
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +0 -29
- data/app/views/alchemy/essences/_essence_text_view.html.erb +0 -17
- data/app/views/alchemy/essences/_essence_video_editor.html.erb +0 -4
- data/app/views/alchemy/essences/_essence_video_view.html.erb +0 -19
- data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +0 -59
- data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +0 -20
- data/app/views/alchemy/pages/show.rss.builder +0 -21
- data/db/migrate/20200226213334_alchemy_four_point_four.rb +0 -313
- data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +0 -11
- data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +0 -28
- data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +0 -8
- data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +0 -27
- data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +0 -6
- data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +0 -24
- data/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +0 -22
- data/db/migrate/20200907111332_remove_tri_state_booleans.rb +0 -33
- data/db/migrate/20201207131309_create_page_versions.rb +0 -19
- data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +0 -76
- data/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +0 -10
- data/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +0 -7
- data/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +0 -12
- data/db/migrate/20210506135919_create_essence_audios.rb +0 -19
- data/db/migrate/20210506140258_create_essence_videos.rb +0 -23
- data/db/migrate/20210508091432_create_alchemy_ingredients.rb +0 -22
- data/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb +0 -13
- data/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb +0 -9
- data/lib/alchemy/essence.rb +0 -250
- data/lib/alchemy/tasks/usage.rb +0 -34
- data/lib/alchemy/test_support/essence_shared_examples.rb +0 -271
- data/lib/alchemy/test_support/factories/content_factory.rb +0 -20
- data/lib/alchemy/test_support/factories/essence_audio_factory.rb +0 -7
- data/lib/alchemy/test_support/factories/essence_file_factory.rb +0 -7
- data/lib/alchemy/test_support/factories/essence_page_factory.rb +0 -7
- data/lib/alchemy/test_support/factories/essence_picture_factory.rb +0 -11
- data/lib/alchemy/test_support/factories/essence_text_factory.rb +0 -7
- data/lib/alchemy/test_support/factories/essence_video_factory.rb +0 -7
- data/lib/alchemy/upgrader/five_point_zero.rb +0 -41
- data/lib/alchemy/upgrader/six_point_zero.rb +0 -21
- data/lib/alchemy/upgrader/tasks/add_page_versions.rb +0 -33
- data/lib/alchemy/upgrader/tasks/element_views_updater.rb +0 -34
- data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +0 -29
- data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +0 -73
- data/lib/generators/alchemy/essence/essence_generator.rb +0 -49
- data/lib/generators/alchemy/essence/templates/editor.html.erb +0 -17
- data/lib/generators/alchemy/essence/templates/view.html.erb +0 -2
- data/lib/generators/alchemy/install/files/babel.config.js +0 -64
- data/lib/tasks/alchemy/usage.rake +0 -44
|
@@ -24,69 +24,32 @@ module Alchemy
|
|
|
24
24
|
# Block-level helper class for element views.
|
|
25
25
|
#
|
|
26
26
|
class ElementViewHelper < BlockHelper
|
|
27
|
-
# Renders one of the element's
|
|
27
|
+
# Renders one of the element's ingredients.
|
|
28
28
|
#
|
|
29
29
|
# If the element uses +ingredients+ it renders the ingredient record.
|
|
30
30
|
#
|
|
31
31
|
def render(name, options = {}, html_options = {})
|
|
32
|
-
renderable = element.ingredient_by_role(name)
|
|
32
|
+
renderable = element.ingredient_by_role(name)
|
|
33
33
|
return if renderable.nil?
|
|
34
34
|
|
|
35
|
-
if Alchemy::DEPRECATED_ESSENCE_CLASSES.include?(renderable.try(:essence)&.class&.name)
|
|
36
|
-
Alchemy::Deprecation.warn(
|
|
37
|
-
"Using a '#{renderable.essence.class.name.demodulize}' content is deprecated. " \
|
|
38
|
-
"Please use a '#{Alchemy::DEPRECATED_ESSENCE_CLASS_MAPPING[renderable.essence.class.name].demodulize}' ingredient instead."
|
|
39
|
-
)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
35
|
helpers.render(renderable, {
|
|
43
36
|
options: options,
|
|
44
37
|
html_options: html_options,
|
|
45
38
|
})
|
|
46
39
|
end
|
|
47
40
|
|
|
48
|
-
# Returns one of the element's contents (ie. essence instances).
|
|
49
|
-
#
|
|
50
|
-
def content(name)
|
|
51
|
-
element.content_by_name(name)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
deprecate content: "Use `ingredient_by_role` instead", deprecator: Alchemy::Deprecation
|
|
55
|
-
|
|
56
|
-
# Returns the ingredient of one of the element's contents.
|
|
57
|
-
#
|
|
58
|
-
# If the element uses +ingredients+ it returns the +value+ of the ingredient record.
|
|
59
|
-
#
|
|
60
|
-
def ingredient(name)
|
|
61
|
-
element.ingredient(name)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
41
|
# Returns the value of one of the element's ingredients.
|
|
65
42
|
#
|
|
66
43
|
def value(name)
|
|
67
44
|
element.value_for(name)
|
|
68
45
|
end
|
|
69
46
|
|
|
70
|
-
# Returns true if the given
|
|
47
|
+
# Returns true if the given ingredient has a value.
|
|
71
48
|
#
|
|
72
49
|
def has?(name)
|
|
73
|
-
|
|
74
|
-
element.has_value_for?(name)
|
|
75
|
-
else
|
|
76
|
-
Alchemy::Deprecation.silence do
|
|
77
|
-
element.has_ingredient?(name)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
50
|
+
element.has_value_for?(name)
|
|
80
51
|
end
|
|
81
52
|
|
|
82
|
-
# Return's the given content's essence.
|
|
83
|
-
#
|
|
84
|
-
def essence(name)
|
|
85
|
-
content(name).try(:essence)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
deprecate essence: "Use `ingredient_by_role` instead", deprecator: Alchemy::Deprecation
|
|
89
|
-
|
|
90
53
|
# Return's the ingredient record by given role.
|
|
91
54
|
#
|
|
92
55
|
def ingredient_by_role(role)
|
|
@@ -129,7 +92,7 @@ module Alchemy
|
|
|
129
92
|
# The HTML tag to be used for the wrapping element.
|
|
130
93
|
# @option options :id (the element's dom_id)
|
|
131
94
|
# The wrapper tag's DOM ID.
|
|
132
|
-
# @option options :class (the element's
|
|
95
|
+
# @option options :class (the element's name)
|
|
133
96
|
# The wrapper tag's DOM class.
|
|
134
97
|
# @option options :tags_formatter
|
|
135
98
|
# A lambda used for formatting the element's tags (see Alchemy::ElementsHelper::element_tags_attributes). Set to +false+ to not include tags in the wrapper element.
|
|
@@ -112,9 +112,9 @@ module Alchemy
|
|
|
112
112
|
#
|
|
113
113
|
# # elements.yml
|
|
114
114
|
# - name: headline
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
115
|
+
# ingredients:
|
|
116
|
+
# - role: text
|
|
117
|
+
# type: Text
|
|
118
118
|
#
|
|
119
119
|
# Then your element view partial has to be named like:
|
|
120
120
|
#
|
|
@@ -166,14 +166,6 @@ module Alchemy
|
|
|
166
166
|
render "alchemy/elements/view_not_found", name: element.name
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
-
# Returns a string for the id attribute of a html element for the given element
|
|
170
|
-
# @deprecated
|
|
171
|
-
def element_dom_id(element)
|
|
172
|
-
element&.dom_id
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
deprecate element_dom_id: "element.dom_id", deprecator: Alchemy::Deprecation
|
|
176
|
-
|
|
177
169
|
# Renders the HTML tag attributes required for preview mode.
|
|
178
170
|
def element_preview_code(element)
|
|
179
171
|
tag_builder.tag_options(element_preview_code_attributes(element))
|
|
@@ -5,10 +5,6 @@ module Alchemy
|
|
|
5
5
|
include Alchemy::BaseHelper
|
|
6
6
|
include Alchemy::ElementsHelper
|
|
7
7
|
|
|
8
|
-
def picture_essence_caption(content)
|
|
9
|
-
content.try(:essence).try(:caption)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
8
|
# Renders links to language root pages of all published languages.
|
|
13
9
|
#
|
|
14
10
|
# @option options linkname [String] ('name')
|
|
@@ -30,9 +30,12 @@ module Alchemy
|
|
|
30
30
|
|
|
31
31
|
stampable stamper_class_name: Alchemy.user_class.name
|
|
32
32
|
|
|
33
|
-
has_many :
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
has_many :file_ingredients,
|
|
34
|
+
class_name: "Alchemy::Ingredients::File",
|
|
35
|
+
foreign_key: "related_object_id",
|
|
36
|
+
inverse_of: :related_object
|
|
37
|
+
|
|
38
|
+
has_many :elements, through: :file_ingredients
|
|
36
39
|
has_many :pages, through: :elements
|
|
37
40
|
|
|
38
41
|
scope :by_file_type, ->(file_type) { where(file_mime_type: file_type) }
|
|
@@ -37,13 +37,6 @@ module Alchemy
|
|
|
37
37
|
ingredients_by_type(type).first
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
# All ingredients from element by given role.
|
|
41
|
-
def ingredients_by_role(role)
|
|
42
|
-
ingredients.select do |ingredient|
|
|
43
|
-
ingredient.role == Ingredient.normalize_type(role)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
40
|
# All ingredients from element by given type.
|
|
48
41
|
def ingredients_by_type(type)
|
|
49
42
|
ingredients.select do |ingredient|
|
|
@@ -133,7 +126,7 @@ module Alchemy
|
|
|
133
126
|
# == Error message translation fallbacks
|
|
134
127
|
#
|
|
135
128
|
# In order to not translate every single ingredient for every element
|
|
136
|
-
# you can provide default error messages per
|
|
129
|
+
# you can provide default error messages per ingredient role:
|
|
137
130
|
#
|
|
138
131
|
# === Example
|
|
139
132
|
#
|
|
@@ -38,16 +38,15 @@ module Alchemy
|
|
|
38
38
|
|
|
39
39
|
# Returns a preview text for element.
|
|
40
40
|
#
|
|
41
|
-
# It's taken from the first
|
|
41
|
+
# It's taken from the first Ingredient found in the +elements.yml+ definition file.
|
|
42
42
|
#
|
|
43
|
-
# You can flag a
|
|
43
|
+
# You can flag a Ingredient as +as_element_title+ to take this as preview.
|
|
44
44
|
#
|
|
45
45
|
# @param maxlength [Fixnum] (60)
|
|
46
46
|
# Length of characters after the text will be cut off.
|
|
47
47
|
#
|
|
48
48
|
def preview_text(maxlength = 60)
|
|
49
49
|
preview_text_from_preview_ingredient(maxlength) ||
|
|
50
|
-
preview_text_from_preview_content(maxlength) ||
|
|
51
50
|
preview_text_from_nested_elements(maxlength)
|
|
52
51
|
end
|
|
53
52
|
|
|
@@ -61,14 +60,14 @@ module Alchemy
|
|
|
61
60
|
#
|
|
62
61
|
# - name: funky_element
|
|
63
62
|
# display_name: Funky Element
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
63
|
+
# ingredients:
|
|
64
|
+
# - role: headline
|
|
65
|
+
# type: Text
|
|
66
|
+
# - role: text
|
|
67
|
+
# type: Richtext
|
|
68
|
+
# as_element_title: true
|
|
70
69
|
#
|
|
71
|
-
# With "I want to tell you a funky story" as stripped_body for the
|
|
70
|
+
# With "I want to tell you a funky story" as stripped_body for the Richtext ingredient produces:
|
|
72
71
|
#
|
|
73
72
|
# Funky Element: I want to tell ...
|
|
74
73
|
#
|
|
@@ -85,17 +84,6 @@ module Alchemy
|
|
|
85
84
|
self.class.dom_id_class.new(self).call
|
|
86
85
|
end
|
|
87
86
|
|
|
88
|
-
# The content that's used for element's preview text.
|
|
89
|
-
#
|
|
90
|
-
# It tries to find one of element's contents that is defined +as_element_title+.
|
|
91
|
-
# Takes element's first content if no content is defined +as_element_title+.
|
|
92
|
-
#
|
|
93
|
-
# @return (Alchemy::Content)
|
|
94
|
-
#
|
|
95
|
-
def preview_content
|
|
96
|
-
@_preview_content ||= contents.detect(&:preview_content?) || contents.first
|
|
97
|
-
end
|
|
98
|
-
|
|
99
87
|
# The ingredient that's used for element's preview text.
|
|
100
88
|
#
|
|
101
89
|
# It tries to find one of element's ingredients that is defined +as_element_title+.
|
|
@@ -115,10 +103,6 @@ module Alchemy
|
|
|
115
103
|
all_nested_elements.first.preview_text(maxlength)
|
|
116
104
|
end
|
|
117
105
|
|
|
118
|
-
def preview_text_from_preview_content(maxlength)
|
|
119
|
-
preview_content.try!(:preview_text, maxlength)
|
|
120
|
-
end
|
|
121
|
-
|
|
122
106
|
def preview_text_from_preview_ingredient(maxlength)
|
|
123
107
|
preview_ingredient&.preview_text(maxlength)
|
|
124
108
|
end
|
|
@@ -21,10 +21,7 @@
|
|
|
21
21
|
#
|
|
22
22
|
|
|
23
23
|
require_dependency "alchemy/element/definitions"
|
|
24
|
-
require_dependency "alchemy/element/dom_id"
|
|
25
|
-
require_dependency "alchemy/element/element_contents"
|
|
26
24
|
require_dependency "alchemy/element/element_ingredients"
|
|
27
|
-
require_dependency "alchemy/element/element_essences"
|
|
28
25
|
require_dependency "alchemy/element/presenters"
|
|
29
26
|
|
|
30
27
|
module Alchemy
|
|
@@ -39,14 +36,12 @@ module Alchemy
|
|
|
39
36
|
"amount",
|
|
40
37
|
"autogenerate",
|
|
41
38
|
"nestable_elements",
|
|
42
|
-
"contents",
|
|
43
39
|
"hint",
|
|
44
40
|
"ingredients",
|
|
45
41
|
"taggable",
|
|
46
42
|
"compact",
|
|
47
43
|
"message",
|
|
48
44
|
"deprecated",
|
|
49
|
-
"warning",
|
|
50
45
|
].freeze
|
|
51
46
|
|
|
52
47
|
# All Elements that share the same page version and parent element and are fixed or not are considered a list.
|
|
@@ -61,10 +56,6 @@ module Alchemy
|
|
|
61
56
|
|
|
62
57
|
stampable stamper_class_name: Alchemy.user_class.name
|
|
63
58
|
|
|
64
|
-
has_many :contents, dependent: :destroy, inverse_of: :element
|
|
65
|
-
|
|
66
|
-
deprecate contents: :ingredients, deprecator: Alchemy::Deprecation
|
|
67
|
-
|
|
68
59
|
before_destroy :delete_all_nested_elements
|
|
69
60
|
|
|
70
61
|
has_many :all_nested_elements,
|
|
@@ -97,9 +88,7 @@ module Alchemy
|
|
|
97
88
|
validates_presence_of :name, on: :create
|
|
98
89
|
validates_format_of :name, on: :create, with: NAME_REGEXP
|
|
99
90
|
|
|
100
|
-
attr_accessor :autogenerate_contents
|
|
101
91
|
attr_accessor :autogenerate_nested_elements
|
|
102
|
-
after_create :create_contents, unless: -> { autogenerate_contents == false }
|
|
103
92
|
after_create :generate_nested_elements, unless: -> { autogenerate_nested_elements == false }
|
|
104
93
|
|
|
105
94
|
after_update :touch_touchable_pages
|
|
@@ -107,7 +96,6 @@ module Alchemy
|
|
|
107
96
|
scope :published, -> { where(public: true) }
|
|
108
97
|
scope :hidden, -> { where(public: false) }
|
|
109
98
|
scope :not_restricted, -> { joins(:page).merge(Page.not_restricted) }
|
|
110
|
-
scope :available, -> { published }
|
|
111
99
|
scope :named, ->(names) { where(name: names) }
|
|
112
100
|
scope :excluded, ->(names) { where.not(name: names) }
|
|
113
101
|
scope :fixed, -> { where(fixed: true) }
|
|
@@ -121,8 +109,6 @@ module Alchemy
|
|
|
121
109
|
|
|
122
110
|
# Concerns
|
|
123
111
|
include Definitions
|
|
124
|
-
include ElementContents
|
|
125
|
-
include ElementEssences
|
|
126
112
|
include ElementIngredients
|
|
127
113
|
include Presenters
|
|
128
114
|
|
|
@@ -159,7 +145,7 @@ module Alchemy
|
|
|
159
145
|
@_dom_id_class = klass
|
|
160
146
|
end
|
|
161
147
|
|
|
162
|
-
# This methods does a copy of source and all
|
|
148
|
+
# This methods does a copy of source and all its ingredients.
|
|
163
149
|
#
|
|
164
150
|
# == Options
|
|
165
151
|
#
|
|
@@ -194,8 +180,6 @@ module Alchemy
|
|
|
194
180
|
|
|
195
181
|
all_from_clipboard(clipboard).where(name: parent_element.definition["nestable_elements"])
|
|
196
182
|
end
|
|
197
|
-
|
|
198
|
-
deprecate available: :published, deprecator: Alchemy::Deprecation
|
|
199
183
|
end
|
|
200
184
|
|
|
201
185
|
# Returns next public element from same page.
|
|
@@ -279,7 +263,7 @@ module Alchemy
|
|
|
279
263
|
# Elements are defined in the +config/alchemy/elements.yml+ file
|
|
280
264
|
#
|
|
281
265
|
# - name: article
|
|
282
|
-
#
|
|
266
|
+
# ingredients:
|
|
283
267
|
# ...
|
|
284
268
|
#
|
|
285
269
|
# == Override the view
|
|
@@ -13,11 +13,13 @@ module Alchemy
|
|
|
13
13
|
belongs_to :element, touch: true, class_name: "Alchemy::Element", inverse_of: :ingredients
|
|
14
14
|
belongs_to :related_object, polymorphic: true, optional: true
|
|
15
15
|
|
|
16
|
+
has_one :page, through: :element, class_name: "Alchemy::Page"
|
|
17
|
+
|
|
16
18
|
after_initialize :set_default_value,
|
|
17
19
|
if: -> { definition.key?(:default) && value.nil? }
|
|
18
20
|
|
|
19
21
|
validates :type, presence: true
|
|
20
|
-
validates :role, presence: true
|
|
22
|
+
validates :role, presence: true, uniqueness: { scope: :element_id, case_sensitive: false }
|
|
21
23
|
|
|
22
24
|
validates_with Alchemy::IngredientValidator, on: :update, if: :has_validations?
|
|
23
25
|
|
|
@@ -76,11 +78,16 @@ module Alchemy
|
|
|
76
78
|
default: Alchemy.t("ingredient_roles.#{role}", default: role.humanize),
|
|
77
79
|
)
|
|
78
80
|
end
|
|
79
|
-
end
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
# Allow to define settings on the ingredient definition
|
|
83
|
+
def allow_settings(settings)
|
|
84
|
+
@allowed_settings = Array(settings)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Allowed settings on the ingredient
|
|
88
|
+
def allowed_settings
|
|
89
|
+
@allowed_settings ||= []
|
|
90
|
+
end
|
|
84
91
|
end
|
|
85
92
|
|
|
86
93
|
# The value or the related object if present
|
|
@@ -97,7 +104,7 @@ module Alchemy
|
|
|
97
104
|
#
|
|
98
105
|
# @param key [Symbol] - The hash key you want to fetch the value from
|
|
99
106
|
# @param options [Hash] - An optional Hash that can override the settings.
|
|
100
|
-
# Normally passed as options hash into the
|
|
107
|
+
# Normally passed as options hash into the ingredient
|
|
101
108
|
# editor view.
|
|
102
109
|
def settings_value(key, options = {})
|
|
103
110
|
settings.merge(options || {})[key.to_sym]
|
|
@@ -164,6 +171,10 @@ module Alchemy
|
|
|
164
171
|
role
|
|
165
172
|
end
|
|
166
173
|
|
|
174
|
+
def hint_translation_scope
|
|
175
|
+
"ingredient_hints"
|
|
176
|
+
end
|
|
177
|
+
|
|
167
178
|
def set_default_value
|
|
168
179
|
self.value = default_value
|
|
169
180
|
end
|
|
@@ -5,6 +5,8 @@ module Alchemy
|
|
|
5
5
|
# A datetime value
|
|
6
6
|
#
|
|
7
7
|
class Datetime < Alchemy::Ingredient
|
|
8
|
+
allow_settings %i[date_format]
|
|
9
|
+
|
|
8
10
|
def value
|
|
9
11
|
ActiveRecord::Type::DateTime.new.cast(self[:value])
|
|
10
12
|
end
|
|
@@ -13,7 +15,7 @@ module Alchemy
|
|
|
13
15
|
def preview_text(_maxlength = nil)
|
|
14
16
|
return "" unless value
|
|
15
17
|
|
|
16
|
-
::I18n.l(value, format: :'alchemy.
|
|
18
|
+
::I18n.l(value, format: :'alchemy.ingredient_date')
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
21
|
end
|
|
@@ -27,6 +27,17 @@ module Alchemy
|
|
|
27
27
|
|
|
28
28
|
related_object_alias :picture, class_name: "Alchemy::Picture"
|
|
29
29
|
|
|
30
|
+
allow_settings %i[
|
|
31
|
+
crop
|
|
32
|
+
css_classes
|
|
33
|
+
fixed_ratio
|
|
34
|
+
linkable
|
|
35
|
+
size
|
|
36
|
+
sizes
|
|
37
|
+
srcset
|
|
38
|
+
upsample
|
|
39
|
+
]
|
|
40
|
+
|
|
30
41
|
# The first 30 characters of the pictures name
|
|
31
42
|
#
|
|
32
43
|
# Used by the Element#preview_text method.
|
data/app/models/alchemy/node.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Alchemy
|
|
|
4
4
|
class Node < BaseRecord
|
|
5
5
|
VALID_URL_REGEX = /\A(\/|\D[a-z\+\d\.\-]+:)/
|
|
6
6
|
|
|
7
|
-
before_destroy :
|
|
7
|
+
before_destroy :check_if_related_node_ingredients_present
|
|
8
8
|
|
|
9
9
|
acts_as_nested_set scope: "language_id", touch: true
|
|
10
10
|
stampable stamper_class_name: Alchemy.user_class.name
|
|
@@ -14,7 +14,10 @@ module Alchemy
|
|
|
14
14
|
|
|
15
15
|
has_one :site, through: :language
|
|
16
16
|
|
|
17
|
-
has_many :
|
|
17
|
+
has_many :node_ingredients,
|
|
18
|
+
class_name: "Alchemy::Ingredients::Node",
|
|
19
|
+
foreign_key: :related_object_id,
|
|
20
|
+
inverse_of: :related_object
|
|
18
21
|
|
|
19
22
|
before_validation :translate_root_menu_name, if: -> { root? }
|
|
20
23
|
before_validation :set_menu_type_from_root, unless: -> { root? }
|
|
@@ -76,10 +79,10 @@ module Alchemy
|
|
|
76
79
|
|
|
77
80
|
private
|
|
78
81
|
|
|
79
|
-
def
|
|
80
|
-
|
|
81
|
-
if
|
|
82
|
-
errors.add(:base, :
|
|
82
|
+
def check_if_related_node_ingredients_present
|
|
83
|
+
dependent_node_ingredients = self_and_descendants.flat_map(&:node_ingredients)
|
|
84
|
+
if dependent_node_ingredients.any?
|
|
85
|
+
errors.add(:base, :node_ingredients_present, page_names: dependent_node_ingredients.map { |i| i.element&.page&.name }.to_sentence)
|
|
83
86
|
throw(:abort)
|
|
84
87
|
end
|
|
85
88
|
end
|
|
@@ -19,7 +19,7 @@ module Alchemy
|
|
|
19
19
|
has_many :fixed_elements, -> { fixed.published }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
has_many :
|
|
22
|
+
has_many :ingredients, through: :elements
|
|
23
23
|
has_and_belongs_to_many :to_be_swept_elements, -> { distinct },
|
|
24
24
|
class_name: "Alchemy::Element",
|
|
25
25
|
join_table: ElementToPage.table_name
|
|
@@ -58,17 +58,17 @@ module Alchemy
|
|
|
58
58
|
#
|
|
59
59
|
# - name: headline
|
|
60
60
|
# unique: true
|
|
61
|
-
#
|
|
61
|
+
# ingredients:
|
|
62
62
|
# - name: headline
|
|
63
|
-
# type:
|
|
63
|
+
# type: Text
|
|
64
64
|
#
|
|
65
65
|
# == Example of limited element:
|
|
66
66
|
#
|
|
67
67
|
# - name: article
|
|
68
68
|
# amount: 2
|
|
69
|
-
#
|
|
69
|
+
# ingredients:
|
|
70
70
|
# - name: text
|
|
71
|
-
# type:
|
|
71
|
+
# type: Richtext
|
|
72
72
|
#
|
|
73
73
|
def available_element_definitions(only_element_named = nil)
|
|
74
74
|
@_element_definitions ||= if only_element_named
|
|
@@ -156,27 +156,6 @@ module Alchemy
|
|
|
156
156
|
end
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
-
# Returns all elements that should be feeded via rss.
|
|
160
|
-
#
|
|
161
|
-
# Define feedable elements in your +page_layouts.yml+:
|
|
162
|
-
#
|
|
163
|
-
# - name: news
|
|
164
|
-
# feed: true
|
|
165
|
-
# feed_elements: [element_name, element_2_name]
|
|
166
|
-
#
|
|
167
|
-
def feed_elements
|
|
168
|
-
elements.named(definition["feed_elements"])
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# Returns an array of all EssenceRichtext contents ids from not folded elements
|
|
172
|
-
#
|
|
173
|
-
def richtext_contents_ids
|
|
174
|
-
Alchemy::Content.joins(:element)
|
|
175
|
-
.where(Element.table_name => { page_version_id: draft_version.id, folded: false })
|
|
176
|
-
.select(&:has_tinymce?)
|
|
177
|
-
.collect(&:id)
|
|
178
|
-
end
|
|
179
|
-
|
|
180
159
|
# Returns an array of all Richtext ingredients ids from not folded elements
|
|
181
160
|
#
|
|
182
161
|
def richtext_ingredients_ids
|
|
@@ -23,20 +23,6 @@ module Alchemy
|
|
|
23
23
|
mapped_layouts_for_select(selectable_layouts(language_id, layoutpages: layoutpages))
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
# Returns page layouts including given layout ready for Rails' select form helper.
|
|
27
|
-
#
|
|
28
|
-
def layouts_with_own_for_select(page_layout_name, language_id, layoutpages: false)
|
|
29
|
-
layouts = selectable_layouts(language_id, layoutpages: layoutpages)
|
|
30
|
-
if layouts.detect { |l| l["name"] == page_layout_name }.nil?
|
|
31
|
-
@map_array = [[human_layout_name(page_layout_name), page_layout_name]]
|
|
32
|
-
else
|
|
33
|
-
@map_array = []
|
|
34
|
-
end
|
|
35
|
-
mapped_layouts_for_select(layouts)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
deprecate :layouts_with_own_for_select, deprecator: Alchemy::Deprecation
|
|
39
|
-
|
|
40
26
|
# Returns all layouts that can be used for creating a new page.
|
|
41
27
|
#
|
|
42
28
|
# It removes all layouts from available layouts that are unique and already taken and that are marked as hide.
|