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.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +0 -3
  3. data/.gitignore +1 -6
  4. data/CHANGELOG.md +22 -8
  5. data/Gemfile +1 -0
  6. data/Rakefile +13 -8
  7. data/alchemy_cms.gemspec +1 -3
  8. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +1 -1
  9. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +18 -32
  10. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +2 -2
  11. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +2 -2
  12. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +27 -29
  13. data/app/assets/stylesheets/alchemy/elements.scss +16 -35
  14. data/app/assets/stylesheets/alchemy/forms.scss +0 -4
  15. data/app/assets/stylesheets/alchemy/node-select.scss +2 -2
  16. data/app/controllers/alchemy/admin/attachments_controller.rb +0 -1
  17. data/app/controllers/alchemy/admin/elements_controller.rb +7 -32
  18. data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
  19. data/app/controllers/alchemy/admin/pictures_controller.rb +1 -1
  20. data/app/controllers/alchemy/admin/resources_controller.rb +1 -18
  21. data/app/controllers/alchemy/api/elements_controller.rb +0 -2
  22. data/app/controllers/alchemy/api/pages_controller.rb +6 -4
  23. data/app/controllers/alchemy/messages_controller.rb +9 -9
  24. data/app/controllers/alchemy/pages_controller.rb +19 -28
  25. data/app/decorators/alchemy/element_editor.rb +10 -30
  26. data/app/helpers/alchemy/admin/elements_helper.rb +0 -2
  27. data/app/helpers/alchemy/elements_block_helper.rb +5 -42
  28. data/app/helpers/alchemy/elements_helper.rb +3 -11
  29. data/app/helpers/alchemy/pages_helper.rb +0 -4
  30. data/app/models/alchemy/attachment.rb +6 -3
  31. data/app/models/alchemy/base_record.rb +2 -0
  32. data/app/models/alchemy/eager_loading.rb +0 -1
  33. data/app/models/alchemy/element/element_ingredients.rb +1 -8
  34. data/app/models/alchemy/element/presenters.rb +9 -25
  35. data/app/models/alchemy/element.rb +2 -16
  36. data/app/models/alchemy/ingredient.rb +17 -6
  37. data/app/models/alchemy/ingredients/audio.rb +2 -0
  38. data/app/models/alchemy/ingredients/datetime.rb +3 -1
  39. data/app/models/alchemy/ingredients/file.rb +7 -0
  40. data/app/models/alchemy/ingredients/headline.rb +6 -0
  41. data/app/models/alchemy/ingredients/link.rb +2 -0
  42. data/app/models/alchemy/ingredients/node.rb +2 -0
  43. data/app/models/alchemy/ingredients/page.rb +2 -0
  44. data/app/models/alchemy/ingredients/picture.rb +11 -0
  45. data/app/models/alchemy/ingredients/richtext.rb +6 -0
  46. data/app/models/alchemy/ingredients/select.rb +1 -0
  47. data/app/models/alchemy/ingredients/text.rb +8 -0
  48. data/app/models/alchemy/ingredients/video.rb +2 -0
  49. data/app/models/alchemy/node.rb +9 -6
  50. data/app/models/alchemy/page/page_elements.rb +5 -26
  51. data/app/models/alchemy/page/page_layouts.rb +0 -14
  52. data/app/models/alchemy/page/page_natures.rb +0 -10
  53. data/app/models/alchemy/page.rb +0 -8
  54. data/app/models/alchemy/picture/transformations.rb +0 -30
  55. data/app/models/alchemy/picture/url.rb +1 -1
  56. data/app/models/alchemy/picture.rb +12 -10
  57. data/app/models/alchemy/picture_thumb/create.rb +7 -18
  58. data/app/models/alchemy/picture_thumb/file_store.rb +33 -0
  59. data/app/models/alchemy/picture_thumb.rb +10 -10
  60. data/app/models/concerns/alchemy/picture_thumbnails.rb +2 -2
  61. data/app/serializers/alchemy/element_serializer.rb +1 -6
  62. data/app/services/alchemy/delete_elements.rb +1 -7
  63. data/app/services/alchemy/duplicate_element.rb +1 -6
  64. data/app/views/alchemy/admin/elements/_element.html.erb +5 -22
  65. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  66. data/app/views/alchemy/admin/elements/fold.js.erb +2 -2
  67. data/app/views/alchemy/admin/elements/order.js.erb +1 -1
  68. data/app/views/alchemy/admin/elements/update.js.erb +1 -2
  69. data/app/views/alchemy/admin/pages/_external_link.html.erb +2 -2
  70. data/app/views/alchemy/admin/pages/_file_link.html.erb +2 -2
  71. data/app/views/alchemy/admin/pages/_internal_link.html.erb +2 -2
  72. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +3 -6
  73. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  74. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -3
  75. data/app/views/alchemy/admin/pictures/_infos.html.erb +4 -6
  76. data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
  77. data/app/views/alchemy/ingredients/_headline_editor.html.erb +1 -1
  78. data/app/views/alchemy/ingredients/_html_editor.html.erb +1 -1
  79. data/app/views/alchemy/ingredients/_node_editor.html.erb +1 -1
  80. data/app/views/alchemy/ingredients/_picture_editor.html.erb +4 -4
  81. data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -2
  82. data/app/views/alchemy/ingredients/_text_editor.html.erb +1 -1
  83. data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +3 -3
  84. data/app/views/alchemy/pages/_meta_data.html.erb +0 -1
  85. data/app/views/layouts/alchemy/admin.html.erb +5 -1
  86. data/config/alchemy/config.yml +6 -6
  87. data/config/brakeman.ignore +56 -57
  88. data/config/locales/alchemy.en.yml +98 -112
  89. data/config/routes.rb +1 -16
  90. data/db/migrate/20230121212637_alchemy_six_point_one.rb +248 -0
  91. data/lib/alchemy/cache_digests/template_tracker.rb +6 -7
  92. data/lib/alchemy/config.rb +2 -2
  93. data/lib/alchemy/deprecation.rb +1 -1
  94. data/lib/alchemy/errors.rb +0 -11
  95. data/lib/alchemy/hints.rb +10 -10
  96. data/lib/alchemy/install/tasks.rb +7 -1
  97. data/lib/alchemy/permissions.rb +0 -13
  98. data/lib/alchemy/routing_constraints.rb +3 -3
  99. data/lib/alchemy/searchable_resource.rb +38 -0
  100. data/lib/alchemy/tasks/tidy.rb +0 -38
  101. data/lib/alchemy/test_support/capybara_helpers.rb +69 -0
  102. data/lib/alchemy/test_support/factories/element_factory.rb +0 -6
  103. data/lib/alchemy/test_support/factories/ingredient_factory.rb +1 -1
  104. data/lib/alchemy/test_support/factories/page_factory.rb +4 -2
  105. data/lib/alchemy/test_support/shared_dom_ids_examples.rb +1 -1
  106. data/lib/alchemy/test_support/shared_ingredient_examples.rb +1 -1
  107. data/lib/alchemy/tinymce.rb +1 -18
  108. data/lib/alchemy/upgrader/seven_point_zero.rb +45 -0
  109. data/lib/alchemy/upgrader/tasks/.keep +0 -0
  110. data/lib/alchemy/upgrader.rb +8 -3
  111. data/lib/alchemy/version.rb +1 -1
  112. data/lib/alchemy.rb +0 -19
  113. data/lib/alchemy_cms.rb +2 -3
  114. data/lib/generators/alchemy/elements/elements_generator.rb +0 -1
  115. data/lib/generators/alchemy/elements/templates/view.html.erb +1 -10
  116. data/lib/generators/alchemy/elements/templates/view.html.haml +1 -9
  117. data/lib/generators/alchemy/elements/templates/view.html.slim +1 -9
  118. data/lib/generators/alchemy/install/files/alchemy.en.yml +7 -8
  119. data/lib/generators/alchemy/install/files/application.html.erb +1 -1
  120. data/lib/generators/alchemy/install/install_generator.rb +18 -22
  121. data/lib/generators/alchemy/install/templates/elements.yml.tt +12 -12
  122. data/lib/non_stupid_digest_assets.rb +55 -0
  123. data/lib/tasks/alchemy/thumbnails.rake +2 -21
  124. data/lib/tasks/alchemy/tidy.rake +1 -12
  125. data/lib/tasks/alchemy/upgrade.rake +10 -47
  126. data/package/dist/admin.js +16 -0
  127. data/package/dist/admin.js.map +7 -0
  128. data/package.json +5 -3
  129. metadata +15 -154
  130. data/app/controllers/alchemy/admin/contents_controller.rb +0 -21
  131. data/app/controllers/alchemy/admin/essence_audios_controller.rb +0 -30
  132. data/app/controllers/alchemy/admin/essence_files_controller.rb +0 -31
  133. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +0 -43
  134. data/app/controllers/alchemy/admin/essence_videos_controller.rb +0 -34
  135. data/app/controllers/alchemy/api/contents_controller.rb +0 -52
  136. data/app/decorators/alchemy/content_editor.rb +0 -119
  137. data/app/helpers/alchemy/admin/contents_helper.rb +0 -42
  138. data/app/helpers/alchemy/admin/essences_helper.rb +0 -31
  139. data/app/models/alchemy/content/factory.rb +0 -143
  140. data/app/models/alchemy/content.rb +0 -247
  141. data/app/models/alchemy/element/element_contents.rb +0 -200
  142. data/app/models/alchemy/element/element_essences.rb +0 -133
  143. data/app/models/alchemy/essence_audio.rb +0 -13
  144. data/app/models/alchemy/essence_boolean.rb +0 -20
  145. data/app/models/alchemy/essence_date.rb +0 -25
  146. data/app/models/alchemy/essence_file.rb +0 -49
  147. data/app/models/alchemy/essence_headline.rb +0 -41
  148. data/app/models/alchemy/essence_html.rb +0 -23
  149. data/app/models/alchemy/essence_link.rb +0 -21
  150. data/app/models/alchemy/essence_node.rb +0 -19
  151. data/app/models/alchemy/essence_page.rb +0 -17
  152. data/app/models/alchemy/essence_picture.rb +0 -67
  153. data/app/models/alchemy/essence_picture_view.rb +0 -90
  154. data/app/models/alchemy/essence_richtext.rb +0 -44
  155. data/app/models/alchemy/essence_select.rb +0 -19
  156. data/app/models/alchemy/essence_text.rb +0 -23
  157. data/app/models/alchemy/essence_video.rb +0 -13
  158. data/app/serializers/alchemy/content_serializer.rb +0 -17
  159. data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -10
  160. data/app/serializers/alchemy/essence_date_serializer.rb +0 -10
  161. data/app/serializers/alchemy/essence_file_serializer.rb +0 -13
  162. data/app/serializers/alchemy/essence_html_serializer.rb +0 -10
  163. data/app/serializers/alchemy/essence_link_serializer.rb +0 -13
  164. data/app/serializers/alchemy/essence_picture_serializer.rb +0 -28
  165. data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -11
  166. data/app/serializers/alchemy/essence_select_serializer.rb +0 -10
  167. data/app/serializers/alchemy/essence_text_serializer.rb +0 -22
  168. data/app/views/alchemy/admin/contents/create.js.erb +0 -21
  169. data/app/views/alchemy/admin/essence_audios/edit.html.erb +0 -7
  170. data/app/views/alchemy/admin/essence_files/edit.html.erb +0 -21
  171. data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -5
  172. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +0 -30
  173. data/app/views/alchemy/admin/essence_pictures/save_link.js.erb +0 -3
  174. data/app/views/alchemy/admin/essence_pictures/update.js.erb +0 -8
  175. data/app/views/alchemy/admin/essence_videos/edit.html.erb +0 -12
  176. data/app/views/alchemy/essences/_essence_audio_editor.html.erb +0 -4
  177. data/app/views/alchemy/essences/_essence_audio_view.html.erb +0 -15
  178. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +0 -11
  179. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +0 -2
  180. data/app/views/alchemy/essences/_essence_date_editor.html.erb +0 -16
  181. data/app/views/alchemy/essences/_essence_date_view.html.erb +0 -10
  182. data/app/views/alchemy/essences/_essence_file_editor.html.erb +0 -54
  183. data/app/views/alchemy/essences/_essence_file_view.html.erb +0 -18
  184. data/app/views/alchemy/essences/_essence_headline_editor.html.erb +0 -36
  185. data/app/views/alchemy/essences/_essence_headline_view.html.erb +0 -10
  186. data/app/views/alchemy/essences/_essence_html_editor.html.erb +0 -10
  187. data/app/views/alchemy/essences/_essence_html_view.html.erb +0 -2
  188. data/app/views/alchemy/essences/_essence_link_editor.html.erb +0 -30
  189. data/app/views/alchemy/essences/_essence_link_view.html.erb +0 -10
  190. data/app/views/alchemy/essences/_essence_node_editor.html.erb +0 -27
  191. data/app/views/alchemy/essences/_essence_node_view.html.erb +0 -1
  192. data/app/views/alchemy/essences/_essence_page_editor.html.erb +0 -26
  193. data/app/views/alchemy/essences/_essence_page_view.html.erb +0 -5
  194. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +0 -59
  195. data/app/views/alchemy/essences/_essence_picture_view.html.erb +0 -6
  196. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +0 -14
  197. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +0 -4
  198. data/app/views/alchemy/essences/_essence_select_editor.html.erb +0 -28
  199. data/app/views/alchemy/essences/_essence_select_view.html.erb +0 -2
  200. data/app/views/alchemy/essences/_essence_text_editor.html.erb +0 -29
  201. data/app/views/alchemy/essences/_essence_text_view.html.erb +0 -17
  202. data/app/views/alchemy/essences/_essence_video_editor.html.erb +0 -4
  203. data/app/views/alchemy/essences/_essence_video_view.html.erb +0 -19
  204. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +0 -59
  205. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +0 -20
  206. data/app/views/alchemy/pages/show.rss.builder +0 -21
  207. data/db/migrate/20200226213334_alchemy_four_point_four.rb +0 -313
  208. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +0 -11
  209. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +0 -28
  210. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +0 -8
  211. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +0 -27
  212. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +0 -6
  213. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +0 -24
  214. data/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +0 -22
  215. data/db/migrate/20200907111332_remove_tri_state_booleans.rb +0 -33
  216. data/db/migrate/20201207131309_create_page_versions.rb +0 -19
  217. data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +0 -76
  218. data/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +0 -10
  219. data/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +0 -7
  220. data/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +0 -12
  221. data/db/migrate/20210506135919_create_essence_audios.rb +0 -19
  222. data/db/migrate/20210506140258_create_essence_videos.rb +0 -23
  223. data/db/migrate/20210508091432_create_alchemy_ingredients.rb +0 -22
  224. data/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb +0 -13
  225. data/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb +0 -9
  226. data/lib/alchemy/essence.rb +0 -250
  227. data/lib/alchemy/test_support/essence_shared_examples.rb +0 -271
  228. data/lib/alchemy/test_support/factories/content_factory.rb +0 -20
  229. data/lib/alchemy/test_support/factories/essence_audio_factory.rb +0 -7
  230. data/lib/alchemy/test_support/factories/essence_file_factory.rb +0 -7
  231. data/lib/alchemy/test_support/factories/essence_page_factory.rb +0 -7
  232. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +0 -11
  233. data/lib/alchemy/test_support/factories/essence_text_factory.rb +0 -7
  234. data/lib/alchemy/test_support/factories/essence_video_factory.rb +0 -7
  235. data/lib/alchemy/upgrader/five_point_zero.rb +0 -41
  236. data/lib/alchemy/upgrader/six_point_zero.rb +0 -21
  237. data/lib/alchemy/upgrader/tasks/add_page_versions.rb +0 -33
  238. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +0 -34
  239. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +0 -29
  240. data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +0 -74
  241. data/lib/generators/alchemy/essence/essence_generator.rb +0 -49
  242. data/lib/generators/alchemy/essence/templates/editor.html.erb +0 -17
  243. data/lib/generators/alchemy/essence/templates/view.html.erb +0 -2
