alchemy_cms 6.1.2 → 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 +22 -8
- data/Gemfile +1 -0
- data/Rakefile +13 -8
- data/alchemy_cms.gemspec +1 -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 +6 -4
- data/app/controllers/alchemy/messages_controller.rb +9 -9
- data/app/controllers/alchemy/pages_controller.rb +19 -28
- 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 -16
- 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 -8
- data/app/models/alchemy/picture/transformations.rb +0 -30
- data/app/models/alchemy/picture/url.rb +1 -1
- data/app/models/alchemy/picture.rb +12 -10
- 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 -2
- 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/_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/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 +98 -112
- 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/install/tasks.rb +7 -1
- data/lib/alchemy/permissions.rb +0 -13
- data/lib/alchemy/routing_constraints.rb +3 -3
- data/lib/alchemy/searchable_resource.rb +38 -0
- 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/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 +2 -3
- 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 -22
- data/lib/generators/alchemy/install/templates/elements.yml.tt +12 -12
- data/lib/non_stupid_digest_assets.rb +55 -0
- 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 +15 -154
- 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/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 -74
- 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
|
@@ -49,22 +49,21 @@ module Alchemy
|
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
# Updates the element.
|
|
53
|
-
#
|
|
54
|
-
# And update all contents in the elements by calling update_contents.
|
|
52
|
+
# Updates the element and all ingredients in the element.
|
|
55
53
|
#
|
|
56
54
|
def update
|
|
57
55
|
@page = @element.page
|
|
58
56
|
|
|
59
|
-
if
|
|
60
|
-
|
|
57
|
+
if @element.update(element_params)
|
|
58
|
+
@element_validated = true
|
|
61
59
|
else
|
|
62
|
-
|
|
60
|
+
element_update_error
|
|
61
|
+
@error_messages = @element.ingredient_error_messages
|
|
63
62
|
end
|
|
64
63
|
end
|
|
65
64
|
|
|
66
65
|
def destroy
|
|
67
|
-
@richtext_ids = @element.
|
|
66
|
+
@richtext_ids = @element.richtext_ingredients_ids
|
|
68
67
|
@element.destroy
|
|
69
68
|
@notice = Alchemy.t("Successfully deleted element") % { element: @element.display_name }
|
|
70
69
|
end
|
|
@@ -103,14 +102,12 @@ module Alchemy
|
|
|
103
102
|
def element_includes
|
|
104
103
|
[
|
|
105
104
|
{
|
|
106
|
-
contents: :essence,
|
|
107
105
|
ingredients: :related_object,
|
|
108
106
|
},
|
|
109
107
|
:tags,
|
|
110
108
|
{
|
|
111
109
|
all_nested_elements: [
|
|
112
110
|
{
|
|
113
|
-
contents: :essence,
|
|
114
111
|
ingredients: :related_object,
|
|
115
112
|
},
|
|
116
113
|
:tags,
|
|
@@ -152,10 +149,6 @@ module Alchemy
|
|
|
152
149
|
element
|
|
153
150
|
end
|
|
154
151
|
|
|
155
|
-
def contents_params
|
|
156
|
-
params.fetch(:contents, {}).permit!
|
|
157
|
-
end
|
|
158
|
-
|
|
159
152
|
def element_params
|
|
160
153
|
params.fetch(:element, {}).permit(:tag_list, ingredients_attributes: {})
|
|
161
154
|
end
|
|
@@ -164,28 +157,10 @@ module Alchemy
|
|
|
164
157
|
params.require(:element).permit(:name, :page_version_id, :parent_element_id)
|
|
165
158
|
end
|
|
166
159
|
|
|
167
|
-
def update_element_with_ingredients
|
|
168
|
-
if @element.update(element_params)
|
|
169
|
-
@element_validated = true
|
|
170
|
-
else
|
|
171
|
-
element_update_error
|
|
172
|
-
@error_messages = @element.ingredient_error_messages
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def update_element_with_contents
|
|
177
|
-
if @element.update_contents(contents_params)
|
|
178
|
-
@element_validated = @element.update(element_params)
|
|
179
|
-
else
|
|
180
|
-
element_update_error
|
|
181
|
-
@error_messages = @element.essence_error_messages
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
160
|
def element_update_error
|
|
186
161
|
@element_validated = false
|
|
187
162
|
@notice = Alchemy.t("Validation failed")
|
|
188
|
-
@error_message = "<h2>#{@notice}</h2><p>#{Alchemy.t(:
|
|
163
|
+
@error_message = "<h2>#{@notice}</h2><p>#{Alchemy.t(:ingredient_validations_headline)}</p>".html_safe
|
|
189
164
|
end
|
|
190
165
|
end
|
|
191
166
|
end
|
|
@@ -94,7 +94,7 @@ module Alchemy
|
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
# Edit the content of the page and all its elements and
|
|
97
|
+
# Edit the content of the page and all its elements and ingredients.
|
|
98
98
|
#
|
|
99
99
|
# Locks the page to current user to prevent other users from editing it meanwhile.
|
|
100
100
|
#
|
|
@@ -32,7 +32,7 @@ module Alchemy
|
|
|
32
32
|
@query = Picture.ransack(params[:q])
|
|
33
33
|
@previous = filtered_pictures.where("name < ?", @picture.name).last
|
|
34
34
|
@next = filtered_pictures.where("name > ?", @picture.name).first
|
|
35
|
-
@assignments = @picture.
|
|
35
|
+
@assignments = @picture.picture_ingredients.joins(element: :page)
|
|
36
36
|
|
|
37
37
|
render action: "show"
|
|
38
38
|
end
|
|
@@ -103,7 +103,7 @@ module Alchemy
|
|
|
103
103
|
def resource_filters
|
|
104
104
|
return unless resource_has_filters
|
|
105
105
|
|
|
106
|
-
@_resource_filters ||=
|
|
106
|
+
@_resource_filters ||= resource_model.alchemy_resource_filters
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def resource_filters_for_select
|
|
@@ -114,23 +114,6 @@ module Alchemy
|
|
|
114
114
|
|
|
115
115
|
protected
|
|
116
116
|
|
|
117
|
-
def deprecated_resource_filters
|
|
118
|
-
if resource_has_deprecated_filters
|
|
119
|
-
Alchemy::Deprecation.warn(
|
|
120
|
-
"#{resource_model}.alchemy_resource_filters is using a legacy data structure. " \
|
|
121
|
-
"Please use an Array of Hashes instead. i.e. [{ name: 'foo', values: ['bar', 'baz'] }, ...] " \
|
|
122
|
-
"where values are scopes. With Alchemy 6.1 only the new structure will be supported."
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
@_resource_filters ||= [
|
|
126
|
-
{
|
|
127
|
-
name: :misc,
|
|
128
|
-
values: resource_model.alchemy_resource_filters,
|
|
129
|
-
},
|
|
130
|
-
]
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
117
|
def apply_filters(items)
|
|
135
118
|
sanitize_filter_params!
|
|
136
119
|
|
|
@@ -30,11 +30,13 @@ module Alchemy
|
|
|
30
30
|
def nested
|
|
31
31
|
@page = Page.find_by(id: params[:page_id]) || Language.current_root_page
|
|
32
32
|
|
|
33
|
-
render json: PageTreeSerializer.new(
|
|
33
|
+
render json: PageTreeSerializer.new(
|
|
34
|
+
@page,
|
|
34
35
|
ability: current_ability,
|
|
35
36
|
user: current_alchemy_user,
|
|
36
37
|
elements: params[:elements],
|
|
37
|
-
full: true
|
|
38
|
+
full: true,
|
|
39
|
+
)
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
# Returns a json object for page
|
|
@@ -107,13 +109,13 @@ module Alchemy
|
|
|
107
109
|
{
|
|
108
110
|
nested_elements: [
|
|
109
111
|
{
|
|
110
|
-
|
|
112
|
+
ingredients: :related_object,
|
|
111
113
|
},
|
|
112
114
|
:tags,
|
|
113
115
|
],
|
|
114
116
|
},
|
|
115
117
|
{
|
|
116
|
-
|
|
118
|
+
ingredients: :related_object,
|
|
117
119
|
},
|
|
118
120
|
:tags,
|
|
119
121
|
],
|
|
@@ -11,15 +11,15 @@ module Alchemy
|
|
|
11
11
|
# Make an Element with this options inside your @elements.yml file:
|
|
12
12
|
#
|
|
13
13
|
# - name: contactform
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
14
|
+
# ingredients:
|
|
15
|
+
# - role: mail_to
|
|
16
|
+
# type: Text
|
|
17
|
+
# - role: subject
|
|
18
|
+
# type: Text
|
|
19
|
+
# - role: mail_from
|
|
20
|
+
# type: Text
|
|
21
|
+
# - role: success_page
|
|
22
|
+
# type: Page
|
|
23
23
|
#
|
|
24
24
|
# The fields +mail_to+, +mail_from+, +subject+ and +success_page+ are recommended.
|
|
25
25
|
# The +Alchemy::MessagesController+ uses them to send your mails. So your customer has full controll of these values inside his contactform element.
|
|
@@ -104,14 +104,13 @@ module Alchemy
|
|
|
104
104
|
# If no index page and no admin users are present we show the "Welcome to Alchemy" page.
|
|
105
105
|
#
|
|
106
106
|
def load_index_page
|
|
107
|
-
@page ||=
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
107
|
+
@page ||= Alchemy::Page
|
|
108
|
+
.contentpages
|
|
109
|
+
.language_roots
|
|
110
|
+
.where(language: Language.current)
|
|
111
|
+
.includes(page_includes)
|
|
112
|
+
.first
|
|
113
|
+
|
|
115
114
|
render template: "alchemy/welcome", layout: false if signup_required?
|
|
116
115
|
end
|
|
117
116
|
|
|
@@ -127,13 +126,11 @@ module Alchemy
|
|
|
127
126
|
def load_page
|
|
128
127
|
page_not_found! unless Language.current
|
|
129
128
|
|
|
130
|
-
@page ||=
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
find_by(urlname: params[:urlname])
|
|
136
|
-
end
|
|
129
|
+
@page ||= Alchemy::Page
|
|
130
|
+
.contentpages
|
|
131
|
+
.where(language: Language.current)
|
|
132
|
+
.includes(page_includes)
|
|
133
|
+
.find_by(urlname: params[:urlname])
|
|
137
134
|
end
|
|
138
135
|
|
|
139
136
|
def enforce_locale
|
|
@@ -178,7 +175,7 @@ module Alchemy
|
|
|
178
175
|
|
|
179
176
|
# == Renders the page :show template
|
|
180
177
|
#
|
|
181
|
-
# Handles html
|
|
178
|
+
# Handles html requests
|
|
182
179
|
#
|
|
183
180
|
# Omits the layout, if the request is a XHR request.
|
|
184
181
|
#
|
|
@@ -187,14 +184,6 @@ module Alchemy
|
|
|
187
184
|
format.html do
|
|
188
185
|
render action: :show, layout: !request.xhr?
|
|
189
186
|
end
|
|
190
|
-
|
|
191
|
-
format.rss do
|
|
192
|
-
if @page.contains_feed?
|
|
193
|
-
render action: :show, layout: false, handlers: [:builder]
|
|
194
|
-
else
|
|
195
|
-
render xml: { error: "Not found" }, status: 404
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
187
|
end
|
|
199
188
|
end
|
|
200
189
|
|
|
@@ -230,10 +219,12 @@ module Alchemy
|
|
|
230
219
|
# or the cache is stale, because it's been republished by the user.
|
|
231
220
|
#
|
|
232
221
|
def render_fresh_page?
|
|
233
|
-
must_not_cache? || stale?(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
222
|
+
must_not_cache? || stale?(
|
|
223
|
+
etag: page_etag,
|
|
224
|
+
last_modified: @page.published_at,
|
|
225
|
+
public: !@page.restricted,
|
|
226
|
+
template: "pages/show",
|
|
227
|
+
)
|
|
237
228
|
end
|
|
238
229
|
|
|
239
230
|
# don't cache pages if we have flash message to display or the page has caching disabled
|
|
@@ -8,17 +8,6 @@ module Alchemy
|
|
|
8
8
|
"alchemy/admin/elements/element"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
# Returns content editor instances for defined contents
|
|
12
|
-
#
|
|
13
|
-
# Creates contents on demand if the content is not yet present on the element
|
|
14
|
-
#
|
|
15
|
-
# @return Array<Alchemy::ContentEditor>
|
|
16
|
-
def contents
|
|
17
|
-
element.definition.fetch(:contents, []).map do |content|
|
|
18
|
-
Alchemy::ContentEditor.new(find_or_create_content(content[:name]))
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
11
|
# Returns ingredient editor instances for defined ingredients
|
|
23
12
|
#
|
|
24
13
|
# Creates ingredient on demand if the ingredient is not yet present on the element
|
|
@@ -36,7 +25,7 @@ module Alchemy
|
|
|
36
25
|
element.definition.fetch(:ingredients, []).any?
|
|
37
26
|
end
|
|
38
27
|
|
|
39
|
-
# Returns the translated
|
|
28
|
+
# Returns the translated ingredient group for displaying in admin editor group headings
|
|
40
29
|
#
|
|
41
30
|
# Translate it in your locale yml file:
|
|
42
31
|
#
|
|
@@ -63,7 +52,7 @@ module Alchemy
|
|
|
63
52
|
def css_classes
|
|
64
53
|
[
|
|
65
54
|
"element-editor",
|
|
66
|
-
|
|
55
|
+
ingredient_definitions.present? ? "with-ingredients" : "without-ingredients",
|
|
67
56
|
nestable_elements.any? ? "nestable" : "not-nestable",
|
|
68
57
|
taggable? ? "taggable" : "not-taggable",
|
|
69
58
|
folded ? "folded" : "expanded",
|
|
@@ -78,12 +67,13 @@ module Alchemy
|
|
|
78
67
|
def editable?
|
|
79
68
|
return false if folded?
|
|
80
69
|
|
|
81
|
-
|
|
70
|
+
ingredient_definitions.any? || taggable?
|
|
82
71
|
end
|
|
83
72
|
|
|
84
73
|
# Fixes Rails partial renderer calling to_model on the object
|
|
85
74
|
# which reveals the delegated element instead of this decorator.
|
|
86
|
-
def respond_to?(
|
|
75
|
+
def respond_to?(*args, **kwargs)
|
|
76
|
+
method_name = args.first
|
|
87
77
|
return false if method_name == :to_model
|
|
88
78
|
|
|
89
79
|
super
|
|
@@ -124,26 +114,16 @@ module Alchemy
|
|
|
124
114
|
when String
|
|
125
115
|
definition["deprecated"]
|
|
126
116
|
when TrueClass
|
|
127
|
-
Alchemy.t(
|
|
128
|
-
|
|
129
|
-
|
|
117
|
+
Alchemy.t(
|
|
118
|
+
name,
|
|
119
|
+
scope: :element_deprecation_notices,
|
|
120
|
+
default: Alchemy.t(:element_deprecated),
|
|
121
|
+
)
|
|
130
122
|
end
|
|
131
123
|
end
|
|
132
124
|
|
|
133
125
|
private
|
|
134
126
|
|
|
135
|
-
def find_or_create_content(name)
|
|
136
|
-
find_content(name) || create_content(name)
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def find_content(name)
|
|
140
|
-
element.contents.find { |content| content.name == name }
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def create_content(name)
|
|
144
|
-
Alchemy::Content.create(element: element, name: name)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
127
|
def find_or_create_ingredient(definition)
|
|
148
128
|
element.ingredients.detect { |i| i.role == definition[:role] } ||
|
|
149
129
|
element.ingredients.create!(
|
|
@@ -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
|