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.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +0 -3
  3. data/.gitignore +1 -6
  4. data/CHANGELOG.md +19 -44
  5. data/Gemfile +1 -1
  6. data/Rakefile +14 -9
  7. data/alchemy_cms.gemspec +2 -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 +8 -4
  23. data/app/controllers/alchemy/messages_controller.rb +9 -9
  24. data/app/controllers/alchemy/pages_controller.rb +23 -18
  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 -18
  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 -10
  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 +14 -13
  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 -6
  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/_table.html.erb +0 -6
  73. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +3 -6
  74. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  75. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -3
  76. data/app/views/alchemy/admin/pictures/_infos.html.erb +4 -6
  77. data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
  78. data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
  79. data/app/views/alchemy/ingredients/_headline_editor.html.erb +1 -1
  80. data/app/views/alchemy/ingredients/_html_editor.html.erb +1 -1
  81. data/app/views/alchemy/ingredients/_node_editor.html.erb +1 -1
  82. data/app/views/alchemy/ingredients/_picture_editor.html.erb +4 -4
  83. data/app/views/alchemy/ingredients/_select_editor.html.erb +2 -2
  84. data/app/views/alchemy/ingredients/_text_editor.html.erb +1 -1
  85. data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +3 -3
  86. data/app/views/alchemy/pages/_meta_data.html.erb +0 -1
  87. data/app/views/layouts/alchemy/admin.html.erb +5 -1
  88. data/config/alchemy/config.yml +6 -6
  89. data/config/brakeman.ignore +56 -57
  90. data/config/locales/alchemy.en.yml +99 -113
  91. data/config/routes.rb +1 -16
  92. data/db/migrate/20230121212637_alchemy_six_point_one.rb +248 -0
  93. data/lib/alchemy/cache_digests/template_tracker.rb +6 -7
  94. data/lib/alchemy/config.rb +2 -2
  95. data/lib/alchemy/deprecation.rb +1 -1
  96. data/lib/alchemy/errors.rb +0 -11
  97. data/lib/alchemy/hints.rb +10 -10
  98. data/lib/alchemy/permissions.rb +4 -17
  99. data/lib/alchemy/routing_constraints.rb +3 -3
  100. data/lib/alchemy/searchable_resource.rb +38 -0
  101. data/lib/alchemy/seeder.rb +2 -8
  102. data/lib/alchemy/tasks/tidy.rb +0 -38
  103. data/lib/alchemy/test_support/capybara_helpers.rb +69 -0
  104. data/lib/alchemy/test_support/factories/element_factory.rb +0 -6
  105. data/lib/alchemy/test_support/factories/ingredient_factory.rb +1 -1
  106. data/lib/alchemy/test_support/factories/page_factory.rb +4 -2
  107. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +0 -20
  108. data/lib/alchemy/test_support/shared_dom_ids_examples.rb +1 -1
  109. data/lib/alchemy/test_support/shared_ingredient_examples.rb +1 -1
  110. data/lib/alchemy/tinymce.rb +1 -18
  111. data/lib/alchemy/upgrader/seven_point_zero.rb +45 -0
  112. data/lib/alchemy/upgrader/tasks/.keep +0 -0
  113. data/lib/alchemy/upgrader.rb +8 -3
  114. data/lib/alchemy/version.rb +1 -1
  115. data/lib/alchemy.rb +0 -19
  116. data/lib/alchemy_cms.rb +1 -2
  117. data/lib/generators/alchemy/elements/elements_generator.rb +0 -1
  118. data/lib/generators/alchemy/elements/templates/view.html.erb +1 -10
  119. data/lib/generators/alchemy/elements/templates/view.html.haml +1 -9
  120. data/lib/generators/alchemy/elements/templates/view.html.slim +1 -9
  121. data/lib/generators/alchemy/install/files/alchemy.en.yml +7 -8
  122. data/lib/generators/alchemy/install/files/application.html.erb +1 -1
  123. data/lib/generators/alchemy/install/install_generator.rb +18 -34
  124. data/lib/generators/alchemy/install/templates/elements.yml.tt +12 -12
  125. data/lib/non_stupid_digest_assets.rb +1 -1
  126. data/lib/tasks/alchemy/thumbnails.rake +2 -21
  127. data/lib/tasks/alchemy/tidy.rake +1 -12
  128. data/lib/tasks/alchemy/upgrade.rake +10 -47
  129. data/package/dist/admin.js +16 -0
  130. data/package/dist/admin.js.map +7 -0
  131. data/package.json +5 -3
  132. metadata +18 -147
  133. data/app/controllers/alchemy/admin/contents_controller.rb +0 -21
  134. data/app/controllers/alchemy/admin/essence_audios_controller.rb +0 -30
  135. data/app/controllers/alchemy/admin/essence_files_controller.rb +0 -31
  136. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +0 -43
  137. data/app/controllers/alchemy/admin/essence_videos_controller.rb +0 -34
  138. data/app/controllers/alchemy/api/contents_controller.rb +0 -52
  139. data/app/decorators/alchemy/content_editor.rb +0 -119
  140. data/app/helpers/alchemy/admin/contents_helper.rb +0 -42
  141. data/app/helpers/alchemy/admin/essences_helper.rb +0 -31
  142. data/app/models/alchemy/content/factory.rb +0 -143
  143. data/app/models/alchemy/content.rb +0 -247
  144. data/app/models/alchemy/element/element_contents.rb +0 -200
  145. data/app/models/alchemy/element/element_essences.rb +0 -133
  146. data/app/models/alchemy/essence_audio.rb +0 -13
  147. data/app/models/alchemy/essence_boolean.rb +0 -20
  148. data/app/models/alchemy/essence_date.rb +0 -25
  149. data/app/models/alchemy/essence_file.rb +0 -49
  150. data/app/models/alchemy/essence_headline.rb +0 -41
  151. data/app/models/alchemy/essence_html.rb +0 -23
  152. data/app/models/alchemy/essence_link.rb +0 -21
  153. data/app/models/alchemy/essence_node.rb +0 -19
  154. data/app/models/alchemy/essence_page.rb +0 -17
  155. data/app/models/alchemy/essence_picture.rb +0 -67
  156. data/app/models/alchemy/essence_picture_view.rb +0 -90
  157. data/app/models/alchemy/essence_richtext.rb +0 -44
  158. data/app/models/alchemy/essence_select.rb +0 -19
  159. data/app/models/alchemy/essence_text.rb +0 -23
  160. data/app/models/alchemy/essence_video.rb +0 -13
  161. data/app/serializers/alchemy/content_serializer.rb +0 -17
  162. data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -10
  163. data/app/serializers/alchemy/essence_date_serializer.rb +0 -10
  164. data/app/serializers/alchemy/essence_file_serializer.rb +0 -13
  165. data/app/serializers/alchemy/essence_html_serializer.rb +0 -10
  166. data/app/serializers/alchemy/essence_link_serializer.rb +0 -13
  167. data/app/serializers/alchemy/essence_picture_serializer.rb +0 -28
  168. data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -11
  169. data/app/serializers/alchemy/essence_select_serializer.rb +0 -10
  170. data/app/serializers/alchemy/essence_text_serializer.rb +0 -22
  171. data/app/views/alchemy/admin/contents/create.js.erb +0 -21
  172. data/app/views/alchemy/admin/essence_audios/edit.html.erb +0 -7
  173. data/app/views/alchemy/admin/essence_files/edit.html.erb +0 -21
  174. data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -5
  175. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +0 -30
  176. data/app/views/alchemy/admin/essence_pictures/save_link.js.erb +0 -3
  177. data/app/views/alchemy/admin/essence_pictures/update.js.erb +0 -8
  178. data/app/views/alchemy/admin/essence_videos/edit.html.erb +0 -12
  179. data/app/views/alchemy/essences/_essence_audio_editor.html.erb +0 -4
  180. data/app/views/alchemy/essences/_essence_audio_view.html.erb +0 -15
  181. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +0 -11
  182. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +0 -2
  183. data/app/views/alchemy/essences/_essence_date_editor.html.erb +0 -16
  184. data/app/views/alchemy/essences/_essence_date_view.html.erb +0 -10
  185. data/app/views/alchemy/essences/_essence_file_editor.html.erb +0 -54
  186. data/app/views/alchemy/essences/_essence_file_view.html.erb +0 -18
  187. data/app/views/alchemy/essences/_essence_headline_editor.html.erb +0 -36
  188. data/app/views/alchemy/essences/_essence_headline_view.html.erb +0 -10
  189. data/app/views/alchemy/essences/_essence_html_editor.html.erb +0 -10
  190. data/app/views/alchemy/essences/_essence_html_view.html.erb +0 -2
  191. data/app/views/alchemy/essences/_essence_link_editor.html.erb +0 -30
  192. data/app/views/alchemy/essences/_essence_link_view.html.erb +0 -10
  193. data/app/views/alchemy/essences/_essence_node_editor.html.erb +0 -27
  194. data/app/views/alchemy/essences/_essence_node_view.html.erb +0 -1
  195. data/app/views/alchemy/essences/_essence_page_editor.html.erb +0 -26
  196. data/app/views/alchemy/essences/_essence_page_view.html.erb +0 -5
  197. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +0 -59
  198. data/app/views/alchemy/essences/_essence_picture_view.html.erb +0 -6
  199. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +0 -14
  200. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +0 -4
  201. data/app/views/alchemy/essences/_essence_select_editor.html.erb +0 -28
  202. data/app/views/alchemy/essences/_essence_select_view.html.erb +0 -2
  203. data/app/views/alchemy/essences/_essence_text_editor.html.erb +0 -29
  204. data/app/views/alchemy/essences/_essence_text_view.html.erb +0 -17
  205. data/app/views/alchemy/essences/_essence_video_editor.html.erb +0 -4
  206. data/app/views/alchemy/essences/_essence_video_view.html.erb +0 -19
  207. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +0 -59
  208. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +0 -20
  209. data/app/views/alchemy/pages/show.rss.builder +0 -21
  210. data/db/migrate/20200226213334_alchemy_four_point_four.rb +0 -313
  211. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +0 -11
  212. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +0 -28
  213. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +0 -8
  214. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +0 -27
  215. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +0 -6
  216. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +0 -24
  217. data/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +0 -22
  218. data/db/migrate/20200907111332_remove_tri_state_booleans.rb +0 -33
  219. data/db/migrate/20201207131309_create_page_versions.rb +0 -19
  220. data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +0 -76
  221. data/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +0 -10
  222. data/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +0 -7
  223. data/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +0 -12
  224. data/db/migrate/20210506135919_create_essence_audios.rb +0 -19
  225. data/db/migrate/20210506140258_create_essence_videos.rb +0 -23
  226. data/db/migrate/20210508091432_create_alchemy_ingredients.rb +0 -22
  227. data/db/migrate/20220514072456_restrict_on_delete_page_id_foreign_key_from_alchemy_nodes.rb +0 -13
  228. data/db/migrate/20220622130905_add_playsinline_to_alchemy_essence_videos.rb +0 -9
  229. data/lib/alchemy/essence.rb +0 -250
  230. data/lib/alchemy/tasks/usage.rb +0 -34
  231. data/lib/alchemy/test_support/essence_shared_examples.rb +0 -271
  232. data/lib/alchemy/test_support/factories/content_factory.rb +0 -20
  233. data/lib/alchemy/test_support/factories/essence_audio_factory.rb +0 -7
  234. data/lib/alchemy/test_support/factories/essence_file_factory.rb +0 -7
  235. data/lib/alchemy/test_support/factories/essence_page_factory.rb +0 -7
  236. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +0 -11
  237. data/lib/alchemy/test_support/factories/essence_text_factory.rb +0 -7
  238. data/lib/alchemy/test_support/factories/essence_video_factory.rb +0 -7
  239. data/lib/alchemy/upgrader/five_point_zero.rb +0 -41
  240. data/lib/alchemy/upgrader/six_point_zero.rb +0 -21
  241. data/lib/alchemy/upgrader/tasks/add_page_versions.rb +0 -33
  242. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +0 -34
  243. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +0 -29
  244. data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +0 -73
  245. data/lib/generators/alchemy/essence/essence_generator.rb +0 -49
  246. data/lib/generators/alchemy/essence/templates/editor.html.erb +0 -17
  247. data/lib/generators/alchemy/essence/templates/view.html.erb +0 -2
  248. data/lib/generators/alchemy/install/files/babel.config.js +0 -64
  249. 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 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