@@ -78,7 +78,6 @@ module Alchemy
78
78
  @_search_filter_params ||= params.except(*COMMON_SEARCH_FILTER_EXCLUDES + [:attachment]).permit(
79
79
  *common_search_filter_includes + [
80
80
  :form_field_id,
81
- :content_id,
82
81
  ]
83
82
  )
84
83
  end
@@ -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 element_params.key?(:ingredients_attributes)
60
- update_element_with_ingredients
57
+ if @element.update(element_params)
58
+ @element_validated = true
61
59
  else
62
- update_element_with_contents
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.richtext_contents_ids + @element.richtext_ingredients_ids
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(:content_validations_headline)}</p>".html_safe
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 contents.
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.essence_pictures.joins(content: { element: :page })
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 ||= deprecated_resource_filters || resource_model.alchemy_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
 
@@ -47,14 +47,12 @@ module Alchemy
47
47
  {
48
48
  nested_elements: [
49
49
  {
50
- contents: :essence,
51
50
  ingredients: :related_object,
52
51
  },
53
52
  :tags,
54
53
  ],
55
54
  },
56
55
  {
57
- contents: :essence,
58
56
  ingredients: :related_object,
59
57
  },
60
58
  :tags,
@@ -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(@page,
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
- contents: :essence,
112
+ ingredients: :related_object,
111
113
  },