@@ -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 depending contents and all of their depending essences.
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
- # contents:
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
- # Compatibility method for access from element
82
- def essence
83
- self
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 content
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
@@ -11,6 +11,8 @@ module Alchemy
11
11
  :muted,
12
12
  :loop
13
13
 
14
+ allow_settings %i[except only]
15
+
14
16
  related_object_alias :attachment, class_name: "Alchemy::Attachment"
15
17
 
16
18
  delegate :name, to: :attachment, allow_nil: true
@@ -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.essence_date')
18
+ ::I18n.l(value, format: :'alchemy.ingredient_date')
17
19
  end
18
20
  end
19
21
  end
@@ -12,6 +12,13 @@ module Alchemy
12
12
  :link_text,
13
13
  :title
14
14
 
15
+ allow_settings %i[
16
+ css_classes
17
+ except
18
+ link_text
19
+ only
20
+ ]
21
+
15
22
  related_object_alias :attachment, class_name: "Alchemy::Attachment"
16
23
 
17
24
  delegate :name, to: :attachment, allow_nil: true
@@ -12,6 +12,12 @@ module Alchemy
12
12
  :level,
13
13
  :size
14
14
 
15
+ allow_settings %i[
16
+ anchor
17
+ levels
18
+ sizes
19
+ ]
20
+
15
21
  before_create :set_level_and_size
16
22
 
17
23
  def preview_text(maxlength = 30)
@@ -10,6 +10,8 @@ module Alchemy
10
10
  :link_target,
11
11
  :link_title
12
12
 
13
+ allow_settings %i[text]
14
+
13
15
  alias_method :link, :value
14
16
  end
15
17
  end
@@ -9,6 +9,8 @@ module Alchemy
9
9
  class Node < Alchemy::Ingredient
10
10
  related_object_alias :node, class_name: "Alchemy::Node"
11
11
 
12
+ allow_settings %i[query_params]
13
+
12
14
  # The first 30 characters of node name
13
15
  #
14
16
  # Used by the Element#preview_text method.
@@ -9,6 +9,8 @@ module Alchemy
9
9
  class Page < Alchemy::Ingredient
10
10
  related_object_alias :page, class_name: "Alchemy::Page"
11
11
 
12
+ allow_settings %i[query_params]
13
+
12
14
  # The first 30 characters of page name
13
15
  #
14
16
  # Used by the Element#preview_text method.
@@ -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.
@@ -9,6 +9,12 @@ module Alchemy
9
9
  :stripped_body,
10
10
  :sanitized_body
11
11
 
12
+ allow_settings %i[
13
+ plain_text
14
+ sanitizer
15
+ tinymce
16
+ ]
17
+
12
18
  before_save :strip_content