112
114
  :tags,
113
115
  ],
114
116
  },
115
117
  {
116
- contents: :essence,
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
- # contents:
15
- # - name: mail_to
16
- # type: EssenceText
17
- # - name: subject
18
- # type: EssenceText
19
- # - name: mail_from
20
- # type: EssenceText
21
- # - name: success_page
22
- # type: EssencePage
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 ||= begin
108
- Alchemy::Page.
109
- contentpages.
110
- language_roots.
111
- where(language: Language.current).
112
- includes(page_includes).
113
- first
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 ||= begin
131
- Alchemy::Page.
132
- contentpages.
133
- where(language: Language.current).
134
- includes(page_includes).
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 and rss requests (for pages containing a feed)
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?(etag: page_etag,
234
- last_modified: @page.published_at,
235
- public: !@page.restricted,
236
- template: "pages/show")
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 content/ingredient group for displaying in admin editor group headings
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
- content_definitions.present? ? "with-contents" : "without-contents",
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
- content_definitions.present? || ingredient_definitions.any? || taggable?
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?(method_name)
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(name,
128
- scope: :element_deprecation_notices,
129
- default: Alchemy.t(:element_deprecated))
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!(
@@ -4,8 +4,6 @@ module Alchemy
4
4
  module Admin
5
5
  module ElementsHelper
6
6
  include Alchemy::Admin::IngredientsHelper
7
- include Alchemy::Admin::ContentsHelper
8
- include Alchemy::Admin::EssencesHelper
9
7
 
10
8
  # Returns an elements array for select helper.
11
9
  #
@@ -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 contents.
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) || Alchemy::Deprecation.silence { content(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 content or ingredient has a value.
47
+ # Returns true if the given ingredient has a value.
71
48
  #
72
49
  def has?(name)
73
- if element.ingredient_definitions.any?
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 essence name)
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
- # contents:
116
- # - name: text
117
- # type: EssenceText
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 :essence_files, class_name: "Alchemy::EssenceFile", foreign_key: "attachment_id"
34
- has_many :contents, through: :essence_files
35
- has_many :elements, through: :contents
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) }
@@ -5,6 +5,8 @@ module Alchemy
5
5
  end
6
6
 
7
7
  class BaseRecord < ActiveRecord::Base
8
+ extend Alchemy::SearchableResource
9
+
8
10
  self.abstract_class = true
9
11
  end
10
12
  end
@@ -28,7 +28,6 @@ module Alchemy
28
28
  :tags,
29
29
  {
30
30
  ingredients: :related_object,
31
- contents: :essence,
32
31
  },
33
32
  ],
34
33
  },
@@ -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 content name:
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 Content found in the +elements.yml+ definition file.
41
+ # It's taken from the first Ingredient found in the +elements.yml+ definition file.
42
42
  #
43
- # You can flag a Content as +as_element_title+ to take this as preview.
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
- # contents:
65
- # - name: headline
66
- # type: EssenceText
67
- # - name: text
68
- # type EssenceRichtext
69
- # as_element_title: true
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 EssenceRichtext Content produces:
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