13
19
  before_save :sanitize_content
14
20
 
@@ -5,6 +5,7 @@ module Alchemy
5
5
  # A text value from a select box
6
6
  #
7
7
  class Select < Alchemy::Ingredient
8
+ allow_settings %i[display_inline select_values]
8
9
  end
9
10
  end
10
11
  end
@@ -15,6 +15,14 @@ module Alchemy
15
15
  :link_target,
16
16
  :link_title,
17
17
  :link_class_name
18
+
19
+ allow_settings %i[
20
+ anchor
21
+ disable_link
22
+ display_inline
23
+ input_type
24
+ linkable
25
+ ]
18
26
  end
19
27
  end
20
28
  end
@@ -16,6 +16,8 @@ module Alchemy
16
16
  :preload,
17
17
  :width
18
18
 
19
+ allow_settings %i[except only]
20
+
19
21
  related_object_alias :attachment, class_name: "Alchemy::Attachment"
20
22
 
21
23
  delegate :name, to: :attachment, allow_nil: true
@@ -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 :check_if_related_essence_nodes_present
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 :essence_nodes, class_name: "Alchemy::EssenceNode", foreign_key: :node_id, inverse_of: :ingredient_association
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 check_if_related_essence_nodes_present
80
- dependent_essence_nodes = self_and_descendants.flat_map(&:essence_nodes)
81
- if dependent_essence_nodes.any?
82
- errors.add(:base, :essence_nodes_present, page_names: dependent_essence_nodes.map(&:page).map(&:name).to_sentence)
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 :contents, through: :elements
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
- # contents:
61
+ # ingredients:
62
62
  # - name: headline
63
- # type: EssenceText
63
+ # type: Text
64
64
  #
65
65
  # == Example of limited element:
66
66
  #
67
67
  # - name: article
68
68
  # amount: 2
69
- # contents:
69
+ # ingredients:
70
70
  # - name: text
71
- # type: EssenceRichtext
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